]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/kw/arch.c
kernel: apply uintptr for ulong when a pointer is stored
[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 = 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         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         cycles(&p->kentry);
129         p->pcycles = -p->kentry;
130 }
131
132 void
133 procfork(Proc* p)
134 {
135         p->kentry = up->kentry;
136         p->pcycles = -p->kentry;
137 }
138
139 /*
140  *  Save the mach dependent part of the process state.
141  */
142 void
143 procsave(Proc* p)
144 {
145         uvlong t;
146
147         cycles(&t);
148         p->pcycles += t;
149         p->kentry -= t;
150
151         fpuprocsave(p);
152 }
153
154 void
155 procrestore(Proc* p)
156 {
157         uvlong t;
158
159         if(p->kp)
160                 return;
161
162         cycles(&t);
163         p->pcycles -= t;
164         p->kentry += t;
165
166         fpuprocrestore(p);
167 }
168
169 int
170 userureg(Ureg* ureg)
171 {
172         return (ureg->psr & PsrMask) == PsrMusr;
173 }
174
175 /*
176  * atomic ops
177  * make sure that we don't drag in the C library versions
178  */
179
180 long
181 _xdec(long *p)
182 {
183         int s, v;
184
185         s = splhi();
186         v = --*p;
187         splx(s);
188         return v;
189 }
190
191 void
192 _xinc(long *p)
193 {
194         int s;
195
196         s = splhi();
197         ++*p;
198         splx(s);
199 }
200
201 int
202 ainc(int *p)
203 {
204         int s, v;
205
206         s = splhi();
207         v = ++*p;
208         splx(s);
209         return v;
210 }
211
212 int
213 adec(int *p)
214 {
215         int s, v;
216
217         s = splhi();
218         v = --*p;
219         splx(s);
220         return v;
221 }
222
223 int
224 cas32(void* addr, u32int old, u32int new)
225 {
226         int r, s;
227
228         s = splhi();
229         if(r = (*(u32int*)addr == old))
230                 *(u32int*)addr = new;
231         splx(s);
232         if (r)
233                 coherence();
234         return r;
235 }