]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/arch.c
vmx: clean up mksegment, memset only if segment existed (devsegment clears new ones)
[plan9front.git] / sys / src / 9 / kw / arch.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 #include <tos.h>
9 #include "ureg.h"
10
11 #include "arm.h"
12
13 /*
14  * A lot of this stuff doesn't belong here
15  * but this is a convenient dumping ground for
16  * later sorting into the appropriate buckets.
17  */
18
19 /* Give enough context in the ureg to produce a kernel stack for
20  * a sleeping process
21  */
22 void
23 setkernur(Ureg* ureg, Proc* p)
24 {
25         ureg->pc = p->sched.pc;
26         ureg->sp = p->sched.sp+4;
27         ureg->r14 = (uintptr)sched;
28 }
29
30 /*
31  * called in sysfile.c
32  */
33 void
34 evenaddr(uintptr addr)
35 {
36         if(addr & 3){
37                 postnote(up, 1, "sys: odd address", NDebug);
38                 error(Ebadarg);
39         }
40 }
41
42 /* go to user space */
43 void
44 kexit(Ureg*)
45 {
46         uvlong t;
47         Tos *tos;
48
49         /* precise time accounting, kernel exit */
50         tos = (Tos*)(USTKTOP-sizeof(Tos));
51         t = fastticks(nil);
52         tos->kcycles += t - up->kentry;
53         tos->pcycles = t + up->pcycles;
54         tos->cyclefreq = Frequency;
55         tos->pid = up->pid;
56
57         /* make visible immediately to user proc */
58         cachedwbinvse(tos, sizeof *tos);
59 }
60
61 /*
62  *  return the userpc the last exception happened at
63  */
64 uintptr
65 userpc(void)
66 {
67         Ureg *ureg = up->dbgreg;
68         return ureg->pc;
69 }
70
71 /* This routine must save the values of registers the user is not permitted
72  * to write from devproc and then restore the saved values before returning.
73  */
74 void
75 setregisters(Ureg* ureg, char* pureg, char* uva, int n)
76 {
77         ulong v = ureg->psr;
78         memmove(pureg, uva, n);
79         ureg->psr = ureg->psr & ~(PsrMask|PsrDfiq|PsrDirq) | v & (PsrMask|PsrDfiq|PsrDirq);
80 }
81
82 /*
83  *  this is the body for all kproc's
84  */
85 static void
86 linkproc(void)
87 {
88         spllo();
89         up->kpfun(up->kparg);
90         pexit("kproc exiting", 0);
91 }
92
93 /*
94  *  setup stack and initial PC for a new kernel proc.  This is architecture
95  *  dependent because of the starting stack location
96  */
97 void
98 kprocchild(Proc *p, void (*func)(void*), void *arg)
99 {
100         p->sched.pc = (uintptr)linkproc;
101         p->sched.sp = (uintptr)p->kstack+KSTACK;
102
103         p->kpfun = func;
104         p->kparg = arg;
105 }
106
107 /*
108  *  pc output by dumpaproc
109  */
110 uintptr
111 dbgpc(Proc* p)
112 {
113         Ureg *ureg;
114
115         ureg = p->dbgreg;
116         if(ureg == 0)
117                 return 0;
118
119         return ureg->pc;
120 }
121
122 /*
123  *  set mach dependent process state for a new process
124  */
125 void
126 procsetup(Proc* p)
127 {
128         fpusysprocsetup(p);
129
130         cycles(&p->kentry);
131         p->pcycles = -p->kentry;
132 }
133
134 void
135 procfork(Proc* p)
136 {
137         p->kentry = up->kentry;
138         p->pcycles = -p->kentry;
139 }
140
141 /*
142  *  Save the mach dependent part of the process state.
143  */
144 void
145 procsave(Proc* p)
146 {
147         uvlong t;
148
149         cycles(&t);
150         p->pcycles += t;
151         p->kentry -= t;
152
153         fpuprocsave(p);
154 }
155
156 void
157 procrestore(Proc* p)
158 {
159         uvlong t;
160
161         if(p->kp)
162                 return;
163
164         cycles(&t);
165         p->pcycles -= t;
166         p->kentry += t;
167
168         fpuprocrestore(p);
169 }
170
171 int
172 userureg(Ureg* ureg)
173 {
174         return (ureg->psr & PsrMask) == PsrMusr;
175 }
176
177 int
178 cas32(void* addr, u32int old, u32int new)
179 {
180         int r, s;
181
182         s = splhi();
183         if(r = (*(u32int*)addr == old))
184                 *(u32int*)addr = new;
185         splx(s);
186         if (r)
187                 coherence();
188         return r;
189 }