diff options
| author | Bobby <[email protected]> | 2026-02-24 06:45:06 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2026-02-24 06:45:06 +0530 |
| commit | 297c66b480a238dad5ce7f03405fe6f5b9123701 (patch) | |
| tree | c034198726c68d011380a581b1c32282eb7a2420 /hikari/asm/asm.zig | |
| parent | 6a7363663f34a031f3138802eeab1d5e569a753d (diff) | |
| download | akiba-297c66b480a238dad5ce7f03405fe6f5b9123701.tar.xz akiba-297c66b480a238dad5ce7f03405fe6f5b9123701.zip | |
Implement Hikari Custom Boot Loader
Diffstat (limited to 'hikari/asm/asm.zig')
| -rw-r--r-- | hikari/asm/asm.zig | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/hikari/asm/asm.zig b/hikari/asm/asm.zig new file mode 100644 index 0000000..962fe60 --- /dev/null +++ b/hikari/asm/asm.zig @@ -0,0 +1,146 @@ +//! Hikari Assembly Operations + +pub inline fn read_cr3() u64 { + return asm volatile ("mov %cr3, %[ret]" + : [ret] "=r" (-> u64), + ); +} + +pub inline fn write_cr3(value: u64) void { + asm volatile ("mov %[value], %cr3" + : + : [value] "r" (value), + : .{ .memory = true }); +} + +pub inline fn read_cr0() u64 { + return asm volatile ("mov %cr0, %[ret]" + : [ret] "=r" (-> u64), + ); +} + +pub inline fn write_cr0(value: u64) void { + asm volatile ("mov %[value], %cr0" + : + : [value] "r" (value), + ); +} + +pub inline fn read_cr4() u64 { + return asm volatile ("mov %cr4, %[ret]" + : [ret] "=r" (-> u64), + ); +} + +pub inline fn write_cr4(value: u64) void { + asm volatile ("mov %[value], %cr4" + : + : [value] "r" (value), + ); +} + +pub inline fn read_msr(msr: u32) u64 { + var low: u32 = undefined; + var high: u32 = undefined; + asm volatile ("rdmsr" + : [low] "={eax}" (low), + [high] "={edx}" (high), + : [msr] "{ecx}" (msr), + ); + return (@as(u64, high) << 32) | low; +} + +pub inline fn write_msr(msr: u32, value: u64) void { + const low: u32 = @truncate(value); + const high: u32 = @truncate(value >> 32); + asm volatile ("wrmsr" + : + : [msr] "{ecx}" (msr), + [low] "{eax}" (low), + [high] "{edx}" (high), + ); +} + +pub inline fn halt() noreturn { + while (true) { + asm volatile ("hlt"); + } +} + +pub inline fn disable_interrupts() void { + asm volatile ("cli"); +} + +pub inline fn enable_interrupts() void { + asm volatile ("sti"); +} + +pub inline fn invlpg(address: u64) void { + asm volatile ("invlpg (%[addr])" + : + : [addr] "r" (address), + : .{ .memory = true }); +} + +pub inline fn flush_tlb() void { + const cr3 = read_cr3(); + write_cr3(cr3); +} + +pub const msr_efer: u32 = 0xC0000080; +pub const efer_sce: u64 = 1 << 0; +pub const efer_lme: u64 = 1 << 8; +pub const efer_lma: u64 = 1 << 10; +pub const efer_nxe: u64 = 1 << 11; + +pub const cr0_pe: u64 = 1 << 0; +pub const cr0_mp: u64 = 1 << 1; +pub const cr0_em: u64 = 1 << 2; +pub const cr0_ts: u64 = 1 << 3; +pub const cr0_et: u64 = 1 << 4; +pub const cr0_ne: u64 = 1 << 5; +pub const cr0_wp: u64 = 1 << 16; +pub const cr0_am: u64 = 1 << 18; +pub const cr0_nw: u64 = 1 << 29; +pub const cr0_cd: u64 = 1 << 30; +pub const cr0_pg: u64 = 1 << 31; + +pub const cr4_vme: u64 = 1 << 0; +pub const cr4_pvi: u64 = 1 << 1; +pub const cr4_tsd: u64 = 1 << 2; +pub const cr4_de: u64 = 1 << 3; +pub const cr4_pse: u64 = 1 << 4; +pub const cr4_pae: u64 = 1 << 5; +pub const cr4_mce: u64 = 1 << 6; +pub const cr4_pge: u64 = 1 << 7; +pub const cr4_pce: u64 = 1 << 8; +pub const cr4_osfxsr: u64 = 1 << 9; +pub const cr4_osxmmexcpt: u64 = 1 << 10; +pub const cr4_fsgsbase: u64 = 1 << 16; +pub const cr4_osxsave: u64 = 1 << 18; +pub const cr4_smep: u64 = 1 << 20; +pub const cr4_smap: u64 = 1 << 21; + +pub fn jump_to_kernel( + entry_point: u64, + stack_top: u64, + boot_params: u64, + pml4_address: u64, +) noreturn { + disable_interrupts(); + + write_cr3(pml4_address); + + asm volatile ( + \\mov %[stack], %%rsp + \\mov %[params], %%rdi + \\xor %%rbp, %%rbp + \\jmp *%[entry] + : + : [stack] "r" (stack_top), + [params] "r" (boot_params), + [entry] "r" (entry_point), + : .{ .memory = true }); + + unreachable; +} |
