code wiki / _hdl_build / nx_emu_x86_modes_test.nx
nx_emu_x86_modes_test.nx source
↩ module page · 98 lines · 7122 B
1// nx_emu_x86_modes_test.nx -- x86 full-system ladder R5 rung-2: MODE MACHINERY IN EXECUTION.
2// emu_x86_run_m = the R1-R4 decode + control registers CR0/CR3/EFER + the mode-transition
3// instructions: 0F 22 (mov crX, r64) and 0F 30 (wrmsr -> EFER, simplified to EFER; full ecx-dispatch
4// is a refinement). The emu tracks the LIVE cpu mode (real/protected/long) via the R5-1 rule and
5// exposes the final CR/mode state. KAT: PE -> protected, then EFER.LME + CR0.PG -> LONG.
6// HONEST SCOPE: still 64-bit-encoded driver code; emulating the actual 16/32-bit REAL-MODE boot
7// entry that issues these = R5 rung-3. No hardware writes (Rule 26). expect_exit: 0 license_tier: ORIGINAL
8import "nx_emu_x86_k.nx"
9
10func md_b(c: *u8, o: i64, b: i64) -> i64 { c[o]=(b & 0xff) as u8; return o+1 }
11func md_i32(c: *u8, o: i64, v: i64) -> i64 { c[o]=(v&0xff) as u8; c[o+1]=((v>>8)&0xff) as u8; c[o+2]=((v>>16)&0xff) as u8; c[o+3]=((v>>24)&0xff) as u8; return o+4 }
12func md_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
13func md_num(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
14
15func md_mode(pe: i64, pg: i64, lme: i64) -> i64 { if pe==0 { return 0 } if pg==1 { if lme==1 { return 2 } } return 1 }
16
17// mode-aware interpreter; writes st[0]=CR0 st[1]=EFER st[2]=CR3 st[3]=mode at exit.
18func emu_x86_run_m(code: *u8, len: i64, mem: *u8, st: *i64) -> i64 {
19 let reg: *i64 = sys_mmap(8 * 16) as *i64
20 var pc: i64 = 0
21 var zf: i64 = 0
22 var sf: i64 = 0
23 var cr0: i64 = 0
24 var efer: i64 = 0
25 var cr3: i64 = 0
26 while pc < len {
27 let b: i64 = code[pc] as i64
28 var h: i64 = 0
29 if b == 0x0F {
30 let b1: i64 = code[pc+1] as i64
31 if b1 == 0x05 {
32 if reg[0] == 60 { let pe: i64=cr0&1; let pg: i64=(cr0>>31)&1; let lme: i64=(efer>>8)&1; st[0]=cr0; st[1]=efer; st[2]=cr3; st[3]=md_mode(pe,pg,lme); return reg[7] & 0xff }
33 if reg[0] == 1 { sys_write(reg[7], ((code as i64) + reg[6]) as *u8, reg[2]) }
34 pc = pc + 2; h = 1
35 }
36 if h == 0 { if b1 == 0x22 { let m: i64=code[pc+2] as i64; let cri: i64=(m>>3)&7; if cri==0 { cr0=reg[m&7] } if cri==3 { cr3=reg[m&7] } pc = pc + 3; h = 1 } }
37 if h == 0 { if b1 == 0x30 { efer = reg[0]; pc = pc + 2; h = 1 } }
38 if h == 0 { return 0 - 1 }
39 }
40 if h == 0 { if b == 0xEB { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } pc = pc + 2 + r; h = 1 } }
41 if h == 0 { if b == 0x74 { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } if zf==1 { pc=pc+2+r } else { pc=pc+2 } h = 1 } }
42 if h == 0 { if b == 0x75 { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } if zf==0 { pc=pc+2+r } else { pc=pc+2 } h = 1 } }
43 if h == 0 { if b == 0xE8 { let rel: i64=k_i32(code, pc+1); reg[4]=reg[4]-8; k_st64(mem, reg[4], pc+5); pc=pc+5+rel; h = 1 } }
44 if h == 0 { if b == 0xC3 { pc = k_ld64(mem, reg[4]); reg[4]=reg[4]+8; h = 1 } }
45 if h == 0 { if b >= 0x50 { if b <= 0x57 { reg[4]=reg[4]-8; k_st64(mem, reg[4], reg[b-0x50]); pc=pc+1; h = 1 } } }
46 if h == 0 { if b >= 0x58 { if b <= 0x5F { reg[b-0x58]=k_ld64(mem, reg[4]); reg[4]=reg[4]+8; pc=pc+1; h = 1 } } }
47 if h == 0 { if b == 0x48 {
48 let op: i64 = code[pc+1] as i64
49 if op == 0xC7 { reg[(code[pc+2] as i64) & 7] = k_i32(code, pc+3); pc = pc + 7; h = 1 }
50 if op == 0x89 { let m: i64=code[pc+2] as i64; let md: i64=(m>>6)&3; if md==3 { reg[m & 7] = reg[(m>>3) & 7] } else { k_st64(mem, reg[m & 7], reg[(m>>3) & 7]) } pc = pc + 3; h = 1 }
51 if op == 0x8B { let m: i64=code[pc+2] as i64; let md: i64=(m>>6)&3; if md==3 { reg[(m>>3) & 7] = reg[m & 7] } else { reg[(m>>3) & 7] = k_ld64(mem, reg[m & 7]) } pc = pc + 3; h = 1 }
52 if op == 0xC1 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] << (code[pc+3] as i64); pc = pc + 4; h = 1 }
53 if op == 0x01 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] + reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
54 if op == 0x29 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] - reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
55 if op == 0x39 { let m: i64=code[pc+2] as i64; let t: i64 = reg[m & 7] - reg[(m>>3) & 7]; if t==0 { zf=1 } else { zf=0 } if t<0 { sf=1 } else { sf=0 } pc = pc + 3; h = 1 }
56 } }
57 if h == 0 { return 0 - 3 }
58 }
59 return 0 - 4
60}
61
62func main() -> i64 {
63 md_puts("x86 full-system ladder R5 rung-2: MODE MACHINERY (CR0/EFER + mov-cr0/wrmsr; reach LONG)\n" as *u8)
64 let c: *u8 = sys_mmap(256)
65 let mem: *u8 = sys_mmap(65536)
66 var o: i64 = 0
67 // mov rax,1 ; mov cr0,rax (enter PROTECTED)
68 o=md_b(c,o,0x48); o=md_b(c,o,0xC7); o=md_b(c,o,0xC0); o=md_i32(c,o,1)
69 o=md_b(c,o,0x0F); o=md_b(c,o,0x22); o=md_b(c,o,0xC0)
70 // mov rax,256 ; wrmsr (EFER.LME=1)
71 o=md_b(c,o,0x48); o=md_b(c,o,0xC7); o=md_b(c,o,0xC0); o=md_i32(c,o,256)
72 o=md_b(c,o,0x0F); o=md_b(c,o,0x30)
73 // mov rax,1 ; mov rdx,1 ; shl rdx,31 ; add rax,rdx ; mov cr0,rax (CR0 = PE|PG -> LONG)
74 o=md_b(c,o,0x48); o=md_b(c,o,0xC7); o=md_b(c,o,0xC0); o=md_i32(c,o,1)
75 o=md_b(c,o,0x48); o=md_b(c,o,0xC7); o=md_b(c,o,0xC2); o=md_i32(c,o,1)
76 o=md_b(c,o,0x48); o=md_b(c,o,0xC1); o=md_b(c,o,0xE2); o=md_b(c,o,31)
77 o=md_b(c,o,0x48); o=md_b(c,o,0x01); o=md_b(c,o,0xD0)
78 o=md_b(c,o,0x0F); o=md_b(c,o,0x22); o=md_b(c,o,0xC0)
79 // mov rdi,0 ; mov rax,60 ; syscall
80 o=md_b(c,o,0x48); o=md_b(c,o,0xC7); o=md_b(c,o,0xC7); o=md_i32(c,o,0)
81 o=md_b(c,o,0x48); o=md_b(c,o,0xC7); o=md_b(c,o,0xC0); o=md_i32(c,o,60)
82 o=md_b(c,o,0x0F); o=md_b(c,o,0x05)
83
84 let st: *i64 = sys_mmap(8*8) as *i64
85 let rc: i64 = emu_x86_run_m(c, o, mem, st)
86 md_puts(" after transition: CR0=" as *u8); md_num(st[0]); md_puts(" EFER=" as *u8); md_num(st[1]); md_puts(" mode=" as *u8); md_num(st[3]); md_puts(" (0=real 1=protected 2=long)\n" as *u8)
87
88 var pass: i64=0
89 var ttl: i64=0
90 ttl=ttl+1; md_puts(" T1 clean exit: " as *u8); if rc==0 { pass=pass+1; md_puts("PASS\n" as *u8) } else { md_puts("FAIL\n" as *u8) }
91 ttl=ttl+1; md_puts(" T2 reached LONG mode: " as *u8); if st[3]==2 { pass=pass+1; md_puts("PASS\n" as *u8) } else { md_puts("FAIL\n" as *u8) }
92 ttl=ttl+1; md_puts(" T3 CR0 has PE+PG: " as *u8); if (st[0]&1)==1 { if ((st[0]>>31)&1)==1 { pass=pass+1; md_puts("PASS\n" as *u8) } else { md_puts("FAIL\n" as *u8) } } else { md_puts("FAIL\n" as *u8) }
93 ttl=ttl+1; md_puts(" T4 EFER.LME set: " as *u8); if ((st[1]>>8)&1)==1 { pass=pass+1; md_puts("PASS\n" as *u8) } else { md_puts("FAIL\n" as *u8) }
94
95 md_puts("X86-MODES-GATE passed " as *u8); md_num(pass); md_puts("/" as *u8); md_num(ttl)
96 if pass==ttl { md_puts(" verdict=GREEN (mode machinery in execution; 16/32-bit real-mode decode = R5 rung-3)\n" as *u8); sys_exit(0); return 0 }
97 md_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
98}