Skip to content

std.x86

x86-64 instructions a kernel needs: ports, interrupts, control registers, msrs most only work in ring 0

pub outb :: fn(port: u16, v: u8)
pub outw :: fn(port: u16, v: u16)
pub outl :: fn(port: u16, v: u32)
pub inb :: fn(port: u16) -> u8
pub inw :: fn(port: u16) -> u16
pub inl :: fn(port: u16) -> u32
pub cli :: fn()
pub sti :: fn()
pub hlt :: fn()

waits for the next interrupt

pub pause :: fn()

spin-loop hint

pub lgdt :: fn(descriptor: *const u8)

loads the gdt/idt from a 10-byte descriptor: u16 limit, then u64 base

pub lidt :: fn(descriptor: *const u8)
pub breakpoint :: fn()

int3: the breakpoint exception, vector 3

pub read_cs :: fn() -> u16

the code segment selector running now

pub InterruptFrame :: struct {
ip: u64,
cs: u64,
flags: u64,
sp: u64,
ss: u64,
}

what the cpu pushes before it calls an #interrupt function; an exception with an error code passes that as the function’s second parameter

pub Idt :: struct {
gates: [512]u64,
}

256 gates of 16 bytes; a gate is two words

pub set :: fn(self: *Self, vector: u8, handler: *void)

vector calls handler (core::fn_ptr of an #interrupt function) with interrupts off

pub load :: fn(self: *const Self)

makes this the cpu’s table; it must stay where it is from then on

pub idt :: fn() -> Idt

an empty table, to fill with set

pub read_cr0 :: fn() -> u64
pub read_cr2 :: fn() -> u64

the address of the last page fault

pub read_cr3 :: fn() -> u64

the page table root

pub write_cr3 :: fn(v: u64)
pub read_cr4 :: fn() -> u64
pub invlpg :: fn(addr: usize)

drops the tlb entry of the page holding addr

pub rdmsr :: fn(msr: u32) -> u64
pub wrmsr :: fn(msr: u32, v: u64)
pub rdtsc :: fn() -> u64

cycles since reset

pub Cpuid :: struct {
eax: u32,
ebx: u32,
ecx: u32,
edx: u32,
}
pub cpuid :: fn(leaf: u32, sub: u32) -> Cpuid

cpuid for leaf and sub