]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/arch.c
segdesc: add /dev/^(ldt gdt) support
[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 = PTR2UINT(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 = 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         USED(ureg, pureg, uva, n);
78 }
79
80 /*
81  *  this is the body for all kproc's
82  */
83 static void
84 linkproc(void)
85 {
86         spllo();
87         up->kpfun(up->kparg);
88         pexit("kproc exiting", 0);
89 }
90
91 /*
92  *  setup stack and initial PC for a new kernel proc.  This is architecture
93  *  dependent because of the starting stack location
94  */
95 void
96 kprocchild(Proc *p, void (*func)(void*), void *arg)
97 {
98         p->sched.pc = PTR2UINT(linkproc);
99         p->sched.sp = PTR2UINT(p->kstack+KSTACK);
100
101         p->kpfun = func;
102         p->kparg = arg;
103 }
104
105 /*
106  *  pc output by dumpaproc
107  */
108 uintptr
109 dbgpc(Proc* p)
110 {
111         Ureg *ureg;
112
113         ureg = p->dbgreg;
114         if(ureg == 0)
115                 return 0;
116
117         return ureg->pc;
118 }
119
120 /*
121  *  set mach dependent process state for a new process
122  */
123 void
124 procsetup(Proc* p)
125 {
126         fpusysprocsetup(p);
127 }
128
129 void
130 procfork(Proc *)
131 {
132 }
133
134 /*
135  *  Save the mach dependent part of the process state.
136  */
137 void
138 procsave(Proc* p)
139 {
140         uvlong t;
141
142         cycles(&t);
143         p->pcycles += t;
144
145         fpuprocsave(p);
146 }
147
148 void
149 procrestore(Proc* p)
150 {
151         uvlong t;
152
153         if(p->kp)
154                 return;
155         t = lcycles();
156         p->pcycles -= t;
157
158         fpuprocrestore(p);
159 }
160
161 int
162 userureg(Ureg* ureg)
163 {
164         return (ureg->psr & PsrMask) == PsrMusr;
165 }
166
167 /*
168  * atomic ops
169  * make sure that we don't drag in the C library versions
170  */
171
172 long
173 _xdec(long *p)
174 {
175         int s, v;
176
177         s = splhi();
178         v = --*p;
179         splx(s);
180         return v;
181 }
182
183 void
184 _xinc(long *p)
185 {
186         int s;
187
188         s = splhi();
189         ++*p;
190         splx(s);
191 }
192
193 int
194 ainc(int *p)
195 {
196         int s, v;
197
198         s = splhi();
199         v = ++*p;
200         splx(s);
201         return v;
202 }
203
204 int
205 adec(int *p)
206 {
207         int s, v;
208
209         s = splhi();
210         v = --*p;
211         splx(s);
212         return v;
213 }
214
215 int
216 cas32(void* addr, u32int old, u32int new)
217 {
218         int r, s;
219
220         s = splhi();
221         if(r = (*(u32int*)addr == old))
222                 *(u32int*)addr = new;
223         splx(s);
224         if (r)
225                 coherence();
226         return r;
227 }