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
	cycles(&t);
69
	tos->kcycles += t - up->kentry;
70
	tos->pcycles = up->pcycles;
71
	tos->cyclefreq = m->cpuhz;
72
	tos->pid = up->pid;
73
 
74
	/* make visible immediately to user phase */
75
	l1cache->wbse(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
	l1cache->wbse(p, sizeof *p);		/* is this needed? */
159
	l1cache->wb();				/* is this needed? */
160
}
161
 
162
void
163
procrestore(Proc* p)
164
{
165
	uvlong t;
166
 
167
	if(p->kp)
168
		return;
169
	cycles(&t);
170
	p->pcycles -= t;
171
	wakewfi();		/* in case there's another runnable proc */
172
 
173
	/* let it fault in at first use */
174
//	fpuprocrestore(p);
175
	l1cache->wb();			/* system is more stable with this */
176
}
177
 
178
int
179
userureg(Ureg* ureg)
180
{
181
	return (ureg->psr & PsrMask) == PsrMusr;
182
}