kernel: handle tos and per process pcycle counters in port/
we might as well handle the per process cycle counter in the portable part instead of duplicating the code in every arch and have inconsistent implementations. we now have a portable kenter() and kexit() function, that is ment to be used in trap/syscall from user, which updates the counters. some kernels missed initializing Mach.cyclefreq.
This commit is contained in:
parent
08c1622b0d
commit
e4ce6aadac
44 changed files with 157 additions and 767 deletions
|
@ -39,25 +39,6 @@ evenaddr(uintptr addr)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 = t + 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
|
||||
*/
|
||||
|
@ -79,29 +60,15 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->psr = ureg->psr & ~(PsrMask|PsrDfiq|PsrDirq) | v & (PsrMask|PsrDfiq|PsrDirq);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr)linkproc;
|
||||
p->sched.pc = (uintptr)entry;
|
||||
p->sched.sp = (uintptr)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -126,17 +93,11 @@ void
|
|||
procsetup(Proc* p)
|
||||
{
|
||||
fpusysprocsetup(p);
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procfork(Proc* p)
|
||||
{
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
fpuprocfork(p);
|
||||
}
|
||||
|
||||
|
@ -146,12 +107,6 @@ procfork(Proc* p)
|
|||
void
|
||||
procsave(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
p->kentry -= t;
|
||||
|
||||
// TODO: save and restore VFPv3 FP state once 5[cal] know the new registers.
|
||||
fpuprocsave(p);
|
||||
|
||||
|
@ -173,14 +128,6 @@ procsave(Proc* p)
|
|||
void
|
||||
procrestore(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
p->kentry += t;
|
||||
|
||||
fpuprocrestore(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -129,8 +129,6 @@ extern void setkernur(Ureg*, Proc*); /* only devproc.c */
|
|||
extern void* sysexecregs(uintptr, ulong, int);
|
||||
extern void sysprocsetup(Proc*);
|
||||
|
||||
extern void kexit(Ureg*);
|
||||
|
||||
#define getpgcolor(a) 0
|
||||
#define kmapinval()
|
||||
#define countpagerefs(a, b)
|
||||
|
|
|
@ -150,12 +150,7 @@ trap(Ureg *ureg)
|
|||
rem, up, ureg, ureg->pc);
|
||||
}
|
||||
|
||||
user = (ureg->psr & PsrMask) == PsrMusr;
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
/*
|
||||
* All interrupts/exceptions should be resumed at ureg->pc-4,
|
||||
* except for Data Abort which resumes at ureg->pc-8.
|
||||
|
|
|
@ -8,7 +8,8 @@ extern int tas(void *);
|
|||
extern int cmpswap(long*, long, long);
|
||||
extern void coherence(void);
|
||||
extern void idlehands(void);
|
||||
extern uvlong cycles(void);
|
||||
extern uvlong vcycles(void);
|
||||
#define cycles(ip) *(ip) = vcycles()
|
||||
extern int splfhi(void);
|
||||
extern void splflo(void);
|
||||
extern void touser(uintptr sp);
|
||||
|
|
|
@ -297,7 +297,7 @@ _goodnight:
|
|||
WFE
|
||||
RETURN
|
||||
|
||||
TEXT cycles(SB), 1, $-4
|
||||
TEXT vcycles(SB), 1, $-4
|
||||
TEXT lcycles(SB), 1, $-4
|
||||
MRS PMCCNTR_EL0, R0
|
||||
RETURN
|
||||
|
|
|
@ -81,20 +81,6 @@ trapinit(void)
|
|||
splx(0x3<<6); // unmask serr and debug
|
||||
}
|
||||
|
||||
void
|
||||
kexit(Ureg*)
|
||||
{
|
||||
Tos *tos;
|
||||
uvlong t;
|
||||
|
||||
t = cycles();
|
||||
|
||||
tos = (Tos*)(USTKTOP-sizeof(Tos));
|
||||
tos->kcycles += t - up->kentry;
|
||||
tos->pcycles = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
static char *traps[64] = {
|
||||
[0x00] "sys: trap: unknown",
|
||||
[0x01] "sys: trap: WFI or WFE instruction execution",
|
||||
|
@ -112,17 +98,15 @@ void
|
|||
trap(Ureg *ureg)
|
||||
{
|
||||
u32int type, intr;
|
||||
|
||||
int user;
|
||||
|
||||
intr = ureg->type >> 32;
|
||||
if(intr == 2){
|
||||
fiq(ureg);
|
||||
return;
|
||||
}
|
||||
splflo();
|
||||
if(userureg(ureg)){
|
||||
up->dbgreg = ureg;
|
||||
up->kentry = cycles();
|
||||
}
|
||||
user = kenter(ureg);
|
||||
type = (u32int)ureg->type >> 26;
|
||||
switch(type){
|
||||
case 0x20: // instruction abort from lower level
|
||||
|
@ -187,7 +171,7 @@ trap(Ureg *ureg)
|
|||
break;
|
||||
}
|
||||
splhi();
|
||||
if(userureg(ureg)){
|
||||
if(user){
|
||||
if(up->procctl || up->nnote)
|
||||
notify(ureg);
|
||||
kexit(ureg);
|
||||
|
@ -203,12 +187,12 @@ syscall(Ureg *ureg)
|
|||
int i, s;
|
||||
char *e;
|
||||
|
||||
up->kentry = cycles();
|
||||
if(!kenter(ureg))
|
||||
panic("syscall from kernel");
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
sp = ureg->sp;
|
||||
up->scallnr = scallnr = ureg->r0;
|
||||
|
@ -542,9 +526,6 @@ procfork(Proc *p)
|
|||
splx(s);
|
||||
|
||||
p->tpidr = up->tpidr;
|
||||
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -555,16 +536,11 @@ procsetup(Proc *p)
|
|||
|
||||
p->tpidr = 0;
|
||||
syswr(TPIDR_EL0, p->tpidr);
|
||||
|
||||
p->kentry = cycles();
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->fpstate == FPactive){
|
||||
if(p->state == Moribund)
|
||||
fpclear();
|
||||
|
@ -577,44 +553,21 @@ procsave(Proc *p)
|
|||
p->tpidr = sysrd(TPIDR_EL0);
|
||||
|
||||
putasid(p); // release asid
|
||||
|
||||
t = cycles();
|
||||
p->kentry -= t;
|
||||
p->pcycles += t;
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
|
||||
syswr(TPIDR_EL0, p->tpidr);
|
||||
|
||||
t = cycles();
|
||||
p->kentry += t;
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc dying", 0);
|
||||
if(p->kp == 0)
|
||||
syswr(TPIDR_EL0, p->tpidr);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc* p, void (*func)(void*), void* arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr) linkproc;
|
||||
p->sched.pc = (uintptr) entry;
|
||||
p->sched.sp = (uintptr) p->kstack + KSTACK - 16;
|
||||
*(void**)p->sched.sp = kprocchild; /* fake */
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -30,7 +30,6 @@ void mmuinit(void);
|
|||
uintptr ttbget(void);
|
||||
void ttbput(uintptr);
|
||||
void cycles(uvlong *);
|
||||
void kexit(Ureg *);
|
||||
ulong getifsr(void);
|
||||
ulong getdfsr(void);
|
||||
uintptr getifar(void);
|
||||
|
|
|
@ -43,9 +43,6 @@ procfork(Proc *p)
|
|||
{
|
||||
ulong s;
|
||||
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
s = splhi();
|
||||
switch(up->fpstate & ~FPillegal){
|
||||
case FPactive:
|
||||
|
@ -63,22 +60,6 @@ procsetup(Proc *p)
|
|||
{
|
||||
p->fpstate = FPinit;
|
||||
fpoff();
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
kexit(Ureg *)
|
||||
{
|
||||
Tos *tos;
|
||||
uvlong t;
|
||||
|
||||
tos = (Tos*)(USTKTOP-sizeof(Tos));
|
||||
cycles(&t);
|
||||
tos->kcycles += t - up->kentry;
|
||||
tos->pcycles = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -96,6 +96,7 @@ timerinit(void)
|
|||
hz = HPS_CLK * 1000000 * (numer + 1) / ((denum + 1) * 2 * (mpuclk + 1));
|
||||
m->cpumhz = (hz + 500000) / 1000000;
|
||||
m->cpuhz = hz;
|
||||
m->cyclefreq = hz;
|
||||
timerhz = m->cpuhz / 4;
|
||||
|
||||
mpcore[GTIMERCTL] = TIMERDIV - 1 << 8 | 3;
|
||||
|
|
|
@ -150,13 +150,7 @@ trap(Ureg *ureg)
|
|||
int user;
|
||||
ulong opc, cp;
|
||||
|
||||
user = userureg(ureg);
|
||||
if(user){
|
||||
if(up == nil)
|
||||
panic("user trap: up=nil");
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
user = kenter(ureg);
|
||||
switch(ureg->type){
|
||||
case PsrMund:
|
||||
ureg->pc -= 4;
|
||||
|
@ -213,15 +207,12 @@ syscall(Ureg *ureg)
|
|||
ulong scallnr;
|
||||
vlong startns, stopns;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: pc=%#.8lux", ureg->pc);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
sp = ureg->sp;
|
||||
up->scallnr = scallnr = ureg->r0;
|
||||
|
@ -511,8 +502,6 @@ dbgpc(Proc *)
|
|||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->fpstate == FPactive){
|
||||
if(p->state == Moribund)
|
||||
fpclear();
|
||||
|
@ -520,9 +509,6 @@ procsave(Proc *p)
|
|||
fpsave(p->fpsave);
|
||||
p->fpstate = FPinactive;
|
||||
}
|
||||
cycles(&t);
|
||||
p->kentry -= t;
|
||||
p->pcycles += t;
|
||||
|
||||
l1switch(&m->l1, 0);
|
||||
}
|
||||
|
@ -530,32 +516,13 @@ procsave(Proc *p)
|
|||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
|
||||
cycles(&t);
|
||||
p->kentry += t;
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc dying", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc* p, void (*func)(void*), void* arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr) linkproc;
|
||||
p->sched.pc = (uintptr) entry;
|
||||
p->sched.sp = (uintptr) p->kstack + KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -39,25 +39,6 @@ evenaddr(uintptr addr)
|
|||
}
|
||||
}
|
||||
|
||||
/* go to user space */
|
||||
void
|
||||
kexit(Ureg*)
|
||||
{
|
||||
uvlong t;
|
||||
Tos *tos;
|
||||
|
||||
/* precise time accounting, kernel exit */
|
||||
tos = (Tos*)(USTKTOP-sizeof(Tos));
|
||||
t = fastticks(nil);
|
||||
tos->kcycles += t - up->kentry;
|
||||
tos->pcycles = t + up->pcycles;
|
||||
tos->cyclefreq = Frequency;
|
||||
tos->pid = up->pid;
|
||||
|
||||
/* make visible immediately to user proc */
|
||||
cachedwbinvse(tos, sizeof *tos);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the userpc the last exception happened at
|
||||
*/
|
||||
|
@ -79,29 +60,15 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->psr = ureg->psr & ~(PsrMask|PsrDfiq|PsrDirq) | v & (PsrMask|PsrDfiq|PsrDirq);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr)linkproc;
|
||||
p->sched.pc = (uintptr)entry;
|
||||
p->sched.sp = (uintptr)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -126,16 +93,11 @@ void
|
|||
procsetup(Proc* p)
|
||||
{
|
||||
fpusysprocsetup(p);
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procfork(Proc* p)
|
||||
procfork(Proc*)
|
||||
{
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -144,27 +106,12 @@ procfork(Proc* p)
|
|||
void
|
||||
procsave(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
p->kentry -= t;
|
||||
|
||||
fpuprocsave(p);
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
p->kentry += t;
|
||||
|
||||
fpuprocrestore(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -381,6 +381,7 @@ void
|
|||
archconfinit(void)
|
||||
{
|
||||
m->cpuhz = Frequency;
|
||||
m->cyclefreq = m->cpuhz;
|
||||
m->delayloop = m->cpuhz/2000; /* initial estimate */
|
||||
fixaddrmap();
|
||||
if (Debug)
|
||||
|
|
|
@ -140,8 +140,6 @@ extern int userureg(Ureg*);
|
|||
void* vmap(uintptr, usize);
|
||||
void vunmap(void*, usize);
|
||||
|
||||
extern void kexit(Ureg*);
|
||||
|
||||
#define getpgcolor(a) 0
|
||||
#define kmapinval()
|
||||
|
||||
|
|
|
@ -187,16 +187,13 @@ syscall(Ureg* ureg)
|
|||
int i, scallnr;
|
||||
vlong startns, stopns;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",
|
||||
ureg->pc, ureg->r14, ureg->psr);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
scallnr = ureg->r0;
|
||||
up->scallnr = scallnr;
|
||||
|
|
|
@ -376,12 +376,7 @@ trap(Ureg *ureg)
|
|||
rem, up, ureg, ureg->pc);
|
||||
}
|
||||
|
||||
user = (ureg->psr & PsrMask) == PsrMusr;
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
if(ureg->type == PsrMabt+1)
|
||||
ureg->pc -= 8;
|
||||
else
|
||||
|
|
|
@ -215,11 +215,8 @@ trap(Ureg *ureg)
|
|||
int ecode, user;
|
||||
char buf[ERRMAX], *s;
|
||||
|
||||
user = kenter(ureg);
|
||||
ecode = (ureg->cause >> 8) & 0xff;
|
||||
user = (ureg->srr1 & MSR_PR) != 0;
|
||||
if(user)
|
||||
up->dbgreg = ureg;
|
||||
|
||||
if((ureg->status & MSR_RI) == 0)
|
||||
print("double fault?: ecode = %d\n", ecode);
|
||||
|
||||
|
@ -503,22 +500,11 @@ dumpregs(Ureg *ur)
|
|||
print("%s\t%.8lux\t%s\t%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
(*up->kpfun)(up->kparg);
|
||||
pexit("", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc *p, void (*func)(void*), void *arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (ulong)linkproc;
|
||||
p->sched.pc = (ulong)entry;
|
||||
p->sched.sp = (ulong)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -625,7 +611,6 @@ syscall(Ureg* ureg)
|
|||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
scallnr = ureg->r3;
|
||||
up->scallnr = ureg->r3;
|
||||
|
|
|
@ -39,25 +39,6 @@ evenaddr(uintptr addr)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 = t + 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
|
||||
*/
|
||||
|
@ -79,29 +60,15 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->psr = ureg->psr & ~(PsrMask|PsrDfiq|PsrDirq) | v & (PsrMask|PsrDfiq|PsrDirq);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr)linkproc;
|
||||
p->sched.pc = (uintptr)entry;
|
||||
p->sched.sp = (uintptr)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -126,17 +93,11 @@ void
|
|||
procsetup(Proc* p)
|
||||
{
|
||||
fpusysprocsetup(p);
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procfork(Proc* p)
|
||||
{
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
fpuprocfork(p);
|
||||
}
|
||||
|
||||
|
@ -146,12 +107,6 @@ procfork(Proc* p)
|
|||
void
|
||||
procsave(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
p->kentry -= t;
|
||||
|
||||
// TODO: save and restore VFPv3 FP state once 5[cal] know the new registers.
|
||||
fpuprocsave(p);
|
||||
}
|
||||
|
@ -159,14 +114,6 @@ procsave(Proc* p)
|
|||
void
|
||||
procrestore(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
p->kentry += t;
|
||||
|
||||
fpuprocrestore(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -157,8 +157,6 @@ extern int userureg(Ureg*);
|
|||
void* vmap(uintptr, usize);
|
||||
void vunmap(void*, usize);
|
||||
|
||||
extern void kexit(Ureg*);
|
||||
|
||||
#define getpgcolor(a) 0
|
||||
#define kmapinval()
|
||||
|
||||
|
|
|
@ -186,16 +186,13 @@ syscall(Ureg* ureg)
|
|||
long ret;
|
||||
int i, scallnr;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",
|
||||
ureg->pc, ureg->r14, ureg->psr);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
if(up->procctl == Proc_tracesyscall){
|
||||
up->procctl = Proc_stopme;
|
||||
|
|
|
@ -465,12 +465,7 @@ trap(Ureg *ureg)
|
|||
rem, up, ureg, ureg->pc);
|
||||
}
|
||||
|
||||
user = (ureg->psr & PsrMask) == PsrMusr;
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
/*
|
||||
* All interrupts/exceptions should be resumed at ureg->pc-4,
|
||||
* except for Data Abort which resumes at ureg->pc-8.
|
||||
|
|
|
@ -251,9 +251,6 @@ procsetup(Proc *p)
|
|||
m->dr7 = 0;
|
||||
putdr7(0);
|
||||
}
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -261,9 +258,6 @@ procfork(Proc *p)
|
|||
{
|
||||
int s;
|
||||
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
/* inherit user descriptors */
|
||||
memmove(p->gdt, up->gdt, sizeof(p->gdt));
|
||||
|
||||
|
@ -292,8 +286,6 @@ procfork(Proc *p)
|
|||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->dr[7] != 0){
|
||||
m->dr7 = p->dr[7];
|
||||
putdr(p->dr);
|
||||
|
@ -301,13 +293,6 @@ procrestore(Proc *p)
|
|||
|
||||
if(p->vmx != nil)
|
||||
vmxprocrestore(p);
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
|
||||
cycles(&t);
|
||||
p->kentry += t;
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -316,12 +301,6 @@ procrestore(Proc *p)
|
|||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->kentry -= t;
|
||||
p->pcycles += t;
|
||||
|
||||
/* we could just always putdr7(0) but accessing DR7 might be slow in a VM */
|
||||
if(m->dr7 != 0){
|
||||
m->dr7 = 0;
|
||||
|
|
|
@ -128,21 +128,6 @@ usertrap(int vno)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* 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 = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
/*
|
||||
* All traps come here. It is slower to have all traps call trap()
|
||||
* rather than directly vectoring the handler. However, this avoids a
|
||||
|
@ -155,12 +140,7 @@ trap(Ureg* ureg)
|
|||
{
|
||||
int vno, user;
|
||||
|
||||
user = userureg(ureg);
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
vno = ureg->trap;
|
||||
if(!irqhandled(ureg, vno) && (!user || !usertrap(vno))){
|
||||
if(!user){
|
||||
|
@ -490,15 +470,12 @@ syscall(Ureg* ureg)
|
|||
ulong scallnr;
|
||||
vlong startns, stopns;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: cs 0x%4.4luX", ureg->cs);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
sp = ureg->usp;
|
||||
scallnr = ureg->ax;
|
||||
|
@ -789,27 +766,16 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->ss |= 3;
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc dying", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc* p, void (*func)(void*), void* arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
/*
|
||||
* gotolabel() needs a word on the stack in
|
||||
* which to place the return PC used to jump
|
||||
* to linkproc().
|
||||
*/
|
||||
p->sched.pc = (ulong)linkproc;
|
||||
p->sched.pc = (ulong)entry;
|
||||
p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -304,25 +304,17 @@ procsetup(Proc *p)
|
|||
m->dr7 = 0;
|
||||
putdr7(0);
|
||||
}
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procfork(Proc *p)
|
||||
{
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
fpuprocfork(p);
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->dr[7] != 0){
|
||||
m->dr7 = p->dr[7];
|
||||
putdr(p->dr);
|
||||
|
@ -332,24 +324,11 @@ procrestore(Proc *p)
|
|||
vmxprocrestore(p);
|
||||
|
||||
fpuprocrestore(p);
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
|
||||
cycles(&t);
|
||||
p->kentry += t;
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->kentry -= t;
|
||||
p->pcycles += t;
|
||||
|
||||
if(m->dr7 != 0){
|
||||
m->dr7 = 0;
|
||||
putdr7(0);
|
||||
|
|
|
@ -130,31 +130,12 @@ usertrap(int vno)
|
|||
}
|
||||
|
||||
/* go to user space */
|
||||
void
|
||||
kexit(Ureg*)
|
||||
{
|
||||
uvlong t;
|
||||
Tos *tos;
|
||||
|
||||
/* precise time accounting, kernel exit */
|
||||
tos = (Tos*)((uintptr)USTKTOP-sizeof(Tos));
|
||||
cycles(&t);
|
||||
tos->kcycles += t - up->kentry;
|
||||
tos->pcycles = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
void
|
||||
trap(Ureg *ureg)
|
||||
{
|
||||
int vno, user;
|
||||
|
||||
user = userureg(ureg);
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
vno = ureg->type;
|
||||
if(!irqhandled(ureg, vno) && (!user || !usertrap(vno))){
|
||||
if(!user){
|
||||
|
@ -463,15 +444,12 @@ syscall(Ureg* ureg)
|
|||
ulong scallnr;
|
||||
vlong startns, stopns;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: cs 0x%4.4lluX", ureg->cs);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
sp = ureg->sp;
|
||||
scallnr = ureg->bp; /* RARG */
|
||||
|
@ -775,27 +753,16 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->pc &= UADDRMASK;
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc dying", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc* p, void (*func)(void*), void* arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
/*
|
||||
* gotolabel() needs a word on the stack in
|
||||
* which to place the return PC used to jump
|
||||
* to linkproc().
|
||||
*/
|
||||
p->sched.pc = (uintptr)linkproc;
|
||||
p->sched.pc = (uintptr)entry;
|
||||
p->sched.sp = (uintptr)p->kstack+KSTACK-BY2WD;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -686,7 +686,7 @@ struct Proc
|
|||
|
||||
uvlong kentry; /* Kernel entry time stamp (for profiling) */
|
||||
/*
|
||||
* pcycles: cycles spent in this process (updated on procsave/restore)
|
||||
* pcycles: cycles spent in this process (updated on procswitch)
|
||||
* when this is the current proc and we're in the kernel
|
||||
* (procrestores outnumber procsaves by one)
|
||||
* the number of cycles spent in the proc is pcycles + cycles()
|
||||
|
|
|
@ -150,10 +150,12 @@ int iseve(void);
|
|||
int islo(void);
|
||||
Segment* isoverlap(uintptr, uintptr);
|
||||
Physseg* findphysseg(char*);
|
||||
int kenter(Ureg*);
|
||||
void kexit(Ureg*);
|
||||
void kickpager(void);
|
||||
void killbig(char*);
|
||||
void kproc(char*, void(*)(void*), void*);
|
||||
void kprocchild(Proc*, void (*)(void*), void*);
|
||||
void kprocchild(Proc*, void (*)(void));
|
||||
void (*kproftimer)(uintptr);
|
||||
void ksetenv(char*, char*, int);
|
||||
void kstrcpy(char*, char*, int);
|
||||
|
|
|
@ -79,7 +79,9 @@ devsd.$O: ../port/sd.h /$objtype/include/ureg.h
|
|||
sdscsi.$O: ../port/sd.h /$objtype/include/ureg.h
|
||||
sdaoe.$O: ../port/sd.h /$objtype/include/ureg.h
|
||||
trap.$O: /$objtype/include/ureg.h
|
||||
proc.$O: /$objtype/include/ureg.h
|
||||
devproc.$O: /$objtype/include/ureg.h
|
||||
portclock.$O: /$objtype/include/ureg.h
|
||||
userinit.$O: initcode.i
|
||||
trap.$O: ../port/systab.h
|
||||
devpipe.$O: ../port/netif.h
|
||||
|
@ -94,7 +96,7 @@ screen.$O: screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/curs
|
|||
thwack.$O: ../port/thwack.h
|
||||
unthwack.$O: ../port/thwack.h
|
||||
devsdp.$O: ../port/thwack.h
|
||||
portclock.$O sysproc.$O: /sys/include/tos.h
|
||||
portclock.$O sysproc.$O proc.$O: /sys/include/tos.h
|
||||
devproc.$O edf.$O proc.$O: /sys/include/trace.h
|
||||
auth.$O devcons.$O: /sys/include/authsrv.h
|
||||
devcap.$O: /sys/include/libsec.h
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "../port/error.h"
|
||||
#include "edf.h"
|
||||
#include <trace.h>
|
||||
#include "tos.h"
|
||||
#include "ureg.h"
|
||||
|
||||
int schedgain = 30; /* units in seconds */
|
||||
int nrdy;
|
||||
|
@ -109,6 +111,58 @@ schedinit(void) /* never returns */
|
|||
sched();
|
||||
}
|
||||
|
||||
int
|
||||
kenter(Ureg *ureg)
|
||||
{
|
||||
int user;
|
||||
|
||||
user = userureg(ureg);
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
void
|
||||
kexit(Ureg*)
|
||||
{
|
||||
uvlong t;
|
||||
Tos *tos;
|
||||
|
||||
cycles(&t);
|
||||
|
||||
/* precise time accounting, kernel exit */
|
||||
tos = (Tos*)(USTKTOP-sizeof(Tos));
|
||||
tos->kcycles += t - up->kentry;
|
||||
tos->pcycles = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
static void
|
||||
procswitch(void)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
/* statistics */
|
||||
m->cs++;
|
||||
|
||||
cycles(&t);
|
||||
up->kentry -= t;
|
||||
up->pcycles += t;
|
||||
|
||||
procsave(up);
|
||||
|
||||
if(!setlabel(&up->sched))
|
||||
gotolabel(&m->sched);
|
||||
|
||||
procrestore(up);
|
||||
|
||||
cycles(&t);
|
||||
up->kentry += t;
|
||||
up->pcycles -= t;
|
||||
}
|
||||
|
||||
/*
|
||||
* If changing this routine, look also at sleep(). It
|
||||
* contains a copy of the guts of sched().
|
||||
|
@ -151,19 +205,10 @@ sched(void)
|
|||
return;
|
||||
}
|
||||
up->delaysched = 0;
|
||||
|
||||
splhi();
|
||||
|
||||
/* statistics */
|
||||
m->cs++;
|
||||
|
||||
procsave(up);
|
||||
if(setlabel(&up->sched)){
|
||||
procrestore(up);
|
||||
spllo();
|
||||
return;
|
||||
}
|
||||
gotolabel(&m->sched);
|
||||
procswitch();
|
||||
spllo();
|
||||
return;
|
||||
}
|
||||
p = runproc();
|
||||
if(p->edf == nil){
|
||||
|
@ -758,25 +803,9 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
|
|||
pt(up, SSleep, 0);
|
||||
up->state = Wakeme;
|
||||
up->r = r;
|
||||
|
||||
/* statistics */
|
||||
m->cs++;
|
||||
|
||||
procsave(up);
|
||||
if(setlabel(&up->sched)) {
|
||||
/*
|
||||
* here when the process is awakened
|
||||
*/
|
||||
procrestore(up);
|
||||
spllo();
|
||||
} else {
|
||||
/*
|
||||
* here to go to sleep (i.e. stop Running)
|
||||
*/
|
||||
unlock(&up->rlock);
|
||||
unlock(r);
|
||||
gotolabel(&m->sched);
|
||||
}
|
||||
unlock(&up->rlock);
|
||||
unlock(r);
|
||||
procswitch();
|
||||
}
|
||||
|
||||
if(up->notepending) {
|
||||
|
@ -1376,6 +1405,14 @@ procflushothers(void)
|
|||
procflushmmu(matchother, up);
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
(*up->kpfun)(up->kparg);
|
||||
pexit("kproc exiting", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kproc(char *name, void (*func)(void *), void *arg)
|
||||
{
|
||||
|
@ -1406,7 +1443,9 @@ kproc(char *name, void (*func)(void *), void *arg)
|
|||
p->hang = 0;
|
||||
p->kp = 1;
|
||||
|
||||
kprocchild(p, func, arg);
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
kprocchild(p, linkproc);
|
||||
|
||||
kstrdup(&p->text, name);
|
||||
kstrdup(&p->user, eve);
|
||||
|
@ -1422,6 +1461,8 @@ kproc(char *name, void (*func)(void *), void *arg)
|
|||
p->insyscall = 1;
|
||||
memset(p->time, 0, sizeof(p->time));
|
||||
p->time[TReal] = MACHP(0)->ticks;
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
pidalloc(p);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ sysr1(va_list)
|
|||
}
|
||||
|
||||
static void
|
||||
abortion(void*)
|
||||
abortion(void)
|
||||
{
|
||||
pexit("fork aborted", 1);
|
||||
}
|
||||
|
@ -125,6 +125,8 @@ sysrfork(va_list list)
|
|||
p->insyscall = 0;
|
||||
memset(p->time, 0, sizeof(p->time));
|
||||
p->time[TReal] = MACHP(0)->ticks;
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
pid = pidalloc(p);
|
||||
|
||||
|
@ -133,7 +135,7 @@ sysrfork(va_list list)
|
|||
/* Abort the child process on error */
|
||||
if(waserror()){
|
||||
p->kp = 1;
|
||||
kprocchild(p, abortion, 0);
|
||||
kprocchild(p, abortion);
|
||||
ready(p);
|
||||
nexterror();
|
||||
}
|
||||
|
@ -577,6 +579,7 @@ sysexec(va_list list)
|
|||
up->notified = 0;
|
||||
up->privatemem = 0;
|
||||
up->noswap = 0;
|
||||
up->pcycles = -up->kentry;
|
||||
procsetup(up);
|
||||
qunlock(&up->debug);
|
||||
|
||||
|
|
|
@ -186,28 +186,16 @@ void
|
|||
procsetup(Proc *p)
|
||||
{
|
||||
p->fpstate = FPinit;
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procfork(Proc *p)
|
||||
{
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
p->kentry += t;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -216,11 +204,6 @@ procrestore(Proc *p)
|
|||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
p->kentry -= t;
|
||||
if(p->fpstate == FPactive){
|
||||
if(p->state != Moribund)
|
||||
fpsave(up->fpsave);
|
||||
|
|
|
@ -140,20 +140,6 @@ char *regname[]={
|
|||
"DAR", "DSISR",
|
||||
};
|
||||
|
||||
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 = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
void
|
||||
trap(Ureg *ureg)
|
||||
{
|
||||
|
@ -161,15 +147,10 @@ trap(Ureg *ureg)
|
|||
char buf[ERRMAX], *s;
|
||||
extern FPsave initfp;
|
||||
|
||||
ecode = (ureg->cause >> 8) & 0xff;
|
||||
user = (ureg->srr1 & MSR_PR) != 0;
|
||||
if(user){
|
||||
cycles(&up->kentry);
|
||||
up->dbgreg = ureg;
|
||||
}
|
||||
user = kenter(ureg);
|
||||
if((ureg->status & MSR_RI) == 0)
|
||||
print("double fault?: ecode = %d\n", ecode);
|
||||
|
||||
ecode = (ureg->cause >> 8) & 0xff;
|
||||
switch(ecode) {
|
||||
case CEI:
|
||||
m->intr++;
|
||||
|
@ -495,22 +476,11 @@ dumpregs(Ureg *ur)
|
|||
delay(500);
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
(*up->kpfun)(up->kparg);
|
||||
pexit("", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc *p, void (*func)(void*), void *arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (ulong)linkproc;
|
||||
p->sched.pc = (ulong)entry;
|
||||
p->sched.sp = (ulong)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -618,7 +588,6 @@ syscall(Ureg* ureg)
|
|||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
if (up->fpstate == FPactive && (ureg->srr1 & MSR_FP) == 0){
|
||||
print("fpstate check, entry syscall\n");
|
||||
|
|
|
@ -80,7 +80,7 @@ clockinit(void)
|
|||
|
||||
m->speed = mips;
|
||||
m->hz = m->speed*Mhz;
|
||||
|
||||
m->cyclefreq = Basetickfreq;
|
||||
m->maxperiod = Basetickfreq / HZ;
|
||||
m->minperiod = Basetickfreq / (100*HZ);
|
||||
m->lastcount = rdcount();
|
||||
|
|
|
@ -289,9 +289,6 @@ procsetup(Proc *p)
|
|||
{
|
||||
p->fpstate = FPinit;
|
||||
memmove(p->fpsave, &initfp, sizeof(FPsave));
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -299,9 +296,6 @@ procfork(Proc *p)
|
|||
{
|
||||
int s;
|
||||
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
s = splhi();
|
||||
switch(up->fpstate & ~FPillegal){
|
||||
case FPactive:
|
||||
|
@ -318,28 +312,17 @@ procfork(Proc *p)
|
|||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->fpstate == FPactive){
|
||||
if(p->state != Moribund) {
|
||||
savefpregs(p->fpsave);
|
||||
p->fpstate = FPinactive;
|
||||
}
|
||||
}
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -152,23 +152,6 @@ kvce(Ureg *ur, int ecode)
|
|||
}
|
||||
}
|
||||
|
||||
/* prepare to go to user space */
|
||||
void
|
||||
kexit(Ureg *ur)
|
||||
{
|
||||
Tos *tos;
|
||||
|
||||
/* replicate fpstate to ureg status */
|
||||
if(up->fpstate != FPactive)
|
||||
ur->status &= ~CU1;
|
||||
|
||||
/* precise time accounting, kernel exit */
|
||||
tos = (Tos*)(USTKTOP-sizeof(Tos));
|
||||
tos->kcycles += fastticks(&tos->cyclefreq) - up->kentry;
|
||||
tos->pcycles = up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
void
|
||||
trap(Ureg *ur)
|
||||
{
|
||||
|
@ -190,18 +173,11 @@ trap(Ureg *ur)
|
|||
dumpstack();
|
||||
for(;;);
|
||||
}
|
||||
|
||||
ecode = (ur->cause>>2)&EXCMASK;
|
||||
user = userureg(ur);
|
||||
user = kenter(ur);
|
||||
if (ur->cause & TS)
|
||||
panic("trap: tlb shutdown");
|
||||
|
||||
ecode = (ur->cause>>2)&EXCMASK;
|
||||
fpchk = 0;
|
||||
if(user){
|
||||
up->dbgreg = ur;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
clockintr = 0;
|
||||
switch(ecode){
|
||||
case CINT:
|
||||
|
@ -308,6 +284,9 @@ trap(Ureg *ur)
|
|||
|
||||
if(user){
|
||||
notify(ur);
|
||||
/* replicate fpstate to ureg status */
|
||||
if(up->fpstate != FPactive)
|
||||
ur->status &= ~CU1;
|
||||
kexit(ur);
|
||||
}
|
||||
}
|
||||
|
@ -701,12 +680,12 @@ syscall(Ureg *ur)
|
|||
vlong startns;
|
||||
char *e;
|
||||
|
||||
cycles(&up->kentry);
|
||||
if(!kenter(ur))
|
||||
panic("syscall from kernel");
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ur->pc;
|
||||
up->dbgreg = ur;
|
||||
ur->cause = 16<<2; /* for debugging: system call is undef 16 */
|
||||
|
||||
scallnr = ur->r1;
|
||||
|
@ -774,6 +753,9 @@ syscall(Ureg *ur)
|
|||
/* if we delayed sched because we held a lock, sched now */
|
||||
if(up->delaysched)
|
||||
sched();
|
||||
/* replicate fpstate to ureg status */
|
||||
if(up->fpstate != FPactive)
|
||||
ur->status &= ~CU1;
|
||||
kexit(ur);
|
||||
}
|
||||
|
||||
|
@ -794,23 +776,11 @@ forkchild(Proc *p, Ureg *ur)
|
|||
cur->pc += 4;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
linkproc(void)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc exiting", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc *p, void (*func)(void*), void *arg)
|
||||
{
|
||||
p->sched.pc = (ulong)linkproc;
|
||||
p->sched.pc = (ulong)entry;
|
||||
p->sched.sp = (ulong)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/* set up user registers before return from exec() */
|
||||
|
|
|
@ -39,25 +39,6 @@ evenaddr(uintptr addr)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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 phase */
|
||||
l1cache->wbse(tos, sizeof *tos);
|
||||
}
|
||||
|
||||
/*
|
||||
* return the userpc the last exception happened at
|
||||
*/
|
||||
|
@ -79,29 +60,15 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->psr = ureg->psr & ~(PsrMask|PsrDfiq|PsrDirq) | v & (PsrMask|PsrDfiq|PsrDirq);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr)linkproc;
|
||||
p->sched.pc = (uintptr)entry;
|
||||
p->sched.sp = (uintptr)p->kstack+KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -134,11 +101,6 @@ procsetup(Proc* p)
|
|||
void
|
||||
procsave(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
|
||||
fpuprocsave(p);
|
||||
l1cache->wbse(p, sizeof *p); /* is this needed? */
|
||||
l1cache->wb(); /* is this needed? */
|
||||
|
@ -147,21 +109,14 @@ procsave(Proc* p)
|
|||
void
|
||||
procfork(Proc* p)
|
||||
{
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
fpuprocfork(p);
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc* p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
wakewfi(); /* in case there's another runnable proc */
|
||||
|
||||
/* let it fault in at first use */
|
||||
|
|
|
@ -327,6 +327,7 @@ archconfinit(void)
|
|||
if (hz >= 100*Mhz && hz <= 3600UL*Mhz)
|
||||
m->cpuhz = hz;
|
||||
}
|
||||
m->cyclefreq = m->cpuhz;
|
||||
m->delayloop = m->cpuhz/2000; /* initial estimate */
|
||||
errata();
|
||||
}
|
||||
|
|
|
@ -191,8 +191,6 @@ extern int userureg(Ureg*);
|
|||
void* vmap(uintptr, usize);
|
||||
void vunmap(void*, usize);
|
||||
|
||||
extern void kexit(Ureg*);
|
||||
|
||||
#define getpgcolor(a) 0
|
||||
#define kmapinval()
|
||||
|
||||
|
|
|
@ -194,16 +194,13 @@ syscall(Ureg* ureg)
|
|||
int i, scallnr;
|
||||
vlong startns, stopns;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: from kernel: pc %#lux r14 %#lux psr %#lux",
|
||||
ureg->pc, ureg->r14, ureg->psr);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
scallnr = ureg->r0;
|
||||
up->scallnr = scallnr;
|
||||
|
|
|
@ -831,12 +831,7 @@ trap(Ureg *ureg)
|
|||
}
|
||||
|
||||
m->perf.intrts = perfticks();
|
||||
user = (ureg->psr & PsrMask) == PsrMusr;
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
/*
|
||||
* All interrupts/exceptions should be resumed at ureg->pc-4,
|
||||
* except for Data Abort which resumes at ureg->pc-8.
|
||||
|
|
|
@ -337,9 +337,6 @@ procfork(Proc *p)
|
|||
{
|
||||
int s;
|
||||
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
/* save floating point state */
|
||||
s = splhi();
|
||||
switch(up->fpstate & ~FPillegal){
|
||||
|
@ -358,12 +355,6 @@ procfork(Proc *p)
|
|||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
cycles(&t);
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -372,10 +363,6 @@ procrestore(Proc *p)
|
|||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
cycles(&t);
|
||||
p->pcycles += t;
|
||||
if(p->fpstate == FPactive){
|
||||
if(p->state == Moribund)
|
||||
fpclear();
|
||||
|
|
|
@ -134,22 +134,6 @@ usertrap(int vno)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* 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->pid = up->pid;
|
||||
INTRLOG(dprint("leave kexit, TOS %p\n", tos);)
|
||||
}
|
||||
|
||||
/*
|
||||
* All traps come here. It is slower to have all traps call trap()
|
||||
* rather than directly vectoring the handler. However, this avoids a
|
||||
|
@ -162,12 +146,7 @@ trap(Ureg* ureg)
|
|||
{
|
||||
int vno, user;
|
||||
|
||||
user = userureg(ureg);
|
||||
if(user){
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
|
||||
user = kenter(ureg);
|
||||
vno = ureg->trap;
|
||||
if(!irqhandled(ureg, vno) && (!user || !usertrap(vno))){
|
||||
if(!user){
|
||||
|
@ -406,15 +385,12 @@ syscall(Ureg* ureg)
|
|||
SYSCALLLOG(dprint("%d: syscall ...#%ld(%s)\n",
|
||||
up->pid, ureg->ax, sysctab[ureg->ax]);)
|
||||
|
||||
if((ureg->cs & 0xFFFF) != UESEL)
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: cs 0x%4.4luX\n", ureg->cs);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
if(up->procctl == Proc_tracesyscall){
|
||||
up->procctl = Proc_stopme;
|
||||
|
@ -725,27 +701,16 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
|
|||
ureg->ss = ss;
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc dying", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc* p, void (*func)(void*), void* arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
/*
|
||||
* gotolabel() needs a word on the stack in
|
||||
* which to place the return PC used to jump
|
||||
* to linkproc().
|
||||
*/
|
||||
p->sched.pc = (ulong)linkproc;
|
||||
p->sched.pc = (ulong)entry;
|
||||
p->sched.sp = (ulong)p->kstack+KSTACK-BY2WD;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -30,7 +30,6 @@ void mmuinit(void);
|
|||
uintptr ttbget(void);
|
||||
void ttbput(uintptr);
|
||||
void cycles(uvlong *);
|
||||
void kexit(Ureg *);
|
||||
ulong getifsr(void);
|
||||
ulong getdfsr(void);
|
||||
uintptr getifar(void);
|
||||
|
|
|
@ -43,9 +43,6 @@ procfork(Proc *p)
|
|||
{
|
||||
ulong s;
|
||||
|
||||
p->kentry = up->kentry;
|
||||
p->pcycles = -p->kentry;
|
||||
|
||||
s = splhi();
|
||||
switch(up->fpstate & ~FPillegal){
|
||||
case FPactive:
|
||||
|
@ -63,22 +60,6 @@ procsetup(Proc *p)
|
|||
{
|
||||
p->fpstate = FPinit;
|
||||
fpoff();
|
||||
|
||||
cycles(&p->kentry);
|
||||
p->pcycles = -p->kentry;
|
||||
}
|
||||
|
||||
void
|
||||
kexit(Ureg *)
|
||||
{
|
||||
Tos *tos;
|
||||
uvlong t;
|
||||
|
||||
tos = (Tos*)(USTKTOP-sizeof(Tos));
|
||||
cycles(&t);
|
||||
tos->kcycles += t - up->kentry;
|
||||
tos->pcycles = t + up->pcycles;
|
||||
tos->pid = up->pid;
|
||||
}
|
||||
|
||||
ulong *l2;
|
||||
|
|
|
@ -150,13 +150,7 @@ trap(Ureg *ureg)
|
|||
int user;
|
||||
ulong opc, cp;
|
||||
|
||||
user = userureg(ureg);
|
||||
if(user){
|
||||
if(up == nil)
|
||||
panic("user trap: up=nil");
|
||||
up->dbgreg = ureg;
|
||||
cycles(&up->kentry);
|
||||
}
|
||||
user = kenter(ureg);
|
||||
switch(ureg->type){
|
||||
case PsrMund:
|
||||
ureg->pc -= 4;
|
||||
|
@ -213,15 +207,12 @@ syscall(Ureg *ureg)
|
|||
ulong scallnr;
|
||||
vlong startns, stopns;
|
||||
|
||||
if(!userureg(ureg))
|
||||
if(!kenter(ureg))
|
||||
panic("syscall: pc=%#.8lux", ureg->pc);
|
||||
|
||||
cycles(&up->kentry);
|
||||
|
||||
m->syscall++;
|
||||
up->insyscall = 1;
|
||||
up->pc = ureg->pc;
|
||||
up->dbgreg = ureg;
|
||||
|
||||
sp = ureg->sp;
|
||||
up->scallnr = scallnr = ureg->r0;
|
||||
|
@ -511,8 +502,6 @@ dbgpc(Proc *)
|
|||
void
|
||||
procsave(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->fpstate == FPactive){
|
||||
if(p->state == Moribund)
|
||||
fpclear();
|
||||
|
@ -520,42 +509,19 @@ procsave(Proc *p)
|
|||
fpsave(p->fpsave);
|
||||
p->fpstate = FPinactive;
|
||||
}
|
||||
cycles(&t);
|
||||
p->kentry -= t;
|
||||
p->pcycles += t;
|
||||
|
||||
l1switch(&m->l1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
procrestore(Proc *p)
|
||||
{
|
||||
uvlong t;
|
||||
|
||||
if(p->kp)
|
||||
return;
|
||||
|
||||
cycles(&t);
|
||||
p->kentry += t;
|
||||
p->pcycles -= t;
|
||||
}
|
||||
|
||||
static void
|
||||
linkproc(void)
|
||||
{
|
||||
spllo();
|
||||
up->kpfun(up->kparg);
|
||||
pexit("kproc dying", 0);
|
||||
}
|
||||
|
||||
void
|
||||
kprocchild(Proc* p, void (*func)(void*), void* arg)
|
||||
kprocchild(Proc *p, void (*entry)(void))
|
||||
{
|
||||
p->sched.pc = (uintptr) linkproc;
|
||||
p->sched.pc = (uintptr) entry;
|
||||
p->sched.sp = (uintptr) p->kstack + KSTACK;
|
||||
|
||||
p->kpfun = func;
|
||||
p->kparg = arg;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue