hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/boot
diff options
context:
space:
mode:
Diffstat (limited to 'boot')
-rw-r--r--boot/boot.zig6
-rw-r--r--boot/idt.zig6
-rw-r--r--boot/limine.zig6
-rw-r--r--boot/pmm.zig10
-rw-r--r--boot/timer.zig17
5 files changed, 36 insertions, 9 deletions
diff --git a/boot/boot.zig b/boot/boot.zig
index 108afc8..8f8c7fe 100644
--- a/boot/boot.zig
+++ b/boot/boot.zig
@@ -10,6 +10,7 @@ const vmm = @import("vmm.zig");
const user = @import("user.zig");
const elf = @import("elf.zig");
const keyboard = @import("keyboard.zig");
+const timer = @import("timer.zig");
const bridge = @import("bridge");
// We need a panic handler otherwise zig won't be happy,
@@ -166,11 +167,16 @@ export fn _start() callconv(.c) noreturn {
// the cli/pop/sti-hlt bullshit closes the lost-wakeup race (a key
// arriving between "queue empty" and hlt would otherwise sit until
// the next keypress)
+ var last_ticks: u64 = 0;
while (true) {
asm volatile ("cli");
if (keyboard.pop()) |sc| {
asm volatile ("sti");
bridge.onKey(sc);
+ } else if (timer.now() != last_ticks) {
+ last_ticks = timer.now();
+ asm volatile ("sti");
+ bridge.onTick(last_ticks);
} else {
asm volatile ("sti; hlt");
}
diff --git a/boot/idt.zig b/boot/idt.zig
index fda5b9d..19afa6b 100644
--- a/boot/idt.zig
+++ b/boot/idt.zig
@@ -8,6 +8,7 @@ const gdt = @import("gdt.zig");
const serial = @import("serial.zig");
const pic = @import("pic.zig");
const keyboard = @import("keyboard.zig");
+const timer = @import("timer.zig");
// 64bit interrupt gate
const Gate = packed struct {
@@ -219,6 +220,7 @@ export fn irqCommon() callconv(.naked) void {
export fn irqDispatch(frame: *Frame) callconv(.c) void {
switch (frame.vector) {
+ pic.MASTER_OFFSET + 0 => timer.onIrq(), // IRQ0: PIT
pic.MASTER_OFFSET + 1 => keyboard.onIrq(), // IRQ1: keyboard
else => {},
}
@@ -242,8 +244,10 @@ pub fn setGate(vector: u8, handler: u64, dpl: u2) void {
// fill the exception vectors and load the IDT
pub fn init() void {
inline for (0..32) |v| setGate(v, @intFromPtr(&stub(v)), 0);
+ // IRQ0 (PIT) -> vector 0x20
// IRQ1 (keyboard) -> vector 0x21
- // the PIC is remapped separately in boot.
+ // the PIC is remapped separately in boot
+ setGate(pic.MASTER_OFFSET + 0, @intFromPtr(&irqStub(pic.MASTER_OFFSET + 0)), 0);
setGate(pic.MASTER_OFFSET + 1, @intFromPtr(&irqStub(pic.MASTER_OFFSET + 1)), 0);
idtr = .{ .limit = @sizeOf(@TypeOf(idt)) - 1, .base = @intFromPtr(&idt) };
asm volatile ("lidt (%[idtr])"
diff --git a/boot/limine.zig b/boot/limine.zig
index f1ed158..3d18b31 100644
--- a/boot/limine.zig
+++ b/boot/limine.zig
@@ -1,5 +1,5 @@
-// Limine scans the loaded image for these magic numbers, BaseRevision is
-// a handshake, essentially we ask limine for rev 3, and if it supports it,
+// Limine scans the loaded image for these magic numbers, BaseRevision is
+// a handshake, essentially we ask limine for rev 3, and if it supports it,
// limine zeros it out
pub const BaseRevision = extern struct {
magic0: u64 = 0xf9562b2d5c95a6c8,
@@ -11,7 +11,7 @@ pub const BaseRevision = extern struct {
}
};
-// bracketing markers, they are pretty optional but when we add proper
+// bracketing markers, they are pretty optional but when we add proper
// limine requests, having these here comes handy
pub const RequestsStartMarker = extern struct {
m0: u64 = 0xf6b8f4b39de7d1ae,
diff --git a/boot/pmm.zig b/boot/pmm.zig
index 71d132e..0c4bdda 100644
--- a/boot/pmm.zig
+++ b/boot/pmm.zig
@@ -20,10 +20,10 @@ var hhdm_offset: u64 = 0;
// reached through the HHDM, so it's just a normal slice we write through.
var bitmap: []u8 = &[_]u8{};
-var total_frames: usize = 0; // frames the bitmap can index (up to highest usable end)
+var total_frames: usize = 0; // frames the bitmap can index (up to highest usable end)
var usable_frames: usize = 0; // frames that started free
-var free_frames: usize = 0; // frames currently free
-var next_hint: usize = 0; // where to start the next alloc scan
+var free_frames: usize = 0; // frames currently free
+var next_hint: usize = 0; // where to start the next alloc scan
pub fn physToVirt(phys: u64) u64 {
return phys + hhdm_offset;
@@ -95,7 +95,7 @@ pub fn init(hhdm: *const limine.HhdmResponse, memmap: *const limine.MemoryMapRes
//
// WARNING: never hand out a physical-null address
//
- // unlike marking a region free, here we round the END UP so a partial
+ // unlike marking a region free, here we round the END UP so a partial
// last frame the bitmap spills into still gets reserved
{
const start = storage_base / PAGE_SIZE;
@@ -136,7 +136,7 @@ pub fn alloc() ?u64 {
// hand out n contiguous physical frames cause the heap needs one flat buffer, and a
// single usable region is contiguous in physical space, so this just finds a
-// run of n free bits.
+// run of n free bits.
// NOTE: returns the base physical address of the run
pub fn allocContig(n: usize) ?u64 {
if (n == 0) return null;
diff --git a/boot/timer.zig b/boot/timer.zig
new file mode 100644
index 0000000..4569d6a
--- /dev/null
+++ b/boot/timer.zig
@@ -0,0 +1,17 @@
+// PIT channel 0 tick counter
+// configuring the PIT itself (outb to 0x43/0x40) is done in revo (kernel
+// `pit_init`), since it's just port writes the VM can drive
+
+var ticks: u64 = 0;
+
+// called from the IRQ0 handler
+pub fn onIrq() void {
+ const t: *volatile u64 = &ticks;
+ t.* +%= 1;
+}
+
+// called from the event loop
+pub fn now() u64 {
+ const t: *volatile u64 = &ticks;
+ return t.*;
+}