ref: e5e153803e3a361c15bd907917b06c56581921dd
parent: 3cf826f2dd2b40758d084fbc3737f74a82d35425
author: mia soweli <mia@soweli.net>
date: Sun Aug 3 16:45:03 EDT 2025
*: update for shared syscalls and notes make this build on a modern 9front will all the changes to system call handling and note handling. also tidied up the fpu code a lot to handle floating point in note handlers.
--- a/sys/src/9/omap/dat.h
+++ b/sys/src/9/omap/dat.h
@@ -1,9 +1,11 @@
typedef struct Conf Conf;
typedef struct Confmem Confmem;
+typedef struct FPalloc FPalloc;
typedef struct FPsave FPsave;
typedef struct Label Label;
typedef struct Lock Lock;
typedef struct Mach Mach;
+typedef struct MFPU MFPU;
typedef struct MMMU MMMU;
typedef struct Page Page;
typedef struct Proc Proc;
@@ -62,17 +64,32 @@
uchar regs[256];
};
+struct FPalloc {+ FPsave;
+ FPalloc *link;
+};
+
struct PFPU {- enum {- FPinit,
- FPactive,
- FPinactive,
+ int fpstate;
+ int kfpstate;
+ FPalloc *fpsave;
+ FPalloc *kfpsave;
+};
- FPillegal = 0x100,
- } fpstate;
- FPsave fpsave[1];
+struct MFPU {+ int fpstate;
+ FPalloc *fpsave;
};
+enum {+ FPinit,
+ FPactive,
+ FPprotected,
+ FPinactive,
+
+ FPnotify = 0x100,
+};
+
#define NCOLOR 1
struct PMMU {Page *mmul2;
@@ -90,6 +107,8 @@
int machno;
uintptr splpc;
Proc *proc;
+
+ MFPU;
MMMU;
PMach;
--- a/sys/src/9/omap/fns.h
+++ b/sys/src/9/omap/fns.h
@@ -47,9 +47,9 @@
void intrenable(int, void (*f)(Ureg *, void*), void *, int, char*);
void intrdisable(int, void (*f)(Ureg *, void*), void *, int, char*);
-void intr(Ureg *);
+int intr(Ureg *);
-void uartinit(void);
+void uartconsinit(void);
void mmuinit(void);
void trapinit(void);
void intrinit(void);
@@ -69,10 +69,18 @@
void l2idcachewbinv(void);
void l2ucachewbinv(void);
-
void fpinit(void);
void fpoff(void);
+void fpon(void);
void fpclear(void);
void fpsave(FPsave *);
void fprestore(FPsave *);
+
+void fpukenter(Ureg *u);
+void fpukexit(Ureg *u);
+void fpuprocfork(Proc *p);
+void fpuprocsave(Proc *p);
+void fpuprocsetup(Proc *p);
+void fpuprocrestore(Proc *p);
+
--- a/sys/src/9/omap/intr.c
+++ b/sys/src/9/omap/intr.c
@@ -145,7 +145,7 @@
coherence();
}
-void
+int
intr(Ureg *ureg)
{Ctlr *ctlr = &ctlrmpu;
@@ -159,13 +159,13 @@
/* interrupt controller reports spurious interrupt flag. */
iprint("cpu%d: spurious interrupt\n", m->machno);csr32w(ctlr, Rcontrol, Cnewirqgen);
- return;
+ return 0;
}
if(n >= nelem(ctlr->intrs)) { iprint("cpu%d: invalid interrupt %d\n", m->machno, n);csr32w(ctlr, Rcontrol, Cnewirqgen);
- return;
+ return 0;
}
/* call all handlers for this interrupt number */
@@ -185,15 +185,8 @@
csr32w(ctlr, Rcontrol, Cnewirqgen);
coherence();
- if(!h) iprint("cpu%d: spurious interrupt %d\n", m->machno, n);- if(up) {- if(n >= IRQTIMER1 && n <= IRQTIMER11) {- if(up->delaysched) {- splhi();
- sched();
- }
- } else {- preempted();
- }
- }
+ if(!h)
+ iprint("cpu%d: spurious interrupt %d\n", m->machno, n);+
+ return n >= IRQTIMER1 && n <= IRQTIMER11;
}
--- a/sys/src/9/omap/l.s
+++ b/sys/src/9/omap/l.s
@@ -141,7 +141,7 @@
/* setup stack in mach */
MOVW $(MACH(0)), R13
- ADD $(MACHSZ), R13
+ ADD $(MACHSIZE), R13
SUB $4, R13
BL main(SB)
@@ -326,6 +326,7 @@
BNE _peekloop
RET
+TEXT fpon(SB), $0
TEXT fpinit(SB), $0
MOVW $FPEXCEN, R0
VMSR(0, FPEXC)
@@ -334,7 +335,6 @@
RET
TEXT fpoff(SB), $0
-TEXT fpclear(SB), $0
MOVW $0, R1
VMSR(1, FPEXC)
RET
--- a/sys/src/9/omap/main.c
+++ b/sys/src/9/omap/main.c
@@ -175,6 +175,7 @@
mmuinit();
plan9iniinit();
confinit();
+ uartconsinit();
printinit();
quotefmtinstall();
fmtinstall(L'H', encodefmt);
@@ -190,7 +191,6 @@
initseg();
links();
- uartinit();
screeninit();
chandevreset();
--- a/sys/src/9/omap/mem.h
+++ b/sys/src/9/omap/mem.h
@@ -24,13 +24,13 @@
#define USTKSIZE (16*MiB)
#define MAXMACH 1
-#define MACHSZ (16*KiB)
#define L1SZ (4*4096)
#define L2SZ (4*256)
#define L1X(va) ((((va)>>20) & 0xfff) << 2)
-#define MACH(n) (KZERO+(n)*MACHSZ)
+#define MACHSIZE (16*KiB)
+#define MACH(n) (KZERO+(n)*MACHSIZE)
#define MACHP(n) ((Mach*)MACH(n))
#define MACHL1(n) (MACH(MAXMACH)+(n)*L1SZ)
#define MACHVEC(n) (MACHL1(MAXMACH)+(n)*64*4)
--- a/sys/src/9/omap/mkfile
+++ b/sys/src/9/omap/mkfile
@@ -49,6 +49,7 @@
timer.$O\
trap.$O\
intr.$O\
+ fpu.$O\
$CONF.root.$O\
$CONF.rootc.$O\
$DEVS\
--- a/sys/src/9/omap/trap.c
+++ b/sys/src/9/omap/trap.c
@@ -4,7 +4,6 @@
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
-#include "../port/systab.h"
#include "tos.h"
#include "ureg.h"
@@ -36,7 +35,7 @@
if(up)
estack = (uintptr)up;
else
- estack = (uintptr)m+MACHSZ;
+ estack = (uintptr)m+MACHSIZE;
x += iprint("estackx %p\n", estack); for(l = (uintptr)&l; l < estack; l += sizeof(uintptr)) {@@ -96,43 +95,25 @@
void
procsetup(Proc *p)
{- p->fpstate = FPinit;
- fpoff();
+ fpuprocsetup(p);
}
void
procsave(Proc *p)
{- if(p->fpstate == FPactive) {- if(p->state == Moribund)
- fpclear();
- else
- fpsave(p->fpsave);
- p->fpstate = FPinactive;
- }
+ fpuprocsave(p);
}
void
-procrestore(Proc *)
+procrestore(Proc *p)
{+ fpuprocrestore(p);
}
void
procfork(Proc *p)
{- ulong s;
-
- s = splhi();
- switch(up->fpstate & ~FPillegal) {- case FPactive:
- fpsave(up->fpsave);
- up->fpstate = FPinactive;
- case FPinactive:
- memmove(p->fpsave, up->fpsave, sizeof(FPsave));
- p->fpstate = FPinactive;
- }
-
- splx(s);
+ fpuprocfork(p);
}
void
@@ -198,133 +179,70 @@
}
}
-int
-notify(Ureg *ureg)
+Ureg *
+notify(Ureg *ureg, char *msg)
{- ulong s, sp;
- char *msg;
+ Ureg *nureg;
+ ulong sp;
- if(up->procctl)
- procctl();
- if(up->nnote == 0)
- return 0;
-
- if(up->fpstate == FPactive) {- fpsave(up->fpsave);
- up->fpstate = FPinactive;
- }
- up->fpstate |= FPillegal;
-
- s = spllo();
- qlock(&up->debug);
- msg = popnote(ureg);
- if(msg == nil) {- qunlock(&up->debug);
- splhi();
- return 0;
- }
-
sp = ureg->sp;
sp -= 256;
sp -= sizeof(Ureg);
- if(!okaddr((uintptr)up->notify, 1, 0)
- || !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
+ if (!okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)
|| ((uintptr) up->notify & 3) != 0
- || (sp & 3) != 0) {- qunlock(&up->debug);
- pprint("suicide: bad address in notify\n");- pexit("Suicide", 0);- }
+ || (sp & 3) != 0)
+ return nil;
- memmove((Ureg*)sp, ureg, sizeof(Ureg));
- *(Ureg**)(sp-BY2WD) = up->ureg;
- up->ureg = (void*)sp;
+ nureg = (Ureg*) sp;
+ memmove(nureg, ureg, sizeof(Ureg));
sp -= BY2WD+ERRMAX;
- memmove((char*)sp, msg, ERRMAX);
+ memmove((char*) sp, msg, ERRMAX);
sp -= 3*BY2WD;
*(uintptr*)(sp+2*BY2WD) = sp+3*BY2WD;
- *(uintptr*)(sp+1*BY2WD) = (uintptr)up->ureg;
- ureg->r0 = (uintptr) up->ureg;
+ *(uintptr*)(sp+1*BY2WD) = (ulong) nureg;
+ ureg->r0 = (uintptr) nureg;
ureg->sp = sp;
ureg->pc = (uintptr) up->notify;
ureg->r14 = 0;
- qunlock(&up->debug);
- splx(s);
- return 1;
+ return nureg;
}
-void
-noted(Ureg *ureg, ulong arg0)
+int
+noted(Ureg *ureg, Ureg *nureg, int arg0)
{- Ureg *nureg;
ulong oureg, sp;
-
- qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified) {- qunlock(&up->debug);
- iprint("called to noted when not notified\n");- pexit("Suicide", 0);- }
-
- up->notified = 0;
- up->fpstate &= ~FPillegal;
- nureg = up->ureg;
+
oureg = (ulong) nureg;
- if(!okaddr(oureg - BY2WD, BY2WD + sizeof(Ureg), 0) || (oureg & 3) != 0) {- qunlock(&up->debug);
- pprint("bad ureg in noted or call to noted when not notifed\n");- pexit("Suicide", 0);- }
+ if ((oureg & 3) != 0)
+ return -1;
- nureg->psr &= PsrMask|PsrDfiq|PsrDirq;
- nureg->psr |= (ureg->psr & ~(PsrMask|PsrDfiq|PsrDirq));
+ setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
- memmove(ureg, nureg, sizeof(Ureg));
switch(arg0) {case NCONT:
case NRSTR:
if(!okaddr(nureg->pc, BY2WD, 0) || (nureg->pc & 3) != 0
- || !okaddr(nureg->sp, BY2WD, 0) || (nureg->sp & 3) != 0) {- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");- pexit("Suicide", 0);- }
+ || !okaddr(nureg->sp, BY2WD, 0) || (nureg->sp & 3) != 0)
+ return -1;
- up->ureg = (Ureg *) (*(ulong*) (oureg - BY2WD));
- qunlock(&up->debug);
break;
case NSAVE:
if(!okaddr(nureg->pc, BY2WD, 0) || (nureg->pc & 3) != 0
- || !okaddr(nureg->sp, BY2WD, 0) || (nureg->sp & 3) != 0) {- qunlock(&up->debug);
- pprint("suicide: trap in noted\n");- pexit("Suicide", 0);- }
+ || !okaddr(nureg->sp, 4*BY2WD, 1) || (nureg->sp & 3) != 0)
+ return -1;
- qunlock(&up->debug);
sp = oureg - 4 * BY2WD - ERRMAX;
- splhi();
ureg->sp = sp;
ureg->r0 = (uintptr) oureg;
((ulong*) sp)[1] = oureg;
((ulong*) sp)[0] = 0;
break;
-
- default:
- up->lastnote->flag = NDebug;
- /* wet floor */
-
- case NDFLT:
- qunlock(&up->debug);
- if(up->lastnote->flag == NDebug)
- pprint("suicide: %s\n", up->lastnote->msg);-
- pexit(up->lastnote->msg, up->lastnote->flag != NDebug);
- break;
}
+
+ return 0;
}
void
@@ -352,11 +270,6 @@
{int s;
- if((up->fpstate & FPillegal) != 0) {- postnote(up, 1, "sys: floating point in note handler", NDebug);
- return;
- }
-
switch(up->fpstate) {case FPinit:
s = splhi();
@@ -440,7 +353,7 @@
case PsrMfiq:
case PsrMirq:
ureg->pc -= 4;
- intr(ureg);
+ preempted(intr(ureg));
break;
case PsrMiabt:
@@ -468,7 +381,7 @@
if((op & 0x0f000000) == 0x0e000000 || (op & 0x0e000000) == 0x0c000000) {cp = op >> 8 & 15;
if(cp == 10 || cp == 11) {- trapfpu();
+ fpukenter(ureg);
break;
}
}
@@ -490,7 +403,7 @@
splhi();
if(user) {if(up->procctl || up->nnote)
- notify(ureg);
+ donotify(ureg);
kexit(ureg);
}
@@ -499,91 +412,16 @@
void
syscall(Ureg *ureg)
{- char *e;
- uintptr sp;
- long ret;
- int i, s;
- ulong scallnr;
- vlong startns, stopns;
-
if(!kenter(ureg))
panic("syscall: from kernel: pc=%#.8lux", ureg->pc);- m->syscall++;
- up->insyscall = 1;
- up->pc = ureg->pc;
-
- scallnr = up->scallnr = ureg->r0;
- sp = ureg->sp;
-
- spllo();
-
- up->nerrlab = 0;
- ret = -1;
- if(!waserror()) {- if(scallnr >= nsyscall) {- pprint("bad sys call number %lux pc %#lux", scallnr, ureg->pc);- postnote(up, 1, "sys: bad sys call", NDebug);
- error(Ebadarg);
- }
-
- if(sp < (USTKTOP-BY2PG) || sp > (USTKTOP-sizeof(Sargs)-BY2WD)) {- validaddr(sp, sizeof(Sargs)+BY2WD, 0);
- evenaddr(sp);
- }
-
- up->s = *((Sargs*)(sp + BY2WD));
- up->psstate = sysctab[scallnr];
- if (up->procctl == Proc_tracesyscall) {- syscallfmt(scallnr, ureg->pc, (va_list)up->s.args);
- s = splhi();
- up->procctl = Proc_stopme;
- procctl();
- splx(s);
- startns = todget(nil);
- }
-
- ret = systab[scallnr]((va_list)up->s.args);
- poperror();
- } else {- e = up->syserrstr;
- up->syserrstr = up->errstr;
- up->errstr = e;
- }
-
- if(up->nerrlab) {- print("bad errstack [%lud]: %d extra\n", scallnr, up->nerrlab);- for (i = 0; i < NERR; i++)
- print("sp=%lux pc=%lux\n", up->errlab[i].sp, up->errlab[i].pc);-
- panic("error stack");- }
-
- ureg->r0 = ret;
- if(up->procctl == Proc_tracesyscall) {- stopns = todget(nil);
- sysretfmt(scallnr, (va_list)up->s.args, ret, startns, stopns);
- s = splhi();
- up->procctl = Proc_stopme;
- procctl();
- splx(s);
- }
-
- up->insyscall = 0;
- up->psstate = 0;
- if(scallnr == NOTED)
- noted(ureg, *((ulong *)up->s.args));
-
- if(scallnr != RFORK && (up->procctl || up->nnote)) {- splhi();
- notify(ureg);
- }
-
+ dosyscall(ureg->r0, (Sargs*)(ureg->sp + BY2WD), &ureg->r0);
+ if(up->procctl || up->nnote)
+ donotify(ureg);
if(up->delaysched)
sched();
kexit(ureg);
- splhi();
}
int
--- a/sys/src/9/omap/uartomap.c
+++ b/sys/src/9/omap/uartomap.c
@@ -107,12 +107,6 @@
return omapuart;
}
-static long
-omapuartstatus(Uart *, void *, long, long)
-{- return 0;
-}
-
static void
omapuartintr(Ureg *, void *arg)
{@@ -261,7 +255,6 @@
.enable = omapuartenable,
.disable = omapuartdisable,
.kick = omapuartkick,
- .status = omapuartstatus,
.getc = omapuartgetc,
.putc = omapuartputc,
@@ -278,29 +271,8 @@
};
void
-uartinit(void)
+uartconsinit(void)
{- Uart *u;
- Ctlr *c;
- char *p, *pe;
- ulong n;
-
- p = getconf("console");- if(p == nil)
- return;
-
- n = strtoul(p, &pe, 0);
- if(pe == p || n > nelem(omapuart))
- return;
-
- u = &omapuart[n];
- c = omapuart[n].regs;
- if(!probeaddr((uintptr)c->io))
- return;
-
- (*u->phys->enable)(u, 0);
-
- consuart = u;
+ consuart = &omapuart[2];
consuart->console = 1;
- uartputs(kmesg.buf, kmesg.n);
}
--
⑨