pub const boot = @import("boot.zig"); pub const instructions = @import("instructions/root.zig"); pub const interrupts = @import("interrupts/root.zig"); pub const mm = @import("mm/root.zig"); pub const port = @import("port.zig"); pub const structures = @import("structures/root.zig"); pub const tsc = @import("tsc.zig"); pub const registers = @import("registers.zig"); const common = @import("common"); const std = @import("std"); // needed by std options pub const page_size = struct { pub const min = 4 << 10; pub const max = 4 << 10; pub fn get() usize { return 4 << 10; } }; pub var per_cpu_init_data: PerCpuInitData = .{}; const PerCpuInitData = struct { const StandardGdt = structures.gdt.StandardGdt; const Tss = structures.tss.Tss; gdt_buf: []StandardGdt = undefined, tss_buf: []Tss = undefined, // Physical ptr stack_buf: usize = undefined, const stack_size = std.heap.page_size_max; const Self = @This(); pub fn init(self: *Self, cpu_count: u64) void { // 1. Allocate stack space for every core self.stack_buf = common.init_data.bootmem.allocPhys(stack_size * cpu_count) catch |err| { std.log.err("init PerCpuInitData: failed to allocate stack! {}", .{err}); @panic("stack_buf"); }; // 2. Allocate space for GDT and TSS data const gdt_size = @sizeOf(StandardGdt); const tss_size = @sizeOf(Tss); const total_required_size = gdt_size * cpu_count + tss_size * cpu_count; const buf: [*]u8 = @ptrFromInt(common.init_data.bootmem.allocMem(total_required_size) catch |err| { std.log.err("init PerCpuInitData: GDT/TSS alloc failed: {}", .{err}); @panic("gdt_tss_buf"); }); // 3. Transmute and fill out the structure const gdt_buf: [*]StandardGdt = @ptrCast(@alignCast(buf[0 .. gdt_size * cpu_count])); const tss_buf: [*]Tss = @ptrCast(@alignCast(buf[gdt_size * cpu_count ..][0 .. tss_size * cpu_count])); self.gdt_buf = gdt_buf[0..cpu_count]; self.tss_buf = tss_buf[0..cpu_count]; } // returns a pointer to the TOP of the stack! pub fn getStackPhys(self: *Self, core_num: usize) usize { return self.stack_buf + (core_num + 1) * stack_size; } };