Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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 syscallfmt.c, sysfile.c, sysproc.c
32
 */
33
void
34
validalign(uintptr addr, unsigned align)
35
{
36
	/*
37
	 * Plan 9 is a 32-bit O/S, and the hardware it runs on
38
	 * does not usually have instructions which move 64-bit
39
	 * quantities directly, synthesizing the operations
40
	 * with 32-bit move instructions. Therefore, the compiler
41
	 * (and hardware) usually only enforce 32-bit alignment,
42
	 * if at all.
43
	 *
44
	 * Take this out if the architecture warrants it.
45
	 */
46
	if(align == sizeof(vlong))
47
		align = sizeof(long);
48
 
49
	/*
50
	 * Check align is a power of 2, then addr alignment.
51
	 */
52
	if((align != 0 && !(align & (align-1))) && !(addr & (align-1)))
53
		return;
54
	postnote(up, 1, "sys: odd address", NDebug);
55
	error(Ebadarg);
56
	/*NOTREACHED*/
57
}
58
 
59
/* go to user space */
60
void
61
kexit(Ureg*)
62
{
63
	uvlong t;
64
	Tos *tos;
65
 
66
	/* precise time accounting, kernel exit */
67
	tos = (Tos*)(USTKTOP-sizeof(Tos));
68
	t = fastticks(nil);
69
	tos->kcycles += t - up->kentry;
70
	tos->pcycles = up->pcycles;
71
	tos->cyclefreq = Frequency;
72
	tos->pid = up->pid;
73
 
74
	/* make visible immediately to user proc */
75
	cachedwbinvse(tos, sizeof *tos);
76
}
77
 
78
/*
79
 *  return the userpc the last exception happened at
80
 */
81
uintptr
82
userpc(void)
83
{
84
	Ureg *ureg = up->dbgreg;
85
	return ureg->pc;
86
}
87
 
88
/* This routine must save the values of registers the user is not permitted
89
 * to write from devproc and then restore the saved values before returning.
90
 */
91
void
92
setregisters(Ureg* ureg, char* pureg, char* uva, int n)
93
{
94
	USED(ureg, pureg, uva, n);
95
}
96
 
97
/*
98
 *  this is the body for all kproc's
99
 */
100
static void
101
linkproc(void)
102
{
103
	spllo();
104
	up->kpfun(up->kparg);
105
	pexit("kproc exiting", 0);
106
}
107
 
108
/*
109
 *  setup stack and initial PC for a new kernel proc.  This is architecture
110
 *  dependent because of the starting stack location
111
 */
112
void
113
kprocchild(Proc *p, void (*func)(void*), void *arg)
114
{
115
	p->sched.pc = PTR2UINT(linkproc);
116
	p->sched.sp = PTR2UINT(p->kstack+KSTACK);
117
 
118
	p->kpfun = func;
119
	p->kparg = arg;
120
}
121
 
122
/*
123
 *  pc output by dumpaproc
124
 */
125
uintptr
126
dbgpc(Proc* p)
127
{
128
	Ureg *ureg;
129
 
130
	ureg = p->dbgreg;
131
	if(ureg == 0)
132
		return 0;
133
 
134
	return ureg->pc;
135
}
136
 
137
/*
138
 *  set mach dependent process state for a new process
139
 */
140
void
141
procsetup(Proc* p)
142
{
143
	fpusysprocsetup(p);
144
}
145
 
146
/*
147
 *  Save the mach dependent part of the process state.
148
 */
149
void
150
procsave(Proc* p)
151
{
152
	uvlong t;
153
 
154
	cycles(&t);
155
	p->pcycles += t;
156
 
157
	fpuprocsave(p);
158
}
159
 
160
void
161
procrestore(Proc* p)
162
{
163
	uvlong t;
164
 
165
	if(p->kp)
166
		return;
167
	t = lcycles();
168
	p->pcycles -= t;
169
 
170
	fpuprocrestore(p);
171
}
172
 
173
int
174
userureg(Ureg* ureg)
175
{
176
	return (ureg->psr & PsrMask) == PsrMusr;
177
}
178
 
179
/*
180
 * atomic ops
181
 * make sure that we don't drag in the C library versions
182
 */
183
 
184
long
185
_xdec(long *p)
186
{
187
	int s, v;
188
 
189
	s = splhi();
190
	v = --*p;
191
	splx(s);
192
	return v;
193
}
194
 
195
void
196
_xinc(long *p)
197
{
198
	int s;
199
 
200
	s = splhi();
201
	++*p;
202
	splx(s);
203
}
204
 
205
int
206
ainc(int *p)
207
{
208
	int s, v;
209
 
210
	s = splhi();
211
	v = ++*p;
212
	splx(s);
213
	return v;
214
}
215
 
216
int
217
adec(int *p)
218
{
219
	int s, v;
220
 
221
	s = splhi();
222
	v = --*p;
223
	splx(s);
224
	return v;
225
}
226
 
227
int
228
cas32(void* addr, u32int old, u32int new)
229
{
230
	int r, s;
231
 
232
	s = splhi();
233
	if(r = (*(u32int*)addr == old))
234
		*(u32int*)addr = new;
235
	splx(s);
236
	if (r)
237
		coherence();
238
	return r;
239
}