code: 9ferno

Download patch

ref: 5904f303924ad043240d56ee1875a5f8a1916afc
parent: 6b9b01c4efb785704a8a5bff92d11250cb284c11
author: 9ferno <gophone2015@gmail.com>
date: Sat Oct 30 11:23:47 EDT 2021

working rudimentary c ffi

--- a/os/pc64/ff.s
+++ b/os/pc64/ff.s
@@ -1,6 +1,12 @@
 #include "mem.h"
 
 /*
+
+The bigger goal is to replace the dis vm with ff
+ff outputs to screen now.
+But, the input needs to be fixed.
+make this into a devff like device that reads commands and outputs the result.
+
  ff kernel, amd64 9front variant
 
  Register usage:
@@ -7,13 +13,14 @@
 
  TOS: AX top of stack register
  SP:  SP parameter stack pointer, grows towards lower memory (downwards)
- RP:  BP return stack pointer, grows towards higher memory (upwards)
+ RP:  BP (= RARG) return stack pointer, grows towards higher memory (upwards)
  AP:  SI address pointer
  W:   DI work register (holds CFA)
  	BX, CX, DX, R8-R15 temporary registers
 
-Memory map:
+plan9 assembler puts the first argument in BP (RARG), return value in AX.
 
+Memory map:
 Return stack 4096 bytes at FFSTART
 	|
 	|
@@ -43,6 +50,103 @@
  */
 #include "primitives.s"
 
+/*
+plan9 assembler puts the first argument in BP (RARG), return value in AX.
+	For calling a C function with a parameter:
+		Store AX somewhere
+		POPQ AX
+		PUSHA
+		Store ff's SP
+		Restore C's SP
+		POPA	-- this should not be needed as C is caller save
+		MOVQ from somewhere to BP
+		-- call the c function
+	For calling a C function without a parameter:
+		PUSHA
+		Store ff's SP
+		Restore C's SP
+		POPA	-- this should not be needed as C is caller save
+		-- call the c function
+	For coming back from a C function: -- ignoring the return value
+		PUSHA	-- this should not be needed as C is caller save
+		Store C's SP
+		Restore ff's SP
+		POPA
+	ignoring the EFLAGS register, for now
+	not bothering with maintaining the values of the temporary registers
+*/
+#define PUSHALL \
+	PUSHQ	R13; \
+	PUSHQ	R12; \
+	PUSHQ	R11; \
+	PUSHQ	R10; \
+	PUSHQ	R9; \
+	PUSHQ	R8; \
+	PUSHQ	BP; \
+	PUSHQ	DI; \
+	PUSHQ	SI; \
+	PUSHQ	DX; \
+	PUSHQ	CX; \
+	PUSHQ	BX; \
+	PUSHQ	AX;
+#define POPALL \
+	POPQ	AX; \
+	POPQ	BX; \
+	POPQ	CX; \
+	POPQ	DX; \
+	POPQ	SI; \
+	POPQ	DI; \
+	POPQ	BP; \
+	POPQ	R8; \
+	POPQ	R9; \
+	POPQ	R10; \
+	POPQ	R11; \
+	POPQ	R12; \
+	POPQ	R13;
+#define PUSHREGS \
+	PUSHQ	BP; \
+	PUSHQ	DI; \
+	PUSHQ	SI; \
+	PUSHQ	AX;
+#define POPREGS \
+	POPQ	AX; \
+	POPQ	SI; \
+	POPQ	DI; \
+	POPQ	BP; \
+
+#define FF_TO_C_0 \
+	PUSHREGS; \
+	MOVQ SP, ffsp<>(SB); \
+	MOVQ csp<>(SB), SP; \
+	POPREGS;
+
+#define FF_TO_C_1 \
+	MOVQ AX, BX; \
+	POPQ AX; /* drop AX from the parameter stack */ \
+	FF_TO_C_0 \
+	MOVQ BX, BP; /* 1st argument in BP == RARG */
+
+/* ( 1st_parameter 2nd_parameter -- ) */
+#define FF_TO_C_2 /* for calling a c function with 2 parameters */ \
+	MOVQ AX, CX; \
+	POPQ AX; \
+	FF_TO_C_1 \
+	MOVQ CX, 8(SP) \
+
+/* ( 1st_parameter 2nd_parameter 3rd_parameter -- ) */
+#define FF_TO_C_3 /* for calling a c function with 3 parameters */ \
+	MOVQ AX, DX; \
+	POPQ AX; \
+	FF_TO_C_2 \
+	MOVQ DX, 16(SP) \
+
+/* no arguments when calling ff from C, for now */
+#define C_TO_FF \
+	PUSHREGS; \
+	MOVQ SP, csp<>(SB); \
+	MOVQ ffsp<>(SB), SP; \
+	POPREGS;
+
 TEXT	ffmain(SB), 1, $-4		/* _main(SB), 1, $-4 without the libc */
 	/* The last dictionary entry address is stored in dtop.
 	 * The location of dtop is stored in the variable dp.
@@ -50,8 +154,13 @@
 	 * (link + name(1+2) + code field address = 24 bytes) of the dp
 	 * dictionary entry.
 	 */
-	MOVQ $mventry_dp+24(SB), BX	/* BX = dp parameter field address, which has the dtop address */
-	MOVQ (BX), BX	/* BX = *BX = dtop address */
+	PUSHREGS
+	MOVQ SP, csp<>(SB); /* store C stack pointer */
+	MOVQ $FFEND, SP	/* setting up stack */
+	/*
+	 * dtop address is stored in the parameter field address(24-32 bytes) of mventry_dp
+	 */
+	MOVQ mventry_dp+24(SB), BX	/* now, BX = dtop address */
 	MOVQ (BX), AX	/* AX = *BX = $LAST = boot word address (defined last, stored at dtop) */
 				/* if 6a allows multiple symbols per address, then 
 					the above 3 instructions would have been
@@ -69,7 +178,6 @@
 					 * skipping over docol as we do not need to save the SI
 					 * could have done LEAQ 24(AX), SI
 					 */
-	MOVQ $FFEND, SP	/* setting up stack, argc + argv */
 
 /* lodsl could make this simpler. But, this is more comprehensible
 	why not JMP* (DI)?
@@ -81,6 +189,12 @@
 
 	NEXT
 
+TEXT	ffprint(SB), 1, $-4
+	FF_TO_C_2
+	CALL screenput(SB)
+	C_TO_FF
+	NEXT
+
 TEXT	reset(SB), 1, $-4
 	MOVQ $FFSTART, BP
 	NEXT
@@ -95,6 +209,11 @@
 	LEAQ 8(DI), SI
 	NEXT
 
+TEXT	exitcolon(SB), 1, $-4
+	SUBQ $8, BP
+	MOVQ (BP), SI
+	NEXT
+
 TEXT	dodoes(SB), 1, $-4	/* ( -- a ) */
 	MOVQ SI,(BP)
 	ADDQ $8,BP
@@ -124,7 +243,6 @@
 	MOVQ (AX), AX
 	NEXT
 
-/* shouldn't it be (a n -- )? */
 TEXT	store(SB), 1, $-4	/* ( n a -- ) */
 	POPQ (AX)
 	POPQ AX
@@ -346,11 +464,6 @@
 	ANDQ $~7, SI
 	NEXT
 
-TEXT	exitcolon(SB), 1, $-4
-	SUBQ $8, BP
-	MOVQ (BP), SI
-	NEXT  
-
 /* puts the top 2 entries of the data stack in the return stack */
 TEXT	doinit(SB), 1, $-4	/* ( hi lo -- ) */
 	MOVQ AX, (BP)
@@ -613,5 +726,8 @@
 GLOBL	htop(SB), $8
 DATA	heapend(SB)/8, $0
 GLOBL	heapend(SB), $8
+
+GLOBL	ffsp<>(SB), $8
+GLOBL	csp<>(SB), $8
 
 	END
--- a/os/pc64/main.c
+++ b/os/pc64/main.c
@@ -26,6 +26,9 @@
 char bootdisk[KNAMELEN];
 
 extern void ffmain(void);	/* forth interpreter */
+extern intptr mventry_dp;
+extern intptr mc_dp;
+extern intptr dtop;
 /* until I sort out the mp initialization issue */
 extern void startaps(void);
 
@@ -82,7 +85,32 @@
 	nchars += msglen;
 }
 
+/* used by ff */
 void
+show_ff_return_stack(void)
+{
+	intptr* i;
+
+	for(i = (intptr*)0x112000; i<(intptr*)0x112020; i++){
+		print("0x%p: 0x%zx\n", i, *i);
+	}
+}
+
+void
+screenput(char *msg, int msglen)
+{
+	show_ff_return_stack();
+	print("msg %c, msglen %d\n", *msg, msglen);
+	if(screenputs != nil)
+		screenputs(msg, 1);
+	else
+		writemsg(msg, msglen);
+	print("\nscreenput exiting\n");
+	show_ff_return_stack();
+	print("\n");
+}
+
+void
 ptedebug(uintptr pa, char *desc)
 {
 	uintptr *pml4e, *pdpe, *pde;
@@ -113,7 +141,7 @@
 		"\tkdzero 0x%p confaddr 0x%p apbootstrap 0x%p idtaddr 0x%p\n"
 		"\tcpu0mach 0x%p cpu0sp 0x%p cpu0gdt 0x%p\n"
 		"\tcpu0pml4 0x%p cpu0pdp 0x%p  cpu0pd 0x%p\n"
-		"\tcpu0end 0x%p\n",
+		"\tcpu0end 0x%p\n"
 		"\tetext 0x%p edata 0x%p end 0x%p\n",
 		(void*)KDZERO, CONFADDR,APBOOTSTRAP,
 		IDTADDR, CPU0MACH, CPU0SP, GDTADDR,
@@ -252,7 +280,7 @@
 init0(void)
 {
 	Osenv *o;
-	char buf[2*KNAMELEN];
+	/*char buf[2*KNAMELEN];*/
 
 	up->nerrlab = 0;
 
--- a/os/pc64/primitives-nasm.s
+++ b/os/pc64/primitives-nasm.s
@@ -63,3 +63,4 @@
   MVENTRY "_end", textend, ffend, 4
   MENTRY "cas", cas, 3
   MENTRY "(deferred)", deferred, 10
+  MENTRY "ffprint", ffprint, 7
--- a/os/pc64/trap.c
+++ b/os/pc64/trap.c
@@ -253,7 +253,7 @@
 	print("  CS %4.4zux  DS %4.4ux  ES %4.4ux  FS %4.4ux  GS %4.4ux\n",
 		ureg->cs & 0xFFFF, ureg->ds & 0xFFFF, ureg->es & 0xFFFF,
 		ureg->fs & 0xFFFF, ureg->gs & 0xFFFF);
-	print("  R8 %4.4zux  R9 %4.4ux  R10 %4.4ux  R11 %4.4ux  R12 %4.4ux\n",
+	print("  R8 %4.4zux  R9 %4.4zzux  R10 %4.4zux  R11 %4.4zux  R12 %4.4zux\n",
 		ureg->r8, ureg->r9, ureg->r10, ureg->r11, ureg->r12);
 }
 
@@ -262,6 +262,7 @@
 {
 	extern ulong etext;
 	vlong mca, mct;
+	intptr *i;
 
 	dumpregs2(ureg);
 
@@ -282,7 +283,15 @@
 			print("\n  MCA %8.8zux MCT %8.8zux", mca, mct);
 		}
 	}
-	print("\n  ur %lux up %lux\n", ureg, up);
+	print("\n  ur %lux up %lux ureg->bp & ~0xFFF %zx\n", ureg, up, ureg->bp & ~0xFFF);
+	if((ureg->bp & ~0xFFF) == FFSTART){
+		for(i = (intptr*)FFSTART; i<=(intptr*)ureg->bp; i++){
+			print("0x%p: 0x%zx\n", i, *i);
+		}
+		for(i = (intptr*)FFEND; i>=(intptr*)ureg->sp; i--){
+			print("0x%p: 0x%zx\n", i, *i);
+		}
+	}
 }
 
 /*
--- a/os/pc64/words-nasm.s
+++ b/os/pc64/words-nasm.s
@@ -264,6 +264,7 @@
  VENTRY `stdin`, v_stdin, 5
  VENTRY `stdout`, v_stdout, 6
  VENTRY `eof`, v_eof, 3
+
  CENTRY `key`, c_key, 3
  dd v_iobuf		; variable iobuf
  dd m_literal
@@ -285,23 +286,20 @@
  dd m_cfetch
 L79:
  dd m_exitcolon
- CENTRY `emit`, c_emit, 4	; ( character -- ) TODO correct the below stack notations
- dd v_iobuf			; variable iobuf
+
+ CENTRY `emit`, c_emit, 4	; ( character -- )
+ dd v_iobuf			; variable iobuf address
  dd m_cstore		; variable iobuf has character
- dd v_iobuf			; variable iobuf
+ dd v_iobuf			; variable iobuf address
  dd m_literal
- dd 1			; ( iobuf 1 -- )
- dd v_stdout			; variable stdout
- dd m_fetch		; ( iobuf 1 1 -- )
- dd m_fswrite		; ( -- ) writes out the character
- dd m_drop		; the return value of fswrite
+ dd 1				; ( iobuf 1 -- )
+ dd m_ffprint		; calls c screenput()
  dd m_exitcolon
+
  CENTRY `type`, c_type, 4	; ( addr n -- ) 
- dd v_stdout			; variable stdout, normally 1
- dd m_fetch		; ( addr n 1 -- )
- dd m_fswrite
- dd m_drop
+ dd m_ffprint
  dd m_exitcolon
+
  CENTRY `cr`, c_cr, 2
  dd m_literal
  dd 10			; ascii value of carriage return
@@ -909,6 +907,7 @@
  dd m_rpop
  dd c_parse
  dd m_exitcolon
+
  CENTRY `accept`, c_accept, 6	; ( a n -- ) TODO correct below stack notations
  dd m_xswap	; ( n a -- )
  dd m_dup	; ( n a a -- )
@@ -949,6 +948,7 @@
  dd m_rpop	; ( a a -- )
  dd m_minus	; ( 0 -- )
  dd m_exitcolon
+
  CENTRY `query`, c_query, 5
  dd v_eof	; variable eof
  dd c_off	; off sets variable eof = 0
@@ -974,6 +974,7 @@
  dd c_off
 L153:
  dd m_exitcolon
+
  CENTRY `refill`, c_refill, 6
  dd v_blk
  dd m_fetch
@@ -1699,6 +1700,7 @@
  dd c_cr
  dd c_abort
  dd m_exitcolon
+
  CENTRY `quit`, c_quit, 4 ; TODO correct below stack notations
  dd m_reset ; initialize return stack
  dd m_clear	; SP = sstack_end, initialize data stack
@@ -1720,6 +1722,7 @@
  dd m_jump
  dd L253
  dd m_exitcolon
+
  CENTRY `(abort)`, c_parenabort, 7 ; TODO correct below stack notations
  dd v_state	; ( v_state -- )
  dd c_off		; off sets variable state = 0
@@ -1736,6 +1739,7 @@
  dd m_store	; variable stdout = 1
  dd c_quit	; quit resets return stack and data stack
  dd m_exitcolon
+
  CENTRY `oldboot`, c_oldboot, 7 ; TODO correct below stack notations
  dd m_reset
  dd m_clear	; SP = sstack_end
--- a/os/port/proc.c
+++ b/os/port/proc.c
@@ -396,8 +396,8 @@
 /*	if(p->pid != prevpid){
 		prevpid = p->pid;
 		if(p->type == Interp && p->iprog != nil){
-			print(" %d:%s,%d ",
-				p->pid, p->text, ((Prog*)p->iprog)->pid);
+			print(" %d:%s,%d %s ",
+				p->pid, p->text, ((Prog*)p->iprog)->pid, ((Prog*)p->iprog)->R.M->m->path);
 		}else
 			print(" %d:%s", p->pid, p->text);
 	}else