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}