shithub: nix

Download patch

ref: 7a4f034db548fd023698c091f81905bbe22ea96b
parent: 43734e8f98a5dbe7fd4fe1cca795855e8d74096b
author: glenda <glenda@cirno>
date: Wed May 8 17:38:55 EDT 2024

closer to user mode, but the lidt is wrong somehow.

--- a/sys/src/nix/pc64/acore.c
+++ b/sys/src/nix/pc64/acore.c
@@ -113,9 +113,16 @@
 void
 acsched(int i, NIX *nix)
 {
+	void nixidt(uintptr*);
+	uintptr oldidt[2];
+#define OK 1
+	if (OK)
+	nixidt(oldidt);
+
 	int core = m->machno;
 	acmmuswitch();
 	nix->icc->fn = nil;
+
 	print("acsched %d times on core %d\n", i, core);
 	for(;i;i--){
 		acstackok();
@@ -130,18 +137,20 @@
 		mfence();
 		nix->icc->fn = nil;
 	}
+	if (OK)
+	lidt(oldidt);
 	print("acsched: all done on core %d\n", core);
 }
 
 void
-actrap(Ureg *u)
+actrap(Ureg *)
 {
-	panic("actrap");
+	print("actrap");
 }
 void
 acsyscall(void)
 {
-	panic("acsyscall");
+	print("acsyscall");
 }
 #ifdef _NOTNOW__
 /*
--- a/sys/src/nix/pc64/devnix.c
+++ b/sys/src/nix/pc64/devnix.c
@@ -43,11 +43,62 @@
 } nixes[MAXMACH];
 
 int nnix = 0;
+static Segdesc *acidt;
 
+void nixidt(uintptr *p)
+{
+	uintptr ptr[2];
+	uvlong *gidt(uintptr *);
+	gidt(p);
+	print("gidt returns %#p %#p\n", p[0], p[1]);
+	print("oldidt: %#p\n", p);
+	((ushort*)&ptr[1])[-1] = sizeof(Segdesc)*512-1;
+	ptr[1] = (uintptr)acidt;
+	print("lidt %#p %#p\n", ptr[0], ptr[1]);
+	print("lidt with %#p\n", &((ushort*)&ptr[1])[-1]);
+	if (0)
+	lidt(&((ushort*)&ptr[1])[-1]);
+}
+
 static void
 nixreset(void)
 {
 	DEVNIX *nix;
+	u32int d1, v;
+	uintptr vaddr;
+	extern char acidthandlers[];
+
+	acidt = (Segdesc*)mallocalign(4096,4096,0, 0);
+	print("acidt %#p\n", acidt);
+	//acidt =  (Segdesc*)REBOOTADDR;print("acidt %#p\n", acidt);
+	vaddr = (uintptr)acidthandlers;
+
+	for(v = 0; v < 256; v++){
+		d1 = (vaddr & 0xFFFF0000)|SEGP;
+		switch(v){
+		case VectorBPT:
+			d1 |= SEGPL(3)|SEGIG;
+			break;
+
+		case VectorSYSCALL:
+			d1 |= SEGPL(3)|SEGIG;
+			break;
+
+		default:
+			d1 |= SEGPL(0)|SEGIG;
+			break;
+		}
+
+		acidt->d0 = (vaddr & 0xFFFF)|(KESEL<<16);
+		acidt->d1 = d1;
+		acidt++;
+
+		acidt->d0 = (vaddr >> 32);
+		acidt->d1 = 0;
+		acidt++;
+
+		vaddr += 6;
+	}
 
 	for(nnix = 0; nnix < MAXMACH; nnix++){
 		nix = &nixes[nnix];
--- a/sys/src/nix/pc64/l64acidt.s
+++ b/sys/src/nix/pc64/l64acidt.s
@@ -83,6 +83,12 @@
 	ADDQ	$40, SP
 	IRETQ
 
+TEXT gidt(SB), $0				/* IDTR - interrupt descriptor table */
+	MOVQ	RARG, AX
+	MOVL	IDTR, (AX)
+	RET
+
+
 TEXT acidthandlers(SB), 1, $-4
 	CALL _acintrp<>(SB); BYTE $IdtDE		/* #DE Divide-by-Zero Error */
 	CALL _acintrp<>(SB); BYTE $IdtDB		/* #DB Debug */