code: 9ferno

Download patch

ref: f549aaa55c3b8a30ec70028e38a6d63532031e5f
parent: 8107a788ff769af07e522f6972653949b3c13046
author: 9ferno <gophone2015@gmail.com>
date: Wed Jan 19 13: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;