]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/teg2/arch.c
usbehci: catch interrupt in tsleep
[plan9front.git] / sys / src / 9 / teg2 / 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         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 phase */
58         l1cache->wbse(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         fpuprocsave(p);
141         l1cache->wbse(p, sizeof *p);            /* is this needed? */
142         l1cache->wb();                          /* is this needed? */
143 }
144
145 void
146 procfork(Proc* p)
147 {
148         p->kentry = up->kentry;
149         p->pcycles = -p->kentry;
150         
151         fpuprocfork(p);
152 }
153
154 void
155 procrestore(Proc* p)
156 {
157         uvlong t;
158
159         if(p->kp)
160                 return;
161         cycles(&t);
162         p->pcycles -= t;
163         wakewfi();              /* in case there's another runnable proc */
164
165         /* let it fault in at first use */
166 //      fpuprocrestore(p);
167         l1cache->wb();                  /* system is more stable with this */
168 }
169
170 int
171 userureg(Ureg* ureg)
172 {
173         return (ureg->psr & PsrMask) == PsrMusr;
174 }