From 6d695bf12d7d52bcc14e77c2ab625ae93aa4e895 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 12 Jan 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-01-12 --- alphapc/dat.h | 2 +- alphapc/main.c | 3 +- mtx/dat.h | 4 +-- mtx/fns.h | 14 +++++--- mtx/l.s | 94 ++++++++++++++++++++++++++++++++++++++++++++++++-- mtx/main.c | 27 ++++++++++++--- mtx/mem.h | 7 +++- mtx/mmu.c | 8 ++--- mtx/trap.c | 61 +++++++++++++++++++++----------- 9 files changed, 177 insertions(+), 43 deletions(-) diff --git a/alphapc/dat.h b/alphapc/dat.h index c192404c1b3db2f4498d58c58677a62c818bdc5b..cd596b702927086720a121cf8e95977c16a1afb2 100644 --- a/alphapc/dat.h +++ b/alphapc/dat.h @@ -43,7 +43,7 @@ struct Label }; /* - * FPsave.fpstatus + * Proc.fpstate */ enum { diff --git a/alphapc/main.c b/alphapc/main.c index 5d4d5c8af576eb79f959d4f4312af1c2e3d1e937..b278b51b27c3ae4f77aa8e8256da94bbac31cd59 100644 --- a/alphapc/main.c +++ b/alphapc/main.c @@ -258,14 +258,13 @@ procsave(Proc *p) */ } -/* still too do */ +/* still to do */ void reboot(void*, void*, ulong) { exit(0); } - void exit(int) { diff --git a/mtx/dat.h b/mtx/dat.h index 687c22a58bc27a6fb4646d5af13efad5883e3e23..60642cd2e894ffa17978280c469ee003527ebb89 100644 --- a/mtx/dat.h +++ b/mtx/dat.h @@ -42,7 +42,7 @@ struct Label }; /* - * FPsave.fpstatus + * Proc.fpstate */ enum { @@ -64,8 +64,6 @@ struct FPsave ulong fpscr; }; }; - int fpistate; /* emulated fp */ - ulong emreg[32][3]; /* emulated fp */ }; struct Conf diff --git a/mtx/fns.h b/mtx/fns.h index ddb5b11e1a5ef9aa5275365a3c5b781044460032..9b07b0f7e4b62a8bc1fd43b5137e71811f045df5 100644 --- a/mtx/fns.h +++ b/mtx/fns.h @@ -6,8 +6,7 @@ int cistrncmp(char*, char*, int); void clockcheck(void); void clockinit(void); void clockintr(Ureg*); -void clrfptrap(void); -#define coherence() +#define coherence() eieio() void cpuidentify(void); void cpuidprint(void); void dcflush(void*, ulong); @@ -19,14 +18,17 @@ void evenaddr(ulong); void faultpower(Ureg*, ulong addr, int read); void firmware(void); void fpinit(void); -int fpipower(Ureg*); -void fpoff(void); -ulong fpstatus(void); +void fpoff(Proc*); +void fprestore(FPsave*); +void fpsave(FPsave*); +void fptrap(Ureg*); char* getconf(char*); ulong getdar(void); ulong getdec(void); ulong getdepn(void); ulong getdsisr(void); +ulong gethid0(void); +ulong gethid1(void); ulong getimmr(void); ulong getmsr(void); ulong getpvr(void); @@ -93,6 +95,8 @@ void pcisetbme(Pcidev*); void procsave(Proc*); void procsetup(Proc*); void putdec(ulong); +void puthid0(ulong); +void puthid1(ulong); void putmsr(ulong); void putsdr1(ulong); void putsr(int, ulong); diff --git a/mtx/l.s b/mtx/l.s index 8862811f714a728f309db7bae8a8f3925512f8da..02ff8466ff4126e4b8db756dce37b0b0c7bcf4da 100644 --- a/mtx/l.s +++ b/mtx/l.s @@ -286,6 +286,22 @@ TEXT putsr(SB), $0 MOVW R4, SEG(R3) RETURN +TEXT gethid0(SB), $0 + MOVW SPR(HID0), R3 + RETURN + +TEXT gethid1(SB), $0 + MOVW SPR(HID1), R3 + RETURN + +TEXT puthid0(SB), $0 + MOVW R3, SPR(HID0) + RETURN + +TEXT puthid1(SB), $0 + MOVW R3, SPR(HID1) + RETURN + TEXT eieio(SB), $0 EIEIO RETURN @@ -349,7 +365,6 @@ TEXT trapvec(SB), $-4 MOVW R0, R2 BL saveureg(SB) BL trap(SB) -// BL splhi(SB) /* BUG? */ BR restoreureg ktrap: MOVW R1, CR @@ -358,7 +373,6 @@ ktrap: SUB $UREGSPACE, R1 BL saveureg(SB) BL trap(SB) -// BL splhi(SB) /* BUG? */ BR restoreureg /* @@ -405,7 +419,7 @@ TEXT saveureg(SB), $-4 MOVW $0, R0 /* compiler/linker expect R0 to be zero */ MOVW MSR, R5 - OR $(MSR_IR|MSR_DR|MSR_RI), R5 /* enable MMU */ + OR $(MSR_IR|MSR_DR|MSR_FP|MSR_RI), R5 /* enable MMU */ MOVW R5, SPR(SRR1) MOVW LR, R31 OR $KZERO, R31 /* return PC in KSEG0 */ @@ -441,3 +455,77 @@ restoreureg: MOVW 44(R1), R1 /* old SP */ MOVW SPR(SAVER0), R0 RFI + +TEXT fpsave(SB), $0 + FMOVD F0, (0*8)(R3) + FMOVD F1, (1*8)(R3) + FMOVD F2, (2*8)(R3) + FMOVD F3, (3*8)(R3) + FMOVD F4, (4*8)(R3) + FMOVD F5, (5*8)(R3) + FMOVD F6, (6*8)(R3) + FMOVD F7, (7*8)(R3) + FMOVD F8, (8*8)(R3) + FMOVD F9, (9*8)(R3) + FMOVD F10, (10*8)(R3) + FMOVD F11, (11*8)(R3) + FMOVD F12, (12*8)(R3) + FMOVD F13, (13*8)(R3) + FMOVD F14, (14*8)(R3) + FMOVD F15, (15*8)(R3) + FMOVD F16, (16*8)(R3) + FMOVD F17, (17*8)(R3) + FMOVD F18, (18*8)(R3) + FMOVD F19, (19*8)(R3) + FMOVD F20, (20*8)(R3) + FMOVD F21, (21*8)(R3) + FMOVD F22, (22*8)(R3) + FMOVD F23, (23*8)(R3) + FMOVD F24, (24*8)(R3) + FMOVD F25, (25*8)(R3) + FMOVD F26, (26*8)(R3) + FMOVD F27, (27*8)(R3) + FMOVD F28, (28*8)(R3) + FMOVD F29, (29*8)(R3) + FMOVD F30, (30*8)(R3) + FMOVD F31, (31*8)(R3) + MOVFL FPSCR, F0 + FMOVD F0, (32*8)(R3) + RETURN + +TEXT fprestore(SB), $0 + FMOVD (32*8)(R3), F0 + MOVFL F0, FPSCR + FMOVD (0*8)(R3), F0 + FMOVD (1*8)(R3), F1 + FMOVD (2*8)(R3), F2 + FMOVD (3*8)(R3), F3 + FMOVD (4*8)(R3), F4 + FMOVD (5*8)(R3), F5 + FMOVD (6*8)(R3), F6 + FMOVD (7*8)(R3), F7 + FMOVD (8*8)(R3), F8 + FMOVD (9*8)(R3), F9 + FMOVD (10*8)(R3), F10 + FMOVD (11*8)(R3), F11 + FMOVD (12*8)(R3), F12 + FMOVD (13*8)(R3), F13 + FMOVD (14*8)(R3), F14 + FMOVD (15*8)(R3), F15 + FMOVD (16*8)(R3), F16 + FMOVD (17*8)(R3), F17 + FMOVD (18*8)(R3), F18 + FMOVD (19*8)(R3), F19 + FMOVD (20*8)(R3), F20 + FMOVD (21*8)(R3), F21 + FMOVD (22*8)(R3), F22 + FMOVD (23*8)(R3), F23 + FMOVD (24*8)(R3), F24 + FMOVD (25*8)(R3), F25 + FMOVD (26*8)(R3), F26 + FMOVD (27*8)(R3), F27 + FMOVD (28*8)(R3), F28 + FMOVD (29*8)(R3), F29 + FMOVD (30*8)(R3), F30 + FMOVD (31*8)(R3), F31 + RETURN diff --git a/mtx/main.c b/mtx/main.c index 6e0442f54b885b14986b6a8795e1c70725b53261..60b16d0777a005b7eb49dc7cd4ccc424cba81cae 100644 --- a/mtx/main.c +++ b/mtx/main.c @@ -35,6 +35,8 @@ main(void) chandevreset(); pageinit(); swapinit(); + fpsave(&initfp); + initfp.fpscr = 0; userinit(); schedinit(); } @@ -51,8 +53,11 @@ machinit(void) * be enough for a while. Cpuidentify will * calculate the real value later. */ -// m->loopconst = 100000; -m->loopconst = 5000; /* dog slow, the cache must be off */ + m->loopconst = 100000; + + /* turn on caches (instruction only for now) */ + puthid0(gethid0() | BIT(16)); +//puthid0(gethid0() | BIT(16) | BIT(17)); /* and data */ active.machs = 1; active.exiting = 0; @@ -245,7 +250,7 @@ exit(int ispanic) void procsetup(Proc *p) { - USED(p); + p->fpstate = FPinit; } /* @@ -254,7 +259,21 @@ procsetup(Proc *p) void procsave(Proc *p) { - USED(p); + if(p->fpstate == FPactive){ + if(p->state != Moribund) { + /* + * Fpsave() stores without handling pending + * unmasked exeptions. Postnote() can't be called + * here as sleep() already has up->rlock, so + * the handling of pending exceptions is delayed + * until the process runs again and generates an + * emulation fault to activate the FPU. + */ + fpsave(&up->fpsave); + } + fpoff(p); + p->fpstate = FPinactive; + } } void diff --git a/mtx/mem.h b/mtx/mem.h index 66ff0652a615726735d2c8ea71b7de24a5b76f32..77de81c258fbdefe0450236f0aaff1a1099ff5a3 100644 --- a/mtx/mem.h +++ b/mtx/mem.h @@ -22,7 +22,7 @@ #define MHz 1000000 #define BY2PTE 8 /* bytes per pte entry */ -#define PTE2PG (BY2PG/BY2PTE) /* pte entries per page */ +#define BY2PTEG 64 /* bytes per pte group */ #define MAXMACH 1 /* max # cpus system can run */ #define MACHSIZE BY2PG @@ -140,6 +140,11 @@ #define SSEGMAPSIZE 16 #define PPN(x) ((x)&~(BY2PG-1)) +/* + * First pte word + */ +#define PTE0(v, vsid, h, va) (((v)<<31)|((vsid)<<7)|((h)<<6)|(((va)>>22)&0x3f)) + /* * Second pte word, known by fault.c, passed to putmmu() */ diff --git a/mtx/mmu.c b/mtx/mmu.c index 868c1c3531f839314636273615ba4ef283242947..51f0effe9a3ff4ddb73e7741a69f513da784ca6c 100644 --- a/mtx/mmu.c +++ b/mtx/mmu.c @@ -106,11 +106,11 @@ putmmu(ulong va, ulong pa, Page*) vsid = VSID(mp, va>>28); hash = (vsid ^ (va>>12)&0xffff) & ptab.mask; - ptehi = BIT(0)|(vsid<<7)|((va>>22)&0x3f); + ptehi = PTE0(1, vsid, 0, va); - pteg = ptab.base + 64*hash; + pteg = ptab.base + BY2PTEG*hash; p = (ulong*)pteg; - ep = (ulong*)(pteg+64); + ep = (ulong*)(pteg+BY2PTEG); q = nil; lock(&ptab); tlbflush(va); @@ -127,7 +127,7 @@ if(q[1] == pa) panic("putmmu already set pte"); } if(q == nil) { q = (ulong*)(pteg+ptab.slotgen); - ptab.slotgen = (ptab.slotgen + 8) & 0x3f; + ptab.slotgen = (ptab.slotgen + BY2PTE) & (BY2PTEG-1); } q[0] = ptehi; q[1] = pa; diff --git a/mtx/trap.c b/mtx/trap.c index d97ba1021edfc1dafa428c027b57ecb9dc58a390..42ba033e43ce9d6bdbb373c193ccf0ea600ec614 100644 --- a/mtx/trap.c +++ b/mtx/trap.c @@ -143,10 +143,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) xfree(v); } -void faultpower(Ureg *ur, ulong addr, int read); void syscall(Ureg* ureg); void noted(Ureg*, ulong); -void reset(void); char *excname[] = { @@ -208,8 +206,6 @@ char *regname[]={ "R30", "R31", }; -static int lastecode; - void trap(Ureg *ur) { @@ -232,7 +228,28 @@ trap(Ureg *ur) clockintr(ur); break; case CSYSCALL: + if(!user) + panic("syscall in kernel: srr1 0x%4.4uX\n", ur->srr1); syscall(ur); + return; /* syscall() calls notify itself, don't do it again */ + case CFPU: + if(!user || up == nil) { + dumpregs(ur); + panic("floating point in kernel"); + } + switch(up->fpstate){ + case FPinit: + fprestore(&initfp); + up->fpstate = FPactive; + break; + case FPinactive: + fprestore(&up->fpsave); + up->fpstate = FPactive; + break; + default: + panic("fpstate"); + } + ur->srr1 |= MSR_FP; break; case CISI: faultpower(ur, ur->pc, 1); @@ -274,12 +291,11 @@ trap(Ureg *ur) panic("%s", excname[ecode]); panic("unknown trap/intr: %d\n", ecode); } -lastecode = ecode; - if(user && (up->procctl || up->nnote)){ - splhi(); + /* restoreureg must execute at high IPL */ + splhi(); + if(user) notify(ur); - } } void @@ -299,7 +315,6 @@ faultpower(Ureg *ureg, ulong addr, int read) panic("fault: 0x%lux", addr); } dumpregs(ureg); -print("last ecode %x\n", lastecode); sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", addr); postnote(up, 1, buf, NDebug); } @@ -406,6 +421,15 @@ fpexcname(Ureg *ur, ulong fpscr, char *buf) return buf; } +void +fpoff(Proc *p) +{ + Ureg *ur; + + ur = p->dbgreg; + ur->srr1 &= ~MSR_FP; +} + /* * Fill in enough of Ureg to get a stack trace, and call a function. * Used by debugging interface rdb. @@ -510,6 +534,7 @@ execregs(ulong entry, ulong ssize, ulong nargs) ureg = up->dbgreg; ureg->usp = (ulong)sp; ureg->pc = entry; + ureg->srr1 &= ~MSR_FP; return USTKTOP-BY2WD; /* address of user-level clock */ } @@ -581,19 +606,14 @@ dbgpc(Proc *p) */ #include "../port/systab.h" -/* - * Syscall should be called directly from assembler without going through trap(). - */ +/* TODO: make this trap a separate asm entry point, like on other RISC architectures */ void syscall(Ureg* ureg) { char *e; - ulong sp; + ulong sp; long ret; - int i, scallnr; - - if((ureg->srr1 & MSR_PR) == 0) - panic("syscall: srr1 0x%4.4uX\n", ureg->srr1); + int i, scallnr; m->syscall++; up->insyscall = 1; @@ -651,11 +671,12 @@ syscall(Ureg* ureg) if(scallnr == NOTED) noted(ureg, *(ulong*)(sp+BY2WD)); - if(scallnr!=RFORK && (up->procctl || up->nnote)){ - splhi(); + /* restoreureg must execute at high IPL */ + splhi(); + if(scallnr!=RFORK) notify(ureg); - } } + /* * Call user, if necessary, with note. * Pass user the Ureg struct and the note on his stack.