def cli(): __asm__("cli", [ASM_DESCR.CLOBBER_MEMORY]) def sti(): __asm__("sti", [ASM_DESCR.CLOBBER_MEMORY]) def hlt(): __asm__("hlt", [ASM_DESCR.CLOBBER_MEMORY]) def nop(): __asm__("nop", [ASM_DESCR.CLOBBER_MEMORY]) def pause(): __asm__("pause", op=[ASM_DESCR.CLOBBER_MEMORY]) def inb(port: uint16) -> uint8: value: uint32 __asm__(f"""mov edx, {asminp(uint32(port), ASM_DESCR.REG_ANY)} in al, dx movzx $0, al""", out = [asmout(value, ASM_DESCR.OUTPUT_REG)], op =[ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) return uint8(value) def outb(port: uint16, value: uint8): __asm__(f"""mov edx, {asminp(uint32(port), ASM_DESCR.REG_ANY)} mov eax, {asminp(uint32(value), ASM_DESCR.REG_ANY)} out dx, al""", op = [ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) def inw(port: uint16) -> uint16: value: uint32 __asm__(f"""mov edx, {asminp(uint32(port), ASM_DESCR.REG_ANY)} in ax, dx movzx eax, ax mov {asmout(value, ASM_DESCR.OUTPUT_REG)}, eax""", out = [asmout(value, ASM_DESCR.OUTPUT_REG)], op =[ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) return uint16(value) def outw(port: uint16, value: uint16): __asm__(f"""mov edx, {asminp(uint32(port), ASM_DESCR.REG_ANY)} mov eax, {asminp(uint32(value), ASM_DESCR.REG_ANY)} out dx, ax""", op = [ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) def inl(port: uint16) -> uint32: value: uint32 __asm__(f"""mov edx, {asminp(uint32(port), ASM_DESCR.REG_ANY)} in eax, dx mov {asmout(value, ASM_DESCR.OUTPUT_REG)}, eax""", out = [asmout(value, ASM_DESCR.OUTPUT_REG)], op =[ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) return value def outl(port: uint16, value: uint32): __asm__(f"""mov edx, {asminp(uint32(port), ASM_DESCR.REG_ANY)} mov eax, {asminp(value, ASM_DESCR.REG_ANY)} out dx, eax""", op = [ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) def io_wait(): # ATA 规范的 I/O 延时:**连续 4 次读备选状态寄存器 0x3F6**。它是真实设备端口,每次 in # 都是一次真实 I/O 往返,稳定给出 ≥400ns(规范要求命令块寄存器两次写之间至少 400ns)。 # 原先写的是诊断端口 0x80 —— 该端口背后没有设备,在 QEMU 上几乎不消耗时间,等于**没有 # 延时**:IDE 命令块寄存器(0x1F2..0x1F7)连写会丢写 ⇒ LBA 寄存器残留上一次的值 ⇒ 读到 # **别的扇区**的数据。现场(参见 0ee5ec5 与 serial.log):读根目录扇区 8192 却读回 ELF # 文件头 ⇒ 目录项全是垃圾 ⇒ app spawn 失败;或 waitDataReady 超时 ⇒ diskio.read 报错。 __asm__(f"""mov dx, 0x3F6 in al, dx in al, dx in al, dx in al, dx""", op = [ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_DX, ASM_DESCR.CLOBBER_RAX]) inline def pushall(): __asm__(f""" push rax push rbx push rcx push rdx push rsi push rdi push rbp push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15""", [ASM_DESCR.CLOBBER_MEMORY] ) inline def popall(): __asm__(f""" pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rbp pop rdi pop rsi pop rdx pop rcx pop rbx pop rax""", [ASM_DESCR.CLOBBER_MEMORY] ) def cpu_switch_context(old_stack: uint64*, new_stack: uint64): __asm__(f""" push rax push rbx push rcx push rdx push rsi push rdi push rbp push r8 push r9 push r10 push r11 push r12 push r13 push r14 push r15 mov [{asminp(old_stack, ASM_DESCR.REG_ANY)}], rsp mov rsp, {asminp(new_stack, ASM_DESCR.REG_ANY)} pop r15 pop r14 pop r13 pop r12 pop r11 pop r10 pop r9 pop r8 pop rbp pop rdi pop rsi pop rdx pop rcx pop rbx pop rax""", op=[ASM_DESCR.CLOBBER_MEMORY]) def BSSClean(): __asm__( "lea rdi, [rip + __bss_start]\n" "lea rcx, [rip + __bss_end]\n" "sub rcx, rdi\n" "xor eax, eax\n" "cld\n" "rep stosb", op=[ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_RDI, ASM_DESCR.CLOBBER_RCX, ASM_DESCR.CLOBBER_RAX] )