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:
cinap_lenrek 2020-12-20 22:34:41 +01:00
parent 08c1622b0d
commit e4ce6aadac
44 changed files with 157 additions and 767 deletions

View file

@ -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);
}

View file

@ -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)

View file

@ -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.

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);
}

View file

@ -381,6 +381,7 @@ void
archconfinit(void)
{
m->cpuhz = Frequency;
m->cyclefreq = m->cpuhz;
m->delayloop = m->cpuhz/2000; /* initial estimate */
fixaddrmap();
if (Debug)

View file

@ -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()

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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()

View file

@ -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;

View file

@ -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.

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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()

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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");

View file

@ -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();

View file

@ -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

View file

@ -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() */

View file

@ -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 */

View file

@ -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();
}

View file

@ -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()

View file

@ -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;

View file

@ -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.

View file

@ -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();

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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