aboutsummaryrefslogtreecommitdiff
path: root/mirai/asm
diff options
context:
space:
mode:
Diffstat (limited to 'mirai/asm')
-rw-r--r--mirai/asm/asm.zig4
-rw-r--r--mirai/asm/cpu/control.zig68
-rw-r--r--mirai/asm/cpu/cpu.zig22
-rw-r--r--mirai/asm/cpu/halt.zig36
-rw-r--r--mirai/asm/io/io.zig11
-rw-r--r--mirai/asm/io/port.zig56
6 files changed, 197 insertions, 0 deletions
diff --git a/mirai/asm/asm.zig b/mirai/asm/asm.zig
new file mode 100644
index 0000000..e6d1f24
--- /dev/null
+++ b/mirai/asm/asm.zig
@@ -0,0 +1,4 @@
+//! Assembly Operations
+
+pub const cpu = @import("cpu/cpu.zig");
+pub const io = @import("io/io.zig");
diff --git a/mirai/asm/cpu/control.zig b/mirai/asm/cpu/control.zig
new file mode 100644
index 0000000..ec408c1
--- /dev/null
+++ b/mirai/asm/cpu/control.zig
@@ -0,0 +1,68 @@
+//! CPU Control Register Operations
+
+pub fn read_cr0() u64 {
+ var result: u64 = undefined;
+ asm volatile ("mov %%cr0, %[result]"
+ : [result] "=r" (result),
+ );
+ return result;
+}
+
+pub fn write_cr0(value: u64) void {
+ asm volatile ("mov %[value], %%cr0"
+ :
+ : [value] "r" (value),
+ );
+}
+
+pub fn read_cr2() u64 {
+ var result: u64 = undefined;
+ asm volatile ("mov %%cr2, %[result]"
+ : [result] "=r" (result),
+ );
+ return result;
+}
+
+pub fn read_cr3() u64 {
+ var result: u64 = undefined;
+ asm volatile ("mov %%cr3, %[result]"
+ : [result] "=r" (result),
+ );
+ return result;
+}
+
+pub fn write_cr3(value: u64) void {
+ asm volatile ("mov %[value], %%cr3"
+ :
+ : [value] "r" (value),
+ : .{ .memory = true }
+ );
+}
+
+pub fn read_cr4() u64 {
+ var result: u64 = undefined;
+ asm volatile ("mov %%cr4, %[result]"
+ : [result] "=r" (result),
+ );
+ return result;
+}
+
+pub fn write_cr4(value: u64) void {
+ asm volatile ("mov %[value], %%cr4"
+ :
+ : [value] "r" (value),
+ );
+}
+
+pub fn flush_tlb() void {
+ const cr3_value = read_cr3();
+ write_cr3(cr3_value);
+}
+
+pub fn invalidate_page(virtual_address: u64) void {
+ asm volatile ("invlpg (%[address])"
+ :
+ : [address] "r" (virtual_address),
+ : .{ .memory = true }
+ );
+}
diff --git a/mirai/asm/cpu/cpu.zig b/mirai/asm/cpu/cpu.zig
new file mode 100644
index 0000000..a2c6a78
--- /dev/null
+++ b/mirai/asm/cpu/cpu.zig
@@ -0,0 +1,22 @@
+//! CPU Operations
+
+pub const control = @import("control.zig");
+pub const halt = @import("halt.zig");
+
+pub const read_cr0 = control.read_cr0;
+pub const write_cr0 = control.write_cr0;
+pub const read_cr2 = control.read_cr2;
+pub const read_cr3 = control.read_cr3;
+pub const write_cr3 = control.write_cr3;
+pub const read_cr4 = control.read_cr4;
+pub const write_cr4 = control.write_cr4;
+pub const flush_tlb = control.flush_tlb;
+pub const invalidate_page = control.invalidate_page;
+
+pub const halt_cpu = halt.halt;
+pub const halt_loop = halt.halt_loop;
+pub const enable_interrupts = halt.enable_interrupts;
+pub const disable_interrupts = halt.disable_interrupts;
+pub const are_interrupts_enabled = halt.are_interrupts_enabled;
+pub const read_flags = halt.read_flags;
+pub const pause = halt.pause;
diff --git a/mirai/asm/cpu/halt.zig b/mirai/asm/cpu/halt.zig
new file mode 100644
index 0000000..c401bc9
--- /dev/null
+++ b/mirai/asm/cpu/halt.zig
@@ -0,0 +1,36 @@
+//! CPU Halt Operations
+
+pub fn halt() void {
+ asm volatile ("hlt");
+}
+
+pub fn halt_loop() noreturn {
+ while (true) {
+ halt();
+ }
+}
+
+pub fn enable_interrupts() void {
+ asm volatile ("sti");
+}
+
+pub fn disable_interrupts() void {
+ asm volatile ("cli");
+}
+
+pub fn are_interrupts_enabled() bool {
+ const flags = read_flags();
+ return (flags & 0x200) != 0;
+}
+
+pub fn read_flags() u64 {
+ var result: u64 = undefined;
+ asm volatile ("pushfq; pop %[result]"
+ : [result] "=r" (result),
+ );
+ return result;
+}
+
+pub fn pause() void {
+ asm volatile ("pause");
+}
diff --git a/mirai/asm/io/io.zig b/mirai/asm/io/io.zig
new file mode 100644
index 0000000..8f322f8
--- /dev/null
+++ b/mirai/asm/io/io.zig
@@ -0,0 +1,11 @@
+//! I/O Operations
+
+pub const port = @import("port.zig");
+
+pub const read_byte = port.read_byte;
+pub const write_byte = port.write_byte;
+pub const read_word = port.read_word;
+pub const write_word = port.write_word;
+pub const read_long = port.read_long;
+pub const write_long = port.write_long;
+pub const io_wait = port.io_wait;
diff --git a/mirai/asm/io/port.zig b/mirai/asm/io/port.zig
new file mode 100644
index 0000000..4c2ffbb
--- /dev/null
+++ b/mirai/asm/io/port.zig
@@ -0,0 +1,56 @@
+//! Port I/O Operations
+
+pub fn read_byte(port: u16) u8 {
+ var result: u8 = undefined;
+ asm volatile ("inb %[port], %[result]"
+ : [result] "={al}" (result),
+ : [port] "N{dx}" (port),
+ );
+ return result;
+}
+
+pub fn write_byte(port: u16, value: u8) void {
+ asm volatile ("outb %[value], %[port]"
+ :
+ : [value] "{al}" (value),
+ [port] "N{dx}" (port),
+ );
+}
+
+pub fn read_word(port: u16) u16 {
+ var result: u16 = undefined;
+ asm volatile ("inw %[port], %[result]"
+ : [result] "={ax}" (result),
+ : [port] "N{dx}" (port),
+ );
+ return result;
+}
+
+pub fn write_word(port: u16, value: u16) void {
+ asm volatile ("outw %[value], %[port]"
+ :
+ : [value] "{ax}" (value),
+ [port] "N{dx}" (port),
+ );
+}
+
+pub fn read_long(port: u16) u32 {
+ var result: u32 = undefined;
+ asm volatile ("inl %[port], %[result]"
+ : [result] "={eax}" (result),
+ : [port] "N{dx}" (port),
+ );
+ return result;
+}
+
+pub fn write_long(port: u16, value: u32) void {
+ asm volatile ("outl %[value], %[port]"
+ :
+ : [value] "{eax}" (value),
+ [port] "N{dx}" (port),
+ );
+}
+
+pub fn io_wait() void {
+ write_byte(0x80, 0);
+}