diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/omap/arch.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/omap/arch.c')
-rwxr-xr-x | sys/src/9/omap/arch.c | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/sys/src/9/omap/arch.c b/sys/src/9/omap/arch.c new file mode 100755 index 000000000..a9b9537a9 --- /dev/null +++ b/sys/src/9/omap/arch.c @@ -0,0 +1,223 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include <tos.h> +#include "ureg.h" + +#include "arm.h" + +/* + * A lot of this stuff doesn't belong here + * but this is a convenient dumping ground for + * later sorting into the appropriate buckets. + */ + +/* Give enough context in the ureg to produce a kernel stack for + * a sleeping process + */ +void +setkernur(Ureg* ureg, Proc* p) +{ + ureg->pc = p->sched.pc; + ureg->sp = p->sched.sp+4; + ureg->r14 = PTR2UINT(sched); +} + +/* + * called in sysfile.c + */ +void +evenaddr(uintptr addr) +{ + if(addr & 3){ + postnote(up, 1, "sys: odd address", NDebug); + error(Ebadarg); + } +} + +/* go to user space */ +void +kexit(Ureg*) +{ + uvlong t; + Tos *tos; + + /* precise time accounting, kernel exit */ + tos = (Tos*)(USTKTOP-sizeof(Tos)); + cycles(&t); + tos->kcycles += t - up->kentry; + tos->pcycles = up->pcycles; + tos->cyclefreq = m->cpuhz; + tos->pid = up->pid; + + /* make visible immediately to user proc */ + cachedwbinvse(tos, sizeof *tos); +} + +/* + * return the userpc the last exception happened at + */ +uintptr +userpc(void) +{ + Ureg *ureg = up->dbgreg; + return ureg->pc; +} + +/* This routine must save the values of registers the user is not permitted + * to write from devproc and then restore the saved values before returning. + */ +void +setregisters(Ureg* ureg, char* pureg, char* uva, int n) +{ + USED(ureg, pureg, uva, n); +} + +/* + * this is the body for all kproc's + */ +static void +linkproc(void) +{ + spllo(); + up->kpfun(up->kparg); + pexit("kproc exiting", 0); +} + +/* + * setup stack and initial PC for a new kernel proc. This is architecture + * dependent because of the starting stack location + */ +void +kprocchild(Proc *p, void (*func)(void*), void *arg) +{ + p->sched.pc = PTR2UINT(linkproc); + p->sched.sp = PTR2UINT(p->kstack+KSTACK); + + p->kpfun = func; + p->kparg = arg; +} + +/* + * pc output by dumpaproc + */ +uintptr +dbgpc(Proc* p) +{ + Ureg *ureg; + + ureg = p->dbgreg; + if(ureg == 0) + return 0; + + return ureg->pc; +} + +/* + * set mach dependent process state for a new process + */ +void +procsetup(Proc* p) +{ + fpusysprocsetup(p); +} + +/* + * Save the mach dependent part of the process state. + */ +void +procsave(Proc* p) +{ + uvlong t; + + cycles(&t); + p->pcycles += t; + +// TODO: save and restore VFPv3 FP state once 5[cal] know the new registers. + fpuprocsave(p); +} + +void +procrestore(Proc* p) +{ + uvlong t; + + if(p->kp) + return; + cycles(&t); + p->pcycles -= t; + + fpuprocrestore(p); +} + +int +userureg(Ureg* ureg) +{ + return (ureg->psr & PsrMask) == PsrMusr; +} + +/* + * atomic ops + * make sure that we don't drag in the C library versions + */ + +long +_xdec(long *p) +{ + int s, v; + + s = splhi(); + v = --*p; + splx(s); + return v; +} + +void +_xinc(long *p) +{ + int s; + + s = splhi(); + ++*p; + splx(s); +} + +int +ainc(int *p) +{ + int s, v; + + s = splhi(); + v = ++*p; + splx(s); + return v; +} + +int +adec(int *p) +{ + int s, v; + + s = splhi(); + v = --*p; + splx(s); + return v; +} + +int +cas32(void* addr, u32int old, u32int new) +{ + int r, s; + + s = splhi(); + if(r = (*(u32int*)addr == old)) + *(u32int*)addr = new; + splx(s); + if (r) + coherence(); + return r; +} |