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 cycles(&t); 52 tos->kcycles += t - up->kentry; 53 tos->pcycles = up->pcycles; 54 tos->cyclefreq = m->cpuhz; 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 /* 130 * Save the mach dependent part of the process state. 131 */ 132 void 133 procsave(Proc* p) 134 { 135 uvlong t; 136 137 cycles(&t); 138 p->pcycles += t; 139 140 // TODO: save and restore VFPv3 FP state once 5[cal] know the new registers. 141 fpuprocsave(p); 142 } 143 144 void 145 procrestore(Proc* p) 146 { 147 uvlong t; 148 149 if(p->kp) 150 return; 151 cycles(&t); 152 p->pcycles -= t; 153 154 fpuprocrestore(p); 155 } 156 157 int 158 userureg(Ureg* ureg) 159 { 160 return (ureg->psr & PsrMask) == PsrMusr; 161 } 162 163 /* 164 * atomic ops 165 * make sure that we don't drag in the C library versions 166 */ 167 168 long 169 _xdec(long *p) 170 { 171 int s, v; 172 173 s = splhi(); 174 v = --*p; 175 splx(s); 176 return v; 177 } 178 179 void 180 _xinc(long *p) 181 { 182 int s; 183 184 s = splhi(); 185 ++*p; 186 splx(s); 187 } 188 189 int 190 ainc(int *p) 191 { 192 int s, v; 193 194 s = splhi(); 195 v = ++*p; 196 splx(s); 197 return v; 198 } 199 200 int 201 adec(int *p) 202 { 203 int s, v; 204 205 s = splhi(); 206 v = --*p; 207 splx(s); 208 return v; 209 } 210 211 int 212 cas32(void* addr, u32int old, u32int new) 213 { 214 int r, s; 215 216 s = splhi(); 217 if(r = (*(u32int*)addr == old)) 218 *(u32int*)addr = new; 219 splx(s); 220 if (r) 221 coherence(); 222 return r; 223 } 224