ref: f549aaa55c3b8a30ec70028e38a6d63532031e5f
parent: 8107a788ff769af07e522f6972653949b3c13046
author: 9ferno <gophone2015@gmail.com>
date: Wed Jan 19 20:54:01 EST 2022
forth process terminates when the stdin is closed
--- a/Inferno/amd64/include/ureg.h
+++ b/Inferno/amd64/include/ureg.h
@@ -20,14 +20,14 @@
u16 fs;
u16 gs;
- u64 trap; /* trap type */
- u64 ecode; /* error code (or zero) */
- u64 pc; /* pc */
- u64 cs; /* old context */
- u64 flags; /* old flags */
- union { /* sp */
+ u64 trap; /* trap type */
+ u64 ecode; /* error code (or zero) */
+ u64 pc; /* pc */
+ u64 cs; /* old context */
+ u64 flags; /* old flags */
+ union { /* sp */
u64 usp;
u64 sp;
};
- u64 ss; /* old stack segment */
+ u64 ss; /* old stack segment */
};
--- a/os/pc64/bindings.s
+++ b/os/pc64/bindings.s
@@ -118,6 +118,7 @@
* if fd == 0 and read return value == 0 == End of file, terminate
*/
TEXT fsread(SB), 1, $40 /* ( n a fd -- n2 ) */
+
PUSH(TOP)
MOVQ 16(PSP), TOP
MOVQ 8(PSP), CX
@@ -141,32 +142,10 @@
MOVQ 32(SP), CX /* read return value == 0, check if fd is stdin */
TESTQ CX, CX
JNZ fsread_continue
+
/* and fd == 0, terminate */
ADDQ $40, SP
- /* TODO
- * this should have been JMP terminate(SB), but it is raising a #GP error.
- * CALL terminate(SB) works fine.
- * Would have to dig through the amd64 manuals and
- * https://www.felixcloutier.com/x86/jmp to figure out why.
- * until then, use the label to jump to
-
-JMP to a label: JMP _fthterminate
-2011b8 4883c428 (644) ADDQ $40,SP
-2011bc e9d0fcffff (493) JMP ,200e91
-2011c1 4883c428 (656) ADDQ $40,SP
-
-JMP to symbol: JMP terminate(SB)
-2011b8 4883c428 (645) ADDQ $40,SP
-2011bc ff2425910e2000 (654) JMP ,terminate+0(SB)
-2011c3 4883c428 (657) ADDQ $40,SP
-
-CALL to symbol: CALL terminate(SB)
-2011b8 4883c428 (645) ADDQ $40,SP
-2011bc e8d0fcffff (655) CALL ,200e91+terminate
-2011c1 4883c428 (657) ADDQ $40,SP
- */
JMP _fthterminate
- /* TODO fix this JMP terminate(SB) */
fsread_continue:
ADDQ $40, SP
--- a/os/pc64/forth.s
+++ b/os/pc64/forth.s
@@ -251,7 +251,6 @@
TEXT fthdump(SB), 1, $8 /* ( n -- ) */
INT $0
- CALL dumpstack(SB)
RET
#include "bindings.s"
--- a/os/pc64/l.s
+++ b/os/pc64/l.s
@@ -953,42 +953,52 @@
MOVQ 8(SP), AX /* return value */
- MOVQ (15*8)(SP), RMACH /* r15 */
- MOVQ (14*8)(SP), RUSER /* r14 */
+ MOVQ (15*8)(SP), RMACH /* r15 */
+ MOVQ (14*8)(SP), RUSER /* r14 */
- MOVQ (19*8)(SP), CX /* ip */
- MOVQ (21*8)(SP), R11 /* flags */
- MOVQ (22*8)(SP), SP /* sp */
+ MOVQ (19*8)(SP), CX /* ip */
+ MOVQ (21*8)(SP), R11 /* flags */
+ MOVQ (22*8)(SP), SP /* sp */
BYTE $0x48; SYSRET /* SYSRETQ */
/*
* Interrupt/exception handling.
+ * Each entry in the vector table calls either _strayintr or _strayintrx depending
+ * on whether an error code has been automatically pushed onto the stack
+ * (_strayintrx) or not, in which case a dummy entry must be pushed before retrieving
+ * the trap type from the vector table entry and placing it on the stack as part
+ * of the Ureg structure.
+ * The size of each entry in the vector table (6 bytes) is known in trapinit0().
+ * Volume 3A 6-14
+ * Stack is (high -> low)
+ * SS, RSP, RFLAGS, CS, RIP, Error Code (if any), Vectortable(SB) return PC
+ * (SP) = Vectortable(SB) return PC. The first byte of this return PC will be the
+ * byte we used to identify the trap type.
+ * Removed the nested check that 9front does as we are not using different code
+ * segments or tasks.
*/
-TEXT _strayintr(SB), 1, $-4 /* no error code pushed */
- PUSHQ AX /* save AX */
- MOVQ 8(SP), AX /* vectortable(SB) PC */
+TEXT _strayintr(SB), 1, $-4 /* no error code pushed */
+ PUSHQ AX /* save AX, some junk to fill the ecode slot in the stack */
+ MOVQ 8(SP), AX /* vectortable(SB) PC */
JMP _intrcommon
-TEXT _strayintrx(SB), 1, $-4 /* error code pushed */
- XCHGQ AX, (SP)
+TEXT _strayintrx(SB), 1, $-4/* error code pushed */
+ XCHGQ AX, (SP) /* exchange AX with pointer to trap type */
_intrcommon:
- MOVBQZX (AX), AX
- XCHGQ AX, (SP)
+ MOVBQZX (AX), AX /* extract trap type from the vectortable(SB) return PC -> AX */
+ XCHGQ AX, (SP) /* exchange vectortable(SB) return PC with the trap type in AX */
- SUBQ $24, SP /* R1[45], [DEFG]S */
- CMPW 48(SP), $KESEL /* old CS */
- JEQ _intrnested
+ PUSHW GS
+ PUSHW FS
+ MOVW ES, AX /* PUSHW ES is invalid in amd64, but showing the value for debugging */
+ PUSHW AX
+ MOVW DS, AX /* PUSHW DS is invalid in amd64, but showing the value as JMP uses it */
+ PUSHW AX
- MOVQ RUSER, 0(SP)
- MOVQ RMACH, 8(SP)
-
- SWAPGS
- BYTE $0x65; MOVQ 0, RMACH /* m-> (MOVQ GS:0x0, R15) */
- MOVQ 16(RMACH), RUSER /* up */
-
-_intrnested:
+ PUSHQ R15 /* RMACH m-> */
+ PUSHQ R14 /* RUSER up-> */
PUSHQ R13
PUSHQ R12
PUSHQ R11
@@ -1003,15 +1013,15 @@
PUSHQ BX
PUSHQ AX
- MOVQ SP, RARG
+ MOVQ SP, RARG /* Ureg* argument to trap */
PUSHQ SP
CALL trap(SB)
TEXT _intrr(SB), 1, $-4
_intrestore:
- POPQ AX
+ POPQ AX /* ignore the SP pushed before the call to trap() */
- POPQ AX
+ POPQ AX /* restore registers */
POPQ BX
POPQ CX
POPQ DX
@@ -1024,17 +1034,12 @@
POPQ R11
POPQ R12
POPQ R13
+ POPQ R14 /* RUSER up-> */
+ POPQ R15 /* RMACH m-> */
- CMPQ 48(SP), $KESEL
- JEQ _iretnested
+ ADDQ $8, SP /* to ignore the [DEFG]S registers as they should not be changing */
- SWAPGS
-
- MOVQ 8(SP), RMACH
- MOVQ 0(SP), RUSER
-
-_iretnested:
- ADDQ $40, SP
+ ADDQ $16, SP /* pop error code and trap type */
IRETQ
TEXT noteret(SB), 1, $-4
--- a/os/pc64/mmu.c
+++ b/os/pc64/mmu.c
@@ -122,6 +122,13 @@
m->gdt[TSSSEG+1].d0 = x>>32;
m->gdt[TSSSEG+1].d1 = 0;
+ if(0){
+ print("GDT: m 0x%p m+MACHSIZE 0x%p\n", m, (uintptr)m+MACHSIZE);
+ for(i=0; i<NGDT; i++){
+ print(" i %d d0 0x%ux d1 0x%ux\n", i, m->gdt[i].d0, m->gdt[i].d1);
+ }
+ }
+
loadptr(sizeof(gdt)-1, (uintptr)m->gdt, lgdt);
loadptr(sizeof(Segdesc)*512-1, (uintptr)IDTADDR, lidt);
taskswitch((uintptr)m + MACHSIZE);
--- a/os/pc64/trap.c
+++ b/os/pc64/trap.c
@@ -19,6 +19,7 @@
static void doublefault(Ureg*, void*);
static void unexpected(Ureg*, void*);
static void _dumpstack(Ureg*);
+static void dumpureg(Ureg* ureg);
void
trapinit0(void)
@@ -264,6 +265,7 @@
m->machno, ureg->pc);
}
}
+ dumpureg(ureg);
dumpregs(ureg);
if(vno < nelem(excname)){
dumprstack(ureg->r11, ureg->r8, ureg->r12);
@@ -346,7 +348,37 @@
}
}
}
+/* displays in the order pushed into the stack */
+void
+dumpureg(Ureg* ureg)
+{
+ if(up)
+ print("cpu%d: registers for %s %ud\n",
+ m->machno, up->text, up->pid);
+ else
+ print("cpu%d: registers for kernel\n", m->machno);
+ print("SS %4.4zuX SP %zux\n", ureg->ss & 0xFFFF, ureg->usp);
+ print(" FLAGS %zux CS %zux PC %zux ECODE %zux TRAP %zux\n",
+ ureg->flags, ureg->cs, ureg->pc, ureg->ecode, ureg->trap);
+ print(" GS %4.4zux FS %4.4ux ES %4.4ux DS %4.4ux\n",
+ ureg->gs & 0xFFFF, ureg->fs & 0xFFFF, ureg->es & 0xFFFF,
+ ureg->ds & 0xFFFF);
+
+ print(" R15 m %8.8zux R14 up %8.8zux R13 %8.8zux\n",
+ ureg->r15, ureg->r14, ureg->r13);
+ print(" R12 UPE %8.8zux R11 UP %8.8zzux R10 W %8.8zux\n"
+ " R9 IP %8.8zux R8 RSP %8.8zux\n",
+ ureg->r12, ureg->r11, ureg->r10,
+ ureg->r9, ureg->r8);
+ print(" BP RARG %8.8zux DI %8.8zzux SI %8.8zux\n"
+ " DX PSP %8.8zux CX %8.8zux BX TOP %8.8zux\n"
+ " AX %8.8zux\n",
+ ureg->bp, ureg->di, ureg->si,
+ ureg->dx, ureg->cx, ureg->bx,
+ ureg->ax);
+}
+
/*
* Fill in enough of Ureg to get a stack trace, and call a function.
* Used by debugging interface rdb.
@@ -367,7 +399,7 @@
extern uintptr etext;
int onlypc = 0;
- print("ktrace /kernel/path pc 0x%zux sp 0x%zux &l 0x%zux\n", ureg->pc, ureg->sp, &l);
+ print("ktrace /kernel/path pc 0x%zux sp 0x%zux &l 0x%zux up 0x%p\n", ureg->pc, ureg->sp, &l, up);
i = 0;
if(up &&
(uintptr)&l >= (uintptr)up->kstack &&
--- a/os/port/devforth.c
+++ b/os/port/devforth.c
@@ -72,6 +72,7 @@
int nforthprocs = 0;
Proc *fhead, *ftail;
static QLock forthlock;
+static char forthname[] = "forth";
static void
flock(void)
@@ -336,11 +337,13 @@
up->pid, (intptr)fmem, ((intptr*)fmem)[1], (intptr)fmem+RSTACK);
DBG("fentries[0].name %s\n", fentries[0].hdr.name);
DBG("fentries[1].name %s nfentries %d\n", fentries[1].hdr.name, nelem(fentries));
+ DBG("up->kstack 0x%p\n", up->kstack);
if(waserror()){
print("forthentry error: %r\n");
- poperror();
+ nexterror();
}else
forthmain((u8*)fmem);
+ poperror();
free(fmem);
flock();
@@ -494,7 +497,7 @@
/* this does all of the above 3 lines */
kprocchild(p, forthentry, p->fmem);
- strcpy(p->text, "forth");
+ p->text = forthname;
memset(p->time, 0, sizeof(p->time));
p->time[TReal] = MACHP(0)->ticks;