diff --git a/build.zig b/build.zig index a89b793..ef795d7 100644 --- a/build.zig +++ b/build.zig @@ -6,7 +6,7 @@ const SupportedArch = enum { aarch64, riscv64, - fn makeTarget(self: SupportedArch, b: *std.Build) std.Build.ResolvedTarget { + fn make_target(self: SupportedArch, b: *std.Build) std.Build.ResolvedTarget { switch (self) { .riscv64 => { return b.resolveTargetQuery(.{ @@ -18,11 +18,11 @@ const SupportedArch = enum { .aarch64 => { const T = std.Target.aarch64; - const addFeatures = T.featureSet(&.{ + const add_features = T.featureSet(&.{ T.Feature.v8a, T.Feature.strict_align, }); - const subFeatures = T.featureSet(&.{ + const sub_features = T.featureSet(&.{ T.Feature.neon, T.Feature.fp_armv8, }); @@ -31,14 +31,14 @@ const SupportedArch = enum { .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none, - .cpu_features_add = addFeatures, - .cpu_features_sub = subFeatures, + .cpu_features_add = add_features, + .cpu_features_sub = sub_features, }); }, } } - fn addTargetSpecific(self: SupportedArch, b: *std.Build, kernel: *std.Build.Step.Compile) anyerror!*std.Build.Step { + fn add_target_specific(self: SupportedArch, b: *std.Build, kernel: *std.Build.Step.Compile) anyerror!*std.Build.Step { switch (self) { .riscv64 => { kernel.entry = .{ .symbol_name = "__rv64_entry" }; @@ -63,12 +63,12 @@ const SupportedArch = enum { b.installArtifact(kernel); if (self == .riscv64 or self == .aarch64) { - const fakeLinuxHeader: *std.Build.Step = try b.allocator.create(std.Build.Step); - fakeLinuxHeader.* = std.Build.Step.init(.{ + const fake_linux_header: *std.Build.Step = try b.allocator.create(std.Build.Step); + fake_linux_header.* = std.Build.Step.init(.{ .id = std.Build.Step.Id.custom, .name = "insert fake linux header", .owner = kernel.step.owner, - .makeFn = insertFakeLinuxImageHeader, + .makeFn = insert_fake_linux_image_header, }); const elf2bin = b.addSystemCommand(&.{ @@ -79,8 +79,8 @@ const SupportedArch = enum { "zig-out/bin/kernel.bin", }); - fakeLinuxHeader.dependOn(b.getInstallStep()); - elf2bin.step.dependOn(fakeLinuxHeader); + fake_linux_header.dependOn(b.getInstallStep()); + elf2bin.step.dependOn(fake_linux_header); return &elf2bin.step; } else { @@ -89,7 +89,7 @@ const SupportedArch = enum { } }; -fn insertFakeLinuxImageHeader(step: *std.Build.Step, opts: std.Build.Step.MakeOptions) anyerror!void { +fn insert_fake_linux_image_header(step: *std.Build.Step, opts: std.Build.Step.MakeOptions) anyerror!void { const RISCV_MAGIC1 = "RISCV\x00\x00\x00"; const RISCV_MAGIC2 = "RSC\x05"; @@ -101,15 +101,15 @@ fn insertFakeLinuxImageHeader(step: *std.Build.Step, opts: std.Build.Step.MakeOp _ = try file.readAll(std.mem.asBytes(&ehdr)); // Figure out total image size - var imageAddrMax: u64 = 0; + var image_addr_max: u64 = 0; for (0..ehdr.e_phnum) |i| { var phdr: elf.Phdr = undefined; _ = try file.preadAll(std.mem.asBytes(&phdr), ehdr.e_phoff + i * ehdr.e_phentsize); const end = (phdr.p_vaddr + phdr.p_memsz + 0xFFF) & ~@as(u64, 0xFFF); - if (phdr.p_type == elf.PT_LOAD and end > imageAddrMax) { - imageAddrMax = end; + if (phdr.p_type == elf.PT_LOAD and end > image_addr_max) { + image_addr_max = end; } } @@ -126,7 +126,7 @@ fn insertFakeLinuxImageHeader(step: *std.Build.Step, opts: std.Build.Step.MakeOp _ = try file.preadAll(&data, phdr.p_offset); if (std.mem.eql(u8, RISCV_MAGIC1, data[48..56]) and std.mem.eql(u8, RISCV_MAGIC2, data[56..60])) { - try file.pwriteAll(std.mem.asBytes(&imageAddrMax), phdr.p_offset + 16); + try file.pwriteAll(std.mem.asBytes(&image_addr_max), phdr.p_offset + 16); break; } } @@ -140,41 +140,41 @@ fn build_riscv64(b: *std.Build) anyerror!void { } pub fn build(b: *std.Build) anyerror!void { - const maybeArchOption = b.option(SupportedArch, "arch", "Architecture to use"); + const maybe_arch_option = b.option(SupportedArch, "arch", "Architecture to use"); - const arch = maybeArchOption orelse DEFAULT_ARCH; - const target = arch.makeTarget(b); + const arch = maybe_arch_option orelse DEFAULT_ARCH; + const target = arch.make_target(b); const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .ReleaseFast }); - const codeModel: std.builtin.CodeModel = switch (arch) { + const code_model: std.builtin.CodeModel = switch (arch) { .riscv64 => .medium, .aarch64 => .small, }; - const kernelModule = b.addModule("kernel", .{ + const kernel_module = b.addModule("kernel", .{ .optimize = optimize, .target = target, .pic = true, .red_zone = false, - .code_model = codeModel, + .code_model = code_model, .root_source_file = b.path("src/kernel.zig"), }); const kernel = b.addExecutable(.{ .name = "kernel", - .root_module = kernelModule, + .root_module = kernel_module, .pic = true, }); kernel.pie = true; - const installDocs = b.addInstallDirectory(.{ + const install_docs = b.addInstallDirectory(.{ .source_dir = kernel.getEmittedDocs(), .install_dir = .prefix, .install_subdir = "docs", }); - const docsStep = b.step("docs", "Install documentation"); - docsStep.dependOn(&installDocs.step); + const docs_step = b.step("docs", "Install documentation"); + docs_step.dependOn(&install_docs.step); - const kernelStep = try arch.addTargetSpecific(b, kernel); + const kernel_step = try arch.add_target_specific(b, kernel); // TODO QEMU binary override const qemu_info = switch (target.result.cpu.arch) { @@ -203,7 +203,7 @@ pub fn build(b: *std.Build) anyerror!void { qemu_cmd.addArgs(&.{ "-bios", "etc/boot/rv64_fw_jump.bin" }); } - qemu_cmd.step.dependOn(kernelStep); + qemu_cmd.step.dependOn(kernel_step); if (b.args) |args| qemu_cmd.addArgs(args); const run_step = b.step("run", "Start the OS in qemu"); run_step.dependOn(&qemu_cmd.step); diff --git a/src/arch.zig b/src/arch.zig index b02792b..6ef99a4 100644 --- a/src/arch.zig +++ b/src/arch.zig @@ -4,7 +4,7 @@ const std = @import("std"); const builtin = @import("builtin"); -const impl = switch (builtin.cpu.arch) { +pub const impl = switch (builtin.cpu.arch) { .riscv64 => @import("arch/riscv64.zig"), .aarch64 => @import("arch/aarch64.zig"), else => @compileError("Unsupported architecture"), @@ -16,29 +16,29 @@ pub inline fn halt() noreturn { } /// Returns the current state of IRQ masking. -pub inline fn interruptMask() bool { - return impl.interruptMask(); +pub inline fn interrupt_mask() bool { + return impl.interrupt_mask(); } /// Modifies the interrupt mask to either allow or block IRQs from being delivered to the CPU. /// Returns the old IRQ mask. -pub inline fn setInterruptMask(masked: bool) bool { - return impl.setInterruptMask(masked); +pub inline fn set_interrupt_mask(masked: bool) bool { + return impl.set_interrupt_mask(masked); } /// Suspends the CPU until an interrupt is signalled. -pub inline fn waitForInterrupt() void { - impl.waitForInterrupt(); +pub inline fn wait_for_interrupt() void { + impl.wait_for_interrupt(); } /// Hint to the CPU that the code is executing a "busy-wait" or a "spin-wait" loop. -pub inline fn spinHint() void { - impl.spinHint(); +pub inline fn spin_hint() void { + impl.spin_hint(); } /// Set the CPU's thread pointer to some value. -pub inline fn setThreadPointer(value: usize) void { - impl.setThreadPointer(value); +pub inline fn set_thread_pointer(value: usize) void { + impl.set_thread_pointer(value); } /// Combined memory/compiler fence to ensure specific ordering of instructions and memory accesses. diff --git a/src/arch/aarch64.zig b/src/arch/aarch64.zig index 12bdf62..5a4977f 100644 --- a/src/arch/aarch64.zig +++ b/src/arch/aarch64.zig @@ -3,7 +3,7 @@ const std = @import("std"); const boot = @import("aarch64/boot.zig"); const regs = @import("aarch64/regs.zig"); -export const _ = boot.aa64BspLowerEntry; +export const _ = boot.aa64_bsp_lower_entry; pub const Context = struct { pub fn idle() Context { @@ -21,15 +21,15 @@ pub const Context = struct { @panic("TODO"); } - pub fn switchFrom(self: *Context, from: *Context) void { + pub fn switch_from(self: *Context, from: *Context) void { _ = self; _ = from; @panic("TODO"); } }; -pub fn setInterruptMask(masked: bool) bool { - const old = interruptMask(); +pub fn set_interrupt_mask(masked: bool) bool { + const old = interrupt_mask(); if (masked) { regs.DAIF.modify(.{ .I = true }, .{}); } else { @@ -38,7 +38,7 @@ pub fn setInterruptMask(masked: bool) bool { return old; } -pub fn interruptMask() bool { +pub fn interrupt_mask() bool { return regs.DAIF.read().I; } @@ -46,7 +46,7 @@ pub fn halt() noreturn { while (true) {} } -pub fn spinHint() void { +pub fn spin_hint() void { // TODO } diff --git a/src/arch/aarch64/boot.zig b/src/arch/aarch64/boot.zig index 0efd156..318d848 100644 --- a/src/arch/aarch64/boot.zig +++ b/src/arch/aarch64/boot.zig @@ -6,18 +6,18 @@ const exception = @import("exception.zig"); const arch = kernel.arch; const mem = kernel.mem; const log = kernel.debug.log; -const physMemory = mem.phys; +const phys_memory = mem.phys; extern const __aa64_bsp_stack_top: u8; -var gDtbAddress: u64 = undefined; +var g_dtb_address: u64 = undefined; -fn earlyDebugPrint(byte: u8) void { +fn early_debug_print(byte: u8) void { const address = 0x9000000; @as(*volatile u32, @ptrFromInt(address)).* = byte; } -fn relocAddressToUpper(ptr: *const anyopaque) usize { +fn reloc_address_to_upper(ptr: *const anyopaque) usize { const p = @intFromPtr(ptr); if (p >= vmm.KERNEL_VIRTUAL_BASE) { return p; @@ -26,7 +26,7 @@ fn relocAddressToUpper(ptr: *const anyopaque) usize { } } -fn relocAddressToLower(ptr: *const anyopaque) usize { +fn reloc_address_to_lower(ptr: *const anyopaque) usize { const p = @intFromPtr(ptr); if (p >= vmm.KERNEL_VIRTUAL_BASE) { return p - vmm.KERNEL_VIRTUAL_BASE; @@ -35,24 +35,24 @@ fn relocAddressToLower(ptr: *const anyopaque) usize { } } -fn aa64BspUpperEntry(realAddress: u64) callconv(.C) noreturn { +fn aa64_bsp_upper_entry(real_address: u64) callconv(.C) noreturn { // Relocate the kernel yet again - const relaStart = relocAddressToUpper(&__rela_start); - const relaEnd = relocAddressToUpper(&__rela_end); - const relOffset = vmm.KERNEL_VIRTUAL_BASE + realAddress; + const rela_start = reloc_address_to_upper(&__rela_start); + const rela_end = reloc_address_to_upper(&__rela_end); + const rel_offset = vmm.KERNEL_VIRTUAL_BASE + real_address; arch.barrier(.acq_rel); - aa64RelocateKernel(relOffset, relaStart, relaEnd); + aa64_relocate_kernel(rel_offset, rela_start, rela_end); arch.barrier(.acq_rel); - log.setWriteFn(&earlyDebugPrint); + log.set_write_fn(&early_debug_print); exception.init(); - mem.PhysicalAddress.gVirtualizeBase = 0; - mem.PhysicalAddress.gVirtualizeSize = 16 << 30; + mem.PhysicalAddress.g_virtualize_base = 0; + mem.PhysicalAddress.g_virtualize_size = 16 << 30; - setupMemoryFromFdt(realAddress); + setup_memory_from_fdt(real_address); asm volatile ("" ::: "memory"); @@ -64,15 +64,15 @@ fn aa64BspUpperEntry(realAddress: u64) callconv(.C) noreturn { arch.halt(); } -pub export fn aa64BspLowerEntry(realAddress: u64, dtbAddress: u64) callconv(.C) noreturn { - gDtbAddress = dtbAddress; +pub export fn aa64_bsp_lower_entry(real_address: u64, dtb_address: u64) callconv(.C) noreturn { + g_dtb_address = dtb_address; - vmm.mapEarly(realAddress); + vmm.map_early(real_address); - const pc = @intFromPtr(&aa64BspUpperEntry) + vmm.KERNEL_VIRTUAL_BASE; + const pc = @intFromPtr(&aa64_bsp_upper_entry) + vmm.KERNEL_VIRTUAL_BASE; const sp = @intFromPtr(&__aa64_bsp_stack_top) + vmm.KERNEL_VIRTUAL_BASE; - longJump(pc, sp, realAddress); + long_jump(pc, sp, real_address); } // Functions used by the boot process @@ -82,18 +82,18 @@ extern const __rela_end: u8; extern var __kernel_start: u8; extern var __kernel_end: u8; -export fn aa64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) void { +export fn aa64_relocate_kernel(image_base: usize, rela_start: usize, rela_end: usize) void { const elf = @import("std").elf; - const relaTablePtr = @as([*]elf.Rela, @ptrFromInt(relaStart)); - const relaCount = (relaEnd - relaStart) / @sizeOf(elf.Rela); - const relaTable = relaTablePtr[0..relaCount]; - for (relaTable) |entry| { - const relaType: elf.R_AARCH64 = @enumFromInt(entry.r_type()); - switch (relaType) { + const rela_table_ptr = @as([*]elf.Rela, @ptrFromInt(rela_start)); + const rela_count = (rela_end - rela_start) / @sizeOf(elf.Rela); + const rela_table = rela_table_ptr[0..rela_count]; + for (rela_table) |entry| { + const rela_type: elf.R_AARCH64 = @enumFromInt(entry.r_type()); + switch (rela_type) { .RELATIVE => { - const value = @as(*isize, @ptrFromInt(imageBase + entry.r_offset)); - value.* = @as(isize, @bitCast(imageBase)) + entry.r_addend; + const value = @as(*isize, @ptrFromInt(image_base + entry.r_offset)); + value.* = @as(isize, @bitCast(image_base)) + entry.r_addend; }, else => { arch.halt(); @@ -102,7 +102,7 @@ export fn aa64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) } } -inline fn longJump(pc: usize, sp: usize, a0: usize) noreturn { +inline fn long_jump(pc: usize, sp: usize, a0: usize) noreturn { asm volatile ( \\ mov sp, %[sp] \\ br %[pc] @@ -115,19 +115,19 @@ inline fn longJump(pc: usize, sp: usize, a0: usize) noreturn { unreachable; } -fn setupMemoryFromFdt(realAddress: usize) void { - _ = realAddress; +fn setup_memory_from_fdt(real_address: usize) void { + _ = real_address; - const kernelStart = relocAddressToLower(&__kernel_start); // 0 - const kernelEnd = relocAddressToLower(&__kernel_end); // whatever + const kernel_start = reloc_address_to_lower(&__kernel_start); // 0 + const kernel_end = reloc_address_to_lower(&__kernel_end); // whatever - const fdt = dtb.Fdt.fromPhysicalAddress(.{ .raw = gDtbAddress }) catch |err| { + const fdt = dtb.Fdt.from_physical_address(.{ .raw = g_dtb_address }) catch |err| { log.panic("Cannot initialize raw DTB: {}", .{err}); }; - fdt.addPhysicalMemoryToSystem(); + fdt.add_physical_memory_to_system(); - physMemory.addReservedRegion("kernel", kernelStart, kernelEnd - kernelStart); - physMemory.addReservedRegion("fdt", gDtbAddress, vmm.L3.align_up(fdt.bytes.len)); + phys_memory.add_reserved_region("kernel", kernel_start, kernel_end - kernel_start); + phys_memory.add_reserved_region("fdt", g_dtb_address, vmm.L3.align_up(fdt.bytes.len)); - physMemory.init(); + phys_memory.init(); } diff --git a/src/arch/aarch64/entry.S b/src/arch/aarch64/entry.S index 80f38c7..889c02f 100644 --- a/src/arch/aarch64/entry.S +++ b/src/arch/aarch64/entry.S @@ -41,11 +41,11 @@ __aa64_entry: mov x0, x19 adr x1, __rela_start adr x2, __rela_end - bl aa64RelocateKernel + bl aa64_relocate_kernel mov x0, x19 mov x1, x20 - b aa64BspLowerEntry + b aa64_bsp_lower_entry .parking_lot: wfe diff --git a/src/arch/aarch64/exception.zig b/src/arch/aarch64/exception.zig index 2c26edc..1d036c5 100644 --- a/src/arch/aarch64/exception.zig +++ b/src/arch/aarch64/exception.zig @@ -27,7 +27,7 @@ pub fn init() void { regs.VBAR_EL1.set(vbar_el1); } -fn commonIrqHandler(frame: *ExceptionFrame) void { +fn common_irq_handler(frame: *ExceptionFrame) void { _ = frame; @panic("TODO: IRQ"); } @@ -40,16 +40,16 @@ export fn __aa64_el1_sync_handler(frame: *ExceptionFrame) callconv(.C) void { const elr = regs.ELR_EL1.get(); log.err("Exception in EL1:", .{}); - log.err(" EC = {s} (0b{b:06}) ISS = 0x{x}", .{ esr.EC.asStr(), @intFromEnum(esr.EC), esr.ISS }); + log.err(" EC = {s} (0b{b:06}) ISS = 0x{x}", .{ esr.EC.as_str(), @intFromEnum(esr.EC), esr.ISS }); log.err(" ELR = 0x{x:016}", .{elr}); - switch (esr.asEnum()) { + switch (esr.as_enum()) { .data_abort => |abort| { - const faultKindStr = abort.DFSC.asStr(); - const accessSizeStr = @tagName(abort.SAS); - const accessTypeStr = if (abort.WnR) "write" else "read"; + const fault_kind_str = abort.DFSC.as_str(); + const access_size_str = @tagName(abort.SAS); + const access_type_str = if (abort.WnR) "write" else "read"; - log.err(" Illegal {s} of a {s}: {s}", .{ accessTypeStr, accessSizeStr, faultKindStr }); + log.err(" Illegal {s} of a {s}: {s}", .{ access_type_str, access_size_str, fault_kind_str }); if (!abort.FnV) { log.err(" FAR = 0x{x:016}", .{far}); } else { @@ -65,7 +65,7 @@ export fn __aa64_el1_sync_handler(frame: *ExceptionFrame) callconv(.C) void { // IRQ export fn __aa64_el1_irq_handler(frame: *ExceptionFrame) callconv(.C) void { - commonIrqHandler(frame); + common_irq_handler(frame); } export fn __aa64_el1_fiq_handler(frame: *ExceptionFrame) callconv(.C) void { @@ -88,7 +88,7 @@ export fn __aa64_el0_sync_handler(frame: *ExceptionFrame) callconv(.C) void { } export fn __aa64_el0_irq_handler(frame: *ExceptionFrame) callconv(.C) void { - commonIrqHandler(frame); + common_irq_handler(frame); } export fn __aa64_el0_fiq_handler(frame: *ExceptionFrame) callconv(.C) void { diff --git a/src/arch/aarch64/regs.zig b/src/arch/aarch64/regs.zig index 48e8e2f..48ac49d 100644 --- a/src/arch/aarch64/regs.zig +++ b/src/arch/aarch64/regs.zig @@ -67,7 +67,7 @@ pub const ESR_EL1 = Register("esr_el1", packed struct(u64) { sp_align = 0b100110, _, - pub fn asStr(self: @This()) []const u8 { + pub fn as_str(self: @This()) []const u8 { return std.enums.tagName(@This(), self) orelse ""; } } = .unknown, @@ -94,7 +94,7 @@ pub const ESR_EL1 = Register("esr_el1", packed struct(u64) { permission_fault_l3 = 0b001111, _, - pub fn asStr(self: @This()) []const u8 { + pub fn as_str(self: @This()) []const u8 { return std.enums.tagName(@This(), self) orelse ""; } } = .address_size_fault_l0, @@ -134,7 +134,7 @@ pub const ESR_EL1 = Register("esr_el1", packed struct(u64) { other, }; - pub fn asEnum(self: @This()) AsEnum { + pub fn as_enum(self: @This()) AsEnum { switch (self.EC) { .data_abort_lower_el, .data_abort_same_el => return .{ .data_abort = @bitCast(self.ISS) }, else => return .other, diff --git a/src/arch/aarch64/vmm.zig b/src/arch/aarch64/vmm.zig index 933104a..f66c557 100644 --- a/src/arch/aarch64/vmm.zig +++ b/src/arch/aarch64/vmm.zig @@ -47,7 +47,7 @@ pub const RawEntry = packed struct(u64) { // 55..64 _2: u9 = 0, - pub fn makeUnion(self: @This(), other: @This()) @This() { + pub fn make_union(self: @This(), other: @This()) @This() { const lhs = @as(u64, @bitCast(self)); const rhs = @as(u64, @bitCast(other)); return @as(@This(), @bitCast(lhs | rhs)); @@ -81,7 +81,7 @@ pub fn TableEntry(comptime Level: type) type { pub fn normal_page(addr: PhysicalAddress, flags: RawEntry) @This() { return .{ - .raw = flags.makeUnion(RawEntry{ + .raw = flags.make_union(RawEntry{ .PPN = @as(u36, @intCast(addr.raw >> 12)), .V = true, .P = true, @@ -94,7 +94,7 @@ pub fn TableEntry(comptime Level: type) type { pub fn device_page(addr: PhysicalAddress, flags: RawEntry) @This() { return .{ - .raw = flags.makeUnion(RawEntry{ + .raw = flags.make_union(RawEntry{ .PPN = @as(u36, @intCast(addr.raw >> 12)), .V = true, .P = true, @@ -109,7 +109,7 @@ pub fn TableEntry(comptime Level: type) type { pub fn normal_block(addr: PhysicalAddress, flags: RawEntry) @This() { return .{ - .raw = flags.makeUnion(RawEntry{ + .raw = flags.make_union(RawEntry{ .PPN = @as(u36, @intCast(addr.raw >> 12)), .V = true, .AF = true, @@ -121,7 +121,7 @@ pub fn TableEntry(comptime Level: type) type { pub fn table(addr: PhysicalAddress, flags: RawEntry) @This() { return .{ - .raw = flags.makeUnion(.{ + .raw = flags.make_union(.{ .PPN = @as(u36, @intCast(addr.raw >> 12)), .V = true, .P = true, @@ -144,16 +144,16 @@ pub fn Table(comptime Level: type) type { } // 0x0000_0000_0000_0000 .. 0x0000_0080_0000_0000 -var gFixedLow = Table(L1){}; +var g_fixed_low = Table(L1){}; // 0xFFFF_FF80_0000_0000 .. 0xFFFF_FFFF_FFFF_FFFF -var gFixedHigh = Table(L1){}; +var g_fixed_high = Table(L1){}; -pub fn mapEarly(realAddress: usize) void { - _ = realAddress; +pub fn map_early(real_address: usize) void { + _ = real_address; for (0..16) |i| { // Identity - gFixedLow.entry(i).* = TableEntry(L1).normal_block( + g_fixed_low.entry(i).* = TableEntry(L1).normal_block( .{ .raw = i << L1.SHIFT }, .{}, ); @@ -161,14 +161,14 @@ pub fn mapEarly(realAddress: usize) void { for (0..16) |i| { // Identity + KERNEL_VIRTUAL_BASE - gFixedHigh.entry(i).* = TableEntry(L1).normal_block( + g_fixed_high.entry(i).* = TableEntry(L1).normal_block( .{ .raw = i << L1.SHIFT }, .{}, ); } - const ttbr0 = @intFromPtr(&gFixedLow); - const ttbr1 = @intFromPtr(&gFixedHigh); + const ttbr0 = @intFromPtr(&g_fixed_low); + const ttbr1 = @intFromPtr(&g_fixed_high); regs.TTBR0_EL1.set(ttbr0); regs.TTBR1_EL1.set(ttbr1); diff --git a/src/arch/riscv64.zig b/src/arch/riscv64.zig index 0535021..f8e8595 100644 --- a/src/arch/riscv64.zig +++ b/src/arch/riscv64.zig @@ -8,18 +8,18 @@ const builtin = @import("builtin"); const Arena = @import("../arena.zig").Arena; -export const _ = boot.rv64BspLowerEntry; +export const _ = boot.rv64_bsp_lower_entry; extern fn __rv64_enter_task(cx: *Context) callconv(.C) noreturn; extern fn __rv64_switch_task(dcx: *Context, scx: *Context) callconv(.C) void; extern fn __rv64_task_enter_kernel() callconv(.C) noreturn; -fn idleFunction() callconv(.naked) noreturn { +fn idle_function() callconv(.naked) noreturn { asm volatile ("j ."); } /// This CPU's HART (HARdware Thread) ID. -pub threadlocal var tHartId: u32 = 0; +pub threadlocal var t_hart_id: u32 = 0; /// RISC-V task context pub const Context = extern struct { @@ -30,7 +30,7 @@ pub const Context = extern struct { /// Constructs an idle context struct. pub fn idle() @This() { - const entry = @intFromPtr(&idleFunction); + const entry = @intFromPtr(&idle_function); return Context.kernel(entry, 0); } @@ -66,20 +66,20 @@ pub const Context = extern struct { } /// Low-level task context switch function. - pub fn switchFrom(self: *@This(), from: *@This()) void { + pub fn switch_from(self: *@This(), from: *@This()) void { __rv64_switch_task(self, from); } }; pub inline fn halt() noreturn { while (true) { - _ = setInterruptMask(true); - waitForInterrupt(); + _ = set_interrupt_mask(true); + wait_for_interrupt(); } } -pub inline fn setInterruptMask(mask: bool) bool { - const old = interruptMask(); +pub inline fn set_interrupt_mask(mask: bool) bool { + const old = interrupt_mask(); if (mask) { regs.SSTATUS.modify(.{}, .{ .SIE = true }); } else { @@ -88,15 +88,15 @@ pub inline fn setInterruptMask(mask: bool) bool { return old; } -pub fn interruptMask() bool { +pub fn interrupt_mask() bool { return regs.SSTATUS.read().SIE; } -pub inline fn waitForInterrupt() void { +pub inline fn wait_for_interrupt() void { asm volatile ("wfi"); } -pub inline fn spinHint() void { +pub inline fn spin_hint() void { // Don't want to explicitly enable Zihintpause ext, so just paste this as raw opcode asm volatile (".word 0x0100000f"); } @@ -117,7 +117,7 @@ pub inline fn barrier(comptime ordering: std.builtin.AtomicOrder) void { asm volatile ("" ::: "memory"); } -pub inline fn setThreadPointer(tp: usize) void { +pub inline fn set_thread_pointer(tp: usize) void { asm volatile ("mv tp, %[tp]" : : [tp] "r" (tp), diff --git a/src/arch/riscv64/boot.zig b/src/arch/riscv64/boot.zig index fa65899..02f2111 100644 --- a/src/arch/riscv64/boot.zig +++ b/src/arch/riscv64/boot.zig @@ -8,65 +8,66 @@ const mem = @import("../../mem.zig"); const arena = @import("../../arena.zig"); const exception = @import("exception.zig"); -const physMemory = mem.phys; +const phys_memory = mem.phys; const PAGE_SIZE = mem.vmm.PAGE_SIZE; const log = debug.log; const arch = kernel.arch; extern const __rv64_bsp_stack_top: u8; -var gDtbAddress: usize = 0; -var gBspHartId: u32 = 0; +var g_dtb_address: usize = 0; +var g_bsp_hart_id: u32 = 0; -fn bspUpperEntry(realAddress: usize, unused: usize) callconv(.C) noreturn { +fn bsp_upper_entry(real_address: usize, unused: usize) callconv(.C) noreturn { _ = unused; arch.barrier(.acq_rel); // Relocate the kernel yet again, this time to another base - const relaStart = @intFromPtr(&__rela_start); - const relaEnd = @intFromPtr(&__rela_end); - const relOffset = vmm.KERNEL_VIRTUAL_BASE + vmm.L1.offset(realAddress); + const rela_start = @intFromPtr(&__rela_start); + const rela_end = @intFromPtr(&__rela_end); + const rel_offset = vmm.KERNEL_VIRTUAL_BASE + vmm.L1.offset(real_address); arch.barrier(.acq_rel); - rv64RelocateKernel(relOffset, relaStart, relaEnd); - vmm.unmapEarly(); + rv64_relocate_kernel(rel_offset, rela_start, rela_end); + vmm.unmap_early(); // Setup exception handling exception.init(); - debug.log.setWriteFn(&sbi.debugPrintByte); - kernel.mem.PhysicalAddress.gVirtualizeBase = 0; - kernel.mem.PhysicalAddress.gVirtualizeSize = vmm.virtualizeRange(); + debug.log.set_write_fn(&sbi.debug_print_byte); + kernel.mem.PhysicalAddress.g_virtualize_base = 0; + kernel.mem.PhysicalAddress.g_virtualize_size = vmm.virtualize_range(); // Setup physical memory management - setupMemoryFromFdt(realAddress); + setup_memory_from_fdt(real_address); - setupPerCpu(); - arch.tHartId = gBspHartId; + setup_per_cpu(); + arch.impl.t_hart_id = g_bsp_hart_id; kernel.kernel_main(); } -pub export fn rv64BspLowerEntry(realAddress: usize, bspHartId: usize, dtbAddress: usize) callconv(.C) noreturn { - debug.log.setWriteFn(&sbi.debugPrintByte); +pub export fn rv64_bsp_lower_entry(real_address: usize, bsp_hart_id: usize, dtb_address: usize) callconv(.C) noreturn { + debug.log.set_write_fn(&sbi.debug_print_byte); - gDtbAddress = dtbAddress; - gBspHartId = @truncate(bspHartId); + g_dtb_address = dtb_address; + g_bsp_hart_id = @truncate(bsp_hart_id); - vmm.mapEarly(realAddress); + vmm.map_early(real_address); // &bspUpperEntry will yield a pointer like: X + P, where // * X is symbol's raw address, // * P is the physical load base of the image (0x80200000 on rv64 usually) // // Relocate the address to point to Y + P, where Y is the virtual load base - // const kernelL1Offset = realAddress & ((1 << 30) - 1); - const realAddressL1Offset = vmm.L1.offset(realAddress); - const virtualEntry = @intFromPtr(&bspUpperEntry) + vmm.KERNEL_VIRTUAL_BASE - realAddress + realAddressL1Offset; - const virtualSp = @intFromPtr(&__rv64_bsp_stack_top) + vmm.KERNEL_VIRTUAL_BASE - realAddress + realAddressL1Offset; + const real_address_l1_offset = vmm.L1.offset(real_address); + const virtual_entry = @intFromPtr(&bsp_upper_entry) + vmm.KERNEL_VIRTUAL_BASE // + - real_address + real_address_l1_offset; + const virtual_sp = @intFromPtr(&__rv64_bsp_stack_top) + vmm.KERNEL_VIRTUAL_BASE // + - real_address + real_address_l1_offset; - longJump(virtualEntry, virtualSp, realAddress, 0); + long_jump(virtual_entry, virtual_sp, real_address, 0); arch.halt(); } @@ -82,43 +83,43 @@ extern var __tbss_end: u8; extern var __kernel_start: u8; extern var __kernel_end: u8; -fn setupPerCpu() void { +fn setup_per_cpu() void { // Assume .tbss follows .tdata - const tdataStart = @intFromPtr(&__tdata_start); - const tdataEnd = @intFromPtr(&__tdata_end); - const tdataSize = tdataEnd - tdataStart; - const tbssStart = @intFromPtr(&__tbss_start); - const tbssEnd = @intFromPtr(&__tbss_end); - const tbssSize = tbssEnd - tbssStart; + const tdata_start = @intFromPtr(&__tdata_start); + const tdata_end = @intFromPtr(&__tdata_end); + const tdata_size = tdata_end - tdata_start; + const tbss_start = @intFromPtr(&__tbss_start); + const tbss_end = @intFromPtr(&__tbss_end); + const tbss_size = tbss_end - tbss_start; - const tdataData = @as([*]u8, @ptrFromInt(tdataStart))[0..tdataSize]; + const tdata_data = @as([*]u8, @ptrFromInt(tdata_start))[0..tdata_size]; - const tlsSize = tdataSize + tbssSize; - const tlsPageCount = (tlsSize + PAGE_SIZE - 1) / PAGE_SIZE; + const tls_size = tdata_size + tbss_size; + const tls_page_count = (tls_size + PAGE_SIZE - 1) / PAGE_SIZE; // Variant I: TLS block 0 follows TP after a certain displacement - const tlsAddress = physMemory.alloc_pages(tlsPageCount).?.virtualize(); - const tlsData = @as([*]u8, @ptrFromInt(tlsAddress))[0..tlsSize]; + const tls_address = phys_memory.alloc_pages(tls_page_count).?.virtualize(); + const tls_data = @as([*]u8, @ptrFromInt(tls_address))[0..tls_size]; - log.info("Allocated TLS @ {*}", .{tlsData}); + log.info("Allocated TLS @ {*}", .{tls_data}); - @memcpy(tlsData[0..tdataSize], tdataData); - @memset(tlsData[tdataSize..], 0); + @memcpy(tls_data[0..tdata_size], tdata_data); + @memset(tls_data[tdata_size..], 0); - arch.setThreadPointer(tlsAddress); + arch.set_thread_pointer(tls_address); } -export fn rv64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) void { +export fn rv64_relocate_kernel(image_base: usize, rela_start: usize, rela_end: usize) void { const elf = @import("std").elf; - const relaTablePtr = @as([*]elf.Rela, @ptrFromInt(relaStart)); - const relaCount = (relaEnd - relaStart) / @sizeOf(elf.Rela); - const relaTable = relaTablePtr[0..relaCount]; - for (relaTable) |entry| { - const relaType: elf.R_RISCV = @enumFromInt(entry.r_type()); - switch (relaType) { + const rela_table_ptr = @as([*]elf.Rela, @ptrFromInt(rela_start)); + const rela_count = (rela_end - rela_start) / @sizeOf(elf.Rela); + const rela_table = rela_table_ptr[0..rela_count]; + for (rela_table) |entry| { + const rela_type: elf.R_RISCV = @enumFromInt(entry.r_type()); + switch (rela_type) { .RELATIVE => { - const value = @as(*isize, @ptrFromInt(imageBase + entry.r_offset)); - value.* = @as(isize, @bitCast(imageBase)) + entry.r_addend; + const value = @as(*isize, @ptrFromInt(image_base + entry.r_offset)); + value.* = @as(isize, @bitCast(image_base)) + entry.r_addend; }, else => { arch.halt(); @@ -127,22 +128,27 @@ export fn rv64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) } } -fn setupMemoryFromFdt(realAddress: usize) void { - const kernelStart = @intFromPtr(&__kernel_start); - const kernelEnd = @intFromPtr(&__kernel_end); +fn setup_memory_from_fdt(real_address: usize) void { + const kernel_start = @intFromPtr(&__kernel_start); + const kernel_end = @intFromPtr(&__kernel_end); - const fdt = dtb.Fdt.fromPhysicalAddress(.{ .raw = gDtbAddress }) catch |err| { + const fdt = dtb.Fdt.from_physical_address(.{ .raw = g_dtb_address }) catch |err| { log.panic("Cannot initialize raw DTB: {}", .{err}); }; - fdt.addPhysicalMemoryToSystem(); + fdt.add_physical_memory_to_system(); - physMemory.addReservedRegion("kernel", kernelStart - (vmm.KERNEL_VIRTUAL_BASE + vmm.L1.offset(realAddress)) + realAddress, kernelEnd - kernelStart); - physMemory.addReservedRegion("fdt", gDtbAddress, vmm.L3.align_up(fdt.bytes.len)); + phys_memory.add_reserved_region( + "kernel", + kernel_start - + (vmm.KERNEL_VIRTUAL_BASE + vmm.L1.offset(real_address)) + real_address, + kernel_end - kernel_start, + ); + phys_memory.add_reserved_region("fdt", g_dtb_address, vmm.L3.align_up(fdt.bytes.len)); - physMemory.init(); + phys_memory.init(); } -inline fn longJump(pc: usize, sp: usize, a0: usize, a1: usize) noreturn { +inline fn long_jump(pc: usize, sp: usize, a0: usize, a1: usize) noreturn { asm volatile ( \\ mv sp, %[sp] \\ jr %[pc] diff --git a/src/arch/riscv64/entry.S b/src/arch/riscv64/entry.S index dea208c..394f56d 100644 --- a/src/arch/riscv64/entry.S +++ b/src/arch/riscv64/entry.S @@ -1,5 +1,5 @@ -.set ENTRY_SYMBOL, rv64BspLowerEntry -.set RELOC_SYMBOL, rv64RelocateKernel +.set ENTRY_SYMBOL, rv64_bsp_lower_entry +.set RELOC_SYMBOL, rv64_relocate_kernel .global __rv64_entry .global __rv64_bsp_stack_top diff --git a/src/arch/riscv64/sbi.zig b/src/arch/riscv64/sbi.zig index 67af8eb..4d52335 100644 --- a/src/arch/riscv64/sbi.zig +++ b/src/arch/riscv64/sbi.zig @@ -27,7 +27,7 @@ const SbiResult = union(enum) { ok: u64, err: SbiError, - fn fromSbi(a0: u64, a1: u64) SbiResult { + fn from_sbi(a0: u64, a1: u64) SbiResult { if (a0 == 0) { return .{ .ok = a1 }; } else { @@ -36,7 +36,7 @@ const SbiResult = union(enum) { } }; -fn sbiCall1(ext: SbiExtension, func: u64, arg0: u64) SbiResult { +fn sbi_call1(ext: SbiExtension, func: u64, arg0: u64) SbiResult { var a0: u64 = undefined; var a1: u64 = undefined; asm volatile ("ecall" @@ -47,9 +47,9 @@ fn sbiCall1(ext: SbiExtension, func: u64, arg0: u64) SbiResult { [extn] "{a7}" (ext), : "a2", "a3", "a4", "a5" ); - return SbiResult.fromSbi(a0, a1); + return SbiResult.from_sbi(a0, a1); } -pub fn debugPrintByte(byte: u8) void { - _ = sbiCall1(.dbcn, 0x02, @as(u64, byte)); +pub fn debug_print_byte(byte: u8) void { + _ = sbi_call1(.dbcn, 0x02, @as(u64, byte)); } diff --git a/src/arch/riscv64/vmm.zig b/src/arch/riscv64/vmm.zig index 4889600..59a34bb 100644 --- a/src/arch/riscv64/vmm.zig +++ b/src/arch/riscv64/vmm.zig @@ -38,7 +38,7 @@ pub const RawEntry = packed struct(u64) { // 49..64: Unused bits _pad1: u15 = 0, - pub fn makeUnion(self: @This(), other: @This()) @This() { + pub fn make_union(self: @This(), other: @This()) @This() { const lhs = @as(u64, @bitCast(self)); const rhs = @as(u64, @bitCast(other)); return @as(@This(), @bitCast(lhs | rhs)); @@ -72,7 +72,7 @@ pub fn TableEntry(comptime Level: type) type { pub fn page(addr: PhysicalAddress, flags: RawEntry) @This() { return .{ - .raw = flags.makeUnion(.{ + .raw = flags.make_union(.{ .address = @as(u39, @intCast(addr.raw >> 12)), .r = true, .v = true, @@ -84,7 +84,7 @@ pub fn TableEntry(comptime Level: type) type { pub fn table(addr: PhysicalAddress, flags: RawEntry) @This() { flags.clear(.{ .r = true, .w = true, .x = true }); - return .{ .raw = flags.makeUnion(.{ + return .{ .raw = flags.make_union(.{ .address = @as(u39, @intCast(addr.raw >> 12)), .v = true, }) }; @@ -108,37 +108,43 @@ pub fn Table(comptime Level: type) type { }; } -var gFixed = Table(L1).empty(); -var gFixedLock: sync.IrqSafeSpinlock = .{}; +var g_fixed = Table(L1).empty(); +var g_fixed_lock: sync.Spinlock = .{}; -pub fn virtualizeRange() usize { +pub fn virtualize_range() usize { return EARLY_MAPPING_SIZE * L1.SIZE; } -pub fn unmapEarly() void { +pub fn unmap_early() void { // Make lower half mappings non-executable - gFixedLock.lock(); - defer gFixedLock.release(); + const guard = g_fixed_lock.lock_irqsave(); + defer guard.release(); for (0..EARLY_MAPPING_SIZE) |i| { - gFixed.entry(i).* = .page( + g_fixed.entry(i).* = .page( .{ .raw = L1.address(i) }, .{ .r = true, .w = true }, ); } } -pub fn mapEarly(realAddress: usize) void { - const realL1 = L1.index(realAddress); +pub fn map_early(real_address: usize) void { + const real_l1 = L1.index(real_address); // Identity map first 16GiB of memory for (0..EARLY_MAPPING_SIZE) |i| { - gFixed.entry(i).* = .page(.{ .raw = L1.address(i) }, .{ .r = true, .w = true, .x = true }); + g_fixed.entry(i).* = .page( + .{ .raw = L1.address(i) }, + .{ .r = true, .w = true, .x = true }, + ); } // Map 1GiB at KERNEL_VIRTUAL_BASE -> physical 1GiB where the kernel is loaded - gFixed.entry(KERNEL_VIRTUAL_L1I).* = .page(.{ .raw = L1.address(realL1) }, .{ .r = true, .w = true, .x = true }); + g_fixed.entry(KERNEL_VIRTUAL_L1I).* = .page( + .{ .raw = L1.address(real_l1) }, + .{ .r = true, .w = true, .x = true }, + ); - const address = @as(usize, @intFromPtr(&gFixed)); + const address = @as(usize, @intFromPtr(&g_fixed)); regs.SATP.write(.{ .PPN = @intCast(address >> 12), .MODE = .sv39 }); } diff --git a/src/arena.zig b/src/arena.zig index ad741a9..6ea0228 100644 --- a/src/arena.zig +++ b/src/arena.zig @@ -1,12 +1,12 @@ //! Simple bump allocator arena. -const physMemory = @import("mem/phys.zig"); +const phys_memory = @import("mem/phys.zig"); const log = @import("debug.zig").log; const mem = @import("mem.zig"); /// Bump allocator implementation. pub const Arena = struct { - physBase: mem.PhysicalAddress, + phys_base: mem.PhysicalAddress, capacity: usize, len: usize, @@ -14,8 +14,8 @@ pub const Arena = struct { /// /// Requires initialized physical memory management. pub fn init(cap: usize) ?Arena { - const physBase = physMemory.alloc_pages(cap / mem.vmm.PAGE_SIZE) orelse return null; - return .{ .physBase = physBase, .capacity = cap, .len = 0 }; + const phys_base = phys_memory.alloc_pages(cap / mem.vmm.PAGE_SIZE) orelse return null; + return .{ .phys_base = phys_base, .capacity = cap, .len = 0 }; } /// Allocates an object of type `T` within this arena. @@ -28,7 +28,7 @@ pub const Arena = struct { log.panic("Out of memory. Cannot allocate {} bytes", .{@sizeOf(T)}); } - const v = self.physBase.add(self.len).virtualize(); + const v = self.phys_base.add(self.len).virtualize(); const ptr = @as(*T, @ptrFromInt(v)); self.len += @sizeOf(T); diff --git a/src/debug.zig b/src/debug.zig index 3e61077..952f9a3 100644 --- a/src/debug.zig +++ b/src/debug.zig @@ -2,7 +2,7 @@ const std = @import("std"); -fn dummyWrite(_: u8) void {} +fn dummy_write(_: u8) void {} /// The main method of kernel logging. pub const log = struct { @@ -18,20 +18,20 @@ pub const log = struct { err, }; - var writeFn: *const fn (u8) void = dummyWrite; - const writer: std.io.GenericWriter(u0, error{}, writeWrapperFn) = .{ .context = 0 }; + var write_fn: *const fn (u8) void = dummy_write; + const writer: std.io.GenericWriter(u0, error{}, write_wrapper_fn) = .{ .context = 0 }; - fn writeWrapperFn(context: u0, data: []const u8) error{}!usize { + fn write_wrapper_fn(context: u0, data: []const u8) error{}!usize { _ = context; for (data) |byte| { - writeFn(byte); + write_fn(byte); } return data.len; } /// Replaces the function to print debug bytes with a new one. - pub fn setWriteFn(f: *const fn (u8) void) void { - writeFn = f; + pub fn set_write_fn(f: *const fn (u8) void) void { + write_fn = f; } /// Emit an `info`-level log record. @@ -55,8 +55,8 @@ pub const log = struct { } /// Write raw byte data into the debugging output. - pub fn writeRaw(data: []const u8) void { - _ = writeWrapperFn(0, data) catch return; + pub fn write_waw(data: []const u8) void { + _ = write_wrapper_fn(0, data) catch return; } /// Write a formatted string (without logging prefix/suffix/newline) into the debugging output. @@ -66,8 +66,8 @@ pub const log = struct { /// Write a formatted log record into the debugging output. pub fn writeln(comptime level: Level, comptime format: []const u8, args: anytype) void { - const prefix = comptime logPrefix(level); - const suffix = comptime logSuffix(level); + const prefix = comptime log_prefix(level); + const suffix = comptime log_suffix(level); writer.print(prefix ++ format ++ suffix ++ "\r\n", args) catch return; } @@ -83,7 +83,7 @@ pub const log = struct { @panic("Explicit kernel panic"); } - fn logPrefix(comptime level: Level) []const u8 { + fn log_prefix(comptime level: Level) []const u8 { switch (level) { .debug => return "", .info => return "\x1B[1;36m", @@ -91,7 +91,7 @@ pub const log = struct { .err => return "\x1B[1;31m", } } - fn logSuffix(comptime level: Level) []const u8 { + fn log_suffix(comptime level: Level) []const u8 { if (level == .debug) { return ""; } else { diff --git a/src/kernel.zig b/src/kernel.zig index 62e8fd0..58e5375 100644 --- a/src/kernel.zig +++ b/src/kernel.zig @@ -40,7 +40,7 @@ noinline fn f1(arg: usize, c: usize) void { pub export fn kernel_main() callconv(.C) noreturn { log.write("\x1B[2J", .{}); var a = arena.Arena.init(256 * 0x1000) orelse @panic("Could not setup kernel arena"); - thread.Queue.initThisCpu(&a); + thread.Queue.init_this_cpu(&a); const pc = @intFromPtr(&f0); for (0..4) |i| { diff --git a/src/mem.zig b/src/mem.zig index 2cb4db1..822ff23 100644 --- a/src/mem.zig +++ b/src/mem.zig @@ -15,9 +15,9 @@ pub const PhysicalAddress = packed struct(u64) { pub const NULL: @This() = .{ .raw = 0 }; /// Base address to add to a given `PhysicalAddress` in order to "virtualize" it. - pub var gVirtualizeBase: usize = 0; + pub var g_virtualize_base: usize = 0; /// Maximum `PhysicalAddress` that can be represented as a virtual address. - pub var gVirtualizeSize: usize = 0; + pub var g_virtualize_size: usize = 0; /// Adds an `offset` to this `PhysicalAddress` pub fn add(self: @This(), offset: usize) @This() { @@ -32,11 +32,11 @@ pub const PhysicalAddress = packed struct(u64) { /// Panics if the physical address points to a memory that cannot be represented by a virtual /// address. pub fn virtualize(self: @This()) usize { - if (self.raw > gVirtualizeSize) { + if (self.raw > g_virtualize_size) { @panic("Physical address out of virtualize bounds"); } - return self.raw + gVirtualizeBase; + return self.raw + g_virtualize_base; } /// "De-virtualizes" a previously "virtualized" physical address by mapping it back into its @@ -46,17 +46,17 @@ pub const PhysicalAddress = packed struct(u64) { /// /// Panics if the virtual address provided is outside of virtualizable memory range. pub fn from_virtualized(virt: usize) @This() { - if ((virt < gVirtualizeBase) || (virt - gVirtualizeBase > gVirtualizeSize)) { + if ((virt < g_virtualize_base) || (virt - g_virtualize_base > g_virtualize_size)) { @panic("Invalid virtualized physical address"); } - return .{ .raw = virt - gVirtualizeBase }; + return .{ .raw = virt - g_virtualize_base }; } }; /// Helper function to format a byte quantity into a human-readable size. /// Writes its result to the `buffer` provided and returns a pointer to it. -pub fn formatSize(buffer: []u8, size: u64) []const u8 { +pub fn format_size(buffer: []u8, size: u64) []const u8 { const KIBI: u64 = 1024; const MIBI: u64 = KIBI * 1024; const GIBI: u64 = MIBI * 1024; @@ -73,20 +73,20 @@ pub fn formatSize(buffer: []u8, size: u64) []const u8 { const integer = size / div; const dot = size >= 1024; - const iLen = std.fmt.formatIntBuf(buffer, integer, 10, .lower, .{}); - var len = iLen; - var fLen: usize = 0; + const ilen = std.fmt.formatIntBuf(buffer, integer, 10, .lower, .{}); + var len = ilen; + var flen: usize = 0; if (dot and integer < 100) { const fractional = (((size * 1000) / div) % 1000) / 10; - if (iLen < buffer.len + 1) { - buffer[iLen] = '.'; - fLen = 1 + std.fmt.formatIntBuf(buffer[iLen + 1 ..], fractional, 10, .lower, .{ .fill = '0', .width = 2 }); + if (ilen < buffer.len + 1) { + buffer[ilen] = '.'; + flen = 1 + std.fmt.formatIntBuf(buffer[ilen + 1 ..], fractional, 10, .lower, .{ .fill = '0', .width = 2 }); } } - len += fLen; + len += flen; if (len + suffix.len < buffer.len) { std.mem.copyForwards(u8, buffer[len..], suffix); diff --git a/src/mem/phys.zig b/src/mem/phys.zig index 91b8678..d552b54 100644 --- a/src/mem/phys.zig +++ b/src/mem/phys.zig @@ -26,38 +26,38 @@ pub const Page = extern struct { unused: [3]u32 = undefined, /// Returns `true` if the page is allocated/used. - pub fn isUsed(self: *const @This()) bool { + pub fn is_used(self: *const @This()) bool { return self.refcount != 0; } - fn makeAvailable(self: *@This()) void { + fn make_available(self: *@This()) void { self.refcount = 0; } - fn makeReserved(self: *@This()) void { + fn make_reserved(self: *@This()) void { self.refcount = std.math.maxInt(u32); } }; const PhysicalMemoryManager = struct { - pageArray: []Page, + page_array: []Page, offset: u64 = 0, - lastFree: usize = 0, + last_free: usize = 0, const RECORDS_PER_PAGE: usize = vmm.PAGE_SIZE / @sizeOf(Page); fn alloc_page(self: *@This()) ?mem.PhysicalAddress { - for (self.lastFree..self.pageArray.len) |i| { - if (self.pageArray[i].refcount == 0) { - self.pageArray[i].refcount += 1; - self.lastFree = (i + 1) % self.pageArray.len; + for (self.last_free..self.page_array.len) |i| { + if (self.page_array[i].refcount == 0) { + self.page_array[i].refcount += 1; + self.last_free = (i + 1) % self.page_array.len; return .{ .raw = self.offset + i * vmm.PAGE_SIZE }; } } - for (0..self.lastFree) |i| { - if (self.pageArray[i].refcount == 0) { - self.pageArray[i].refcount += 1; - self.lastFree = (i + 1) % self.pageArray.len; + for (0..self.last_free) |i| { + if (self.page_array[i].refcount == 0) { + self.page_array[i].refcount += 1; + self.last_free = (i + 1) % self.page_array.len; return .{ .raw = self.offset + i * vmm.PAGE_SIZE }; } } @@ -65,19 +65,19 @@ const PhysicalMemoryManager = struct { } fn alloc_pages(self: *@This(), count: usize) ?mem.PhysicalAddress { - if (self.lastFree + count < self.pageArray.len) { - if (self.alloc_from(self.lastFree, self.pageArray.len, count)) |p| { + if (self.last_free + count < self.page_array.len) { + if (self.alloc_from(self.last_free, self.page_array.len, count)) |p| { return p; } } - return self.alloc_from(0, self.lastFree, count); + return self.alloc_from(0, self.last_free, count); } fn alloc_from(self: *@This(), start: usize, end: usize, count: usize) ?mem.PhysicalAddress { for (start..end) |i| { var taken = false; for (0..count) |j| { - if (self.pageArray[i + j].isUsed()) { + if (self.page_array[i + j].is_used()) { taken = true; break; } @@ -85,7 +85,7 @@ const PhysicalMemoryManager = struct { if (!taken) { for (0..count) |j| { - self.pageArray[i + j].refcount = 1; + self.page_array[i + j].refcount = 1; } return .{ .raw = self.offset + i * vmm.PAGE_SIZE }; } @@ -99,7 +99,7 @@ const PhysicalMemoryManager = struct { log.panic("free_page: invalid page 0x{x}: outside of the allocation range", .{page.raw}); } const index = (page.raw - self.offset) / vmm.PAGE_SIZE; - if (index >= self.pageArray.len) { + if (index >= self.page_array.len) { log.panic("free_page: invalid page 0x{x}: outside of the allocation range", .{page.raw}); } return index; @@ -107,34 +107,35 @@ const PhysicalMemoryManager = struct { fn free_page(self: *@This(), page: mem.PhysicalAddress) void { const index = self.valid_index(page); - if (self.pageArray[index].refcount == 0) { + if (self.page_array[index].refcount == 0) { log.panic("free_page: double free of page 0x{x} detected", .{page.raw}); } - self.pageArray[index].refcount -= 1; - if (self.pageArray[index].refcount == 0) { - self.lastFree = index; + self.page_array[index].refcount -= 1; + if (self.page_array[index].refcount == 0) { + self.last_free = index; } } fn get_page(self: *@This(), page: mem.PhysicalAddress) *Page { const index = self.valid_index(page); - return &self.pageArray[index]; + return &self.page_array[index]; } }; -var gMemoryRegions: std.BoundedArray(MemoryRegion, 16) = .{}; -var gReservedRegions: std.BoundedArray(MemoryRegion, 16) = .{}; -var gPhysicalMemoryLock = Spinlock{}; -var gPhysicalMemory = PhysicalMemoryManager{ .pageArray = undefined }; +var g_memory_regions: std.BoundedArray(MemoryRegion, 16) = .{}; +var g_reserved_regions: std.BoundedArray(MemoryRegion, 16) = .{}; +var g_physical_memory_lock = Spinlock{}; +var g_physical_memory = PhysicalMemoryManager{ .page_array = undefined }; /// Adds an available memory region to the list. /// /// # Note /// /// Only meaningful to call before calling `init()`. -pub fn addMemoryRegion(name: []const u8, base: u64, size: u64) void { +pub fn add_memory_region(name: []const u8, base: u64, size: u64) void { log.info("Memory: '{s}', base 0x{x}, size 0x{x}", .{ name, base, size }); - gMemoryRegions.append(.{ .name = name, .range = .{ .start = base, .len = size } }) catch @panic("memory regions overflow"); + g_memory_regions.append(.{ .name = name, .range = .{ .start = base, .len = size } }) // + catch @panic("memory regions overflow"); } /// Adds an reserved memory region to the list. @@ -142,14 +143,15 @@ pub fn addMemoryRegion(name: []const u8, base: u64, size: u64) void { /// # Note /// /// Only meaningful to call before calling `init()`. -pub fn addReservedRegion(name: []const u8, base: u64, size: u64) void { +pub fn add_reserved_region(name: []const u8, base: u64, size: u64) void { log.info("Reserved: '{s}', base 0x{x}, size 0x{x}", .{ name, base, size }); - gReservedRegions.append(.{ .name = name, .range = .{ .start = base, .len = size } }) catch @panic("reserved regions overflow"); + g_reserved_regions.append(.{ .name = name, .range = .{ .start = base, .len = size } }) // + catch @panic("reserved regions overflow"); } -fn isReservedIn(page: u64) ?*const MemoryRegion { - for (0..gReservedRegions.len) |i| { - const region = &gReservedRegions.buffer[i]; +fn is_reserved_in(page: u64) ?*const MemoryRegion { + for (0..g_reserved_regions.len) |i| { + const region = &g_reserved_regions.buffer[i]; if (page >= region.range.start and page < region.range.end()) { return region; } @@ -157,12 +159,12 @@ fn isReservedIn(page: u64) ?*const MemoryRegion { return null; } -fn allocFromRegion(region: *const MemoryRegion, reason: []const u8, pageCount: usize) ?u64 { +fn alloc_from_region(region: *const MemoryRegion, reason: []const u8, page_count: usize) ?u64 { var offset = @as(u64, 0); while (offset < region.range.len) { var taken: ?*const MemoryRegion = null; - for (0..pageCount) |i| { - if (isReservedIn(region.range.start + offset + i * vmm.PAGE_SIZE)) |resv| { + for (0..page_count) |i| { + if (is_reserved_in(region.range.start + offset + i * vmm.PAGE_SIZE)) |resv| { taken = resv; break; } @@ -174,17 +176,17 @@ fn allocFromRegion(region: *const MemoryRegion, reason: []const u8, pageCount: u } const base = region.range.start + offset; - addReservedRegion(reason, base, pageCount * vmm.PAGE_SIZE); + add_reserved_region(reason, base, page_count * vmm.PAGE_SIZE); return base; } return null; } -fn allocPageArray(pageCount: usize) []Page { - for (gMemoryRegions.constSlice()) |region| { - if (allocFromRegion(®ion, "page-array", pageCount)) |physAddress| { +fn alloc_page_array(page_count: usize) []Page { + for (g_memory_regions.constSlice()) |region| { + if (alloc_from_region(®ion, "page-array", page_count)) |physAddress| { const vaddr = (mem.PhysicalAddress{ .raw = physAddress }).virtualize(); - const len = pageCount * PhysicalMemoryManager.RECORDS_PER_PAGE; + const len = page_count * PhysicalMemoryManager.RECORDS_PER_PAGE; const ptr: [*]Page = @ptrFromInt(vaddr); const slice: []Page = ptr[0..len]; for (0..len) |i| { @@ -203,49 +205,49 @@ fn allocPageArray(pageCount: usize) []Page { /// Calls to `add***Region()` functions have no meaning past this point, so all the memory /// present in the system, along with memory reservations, should be added **prior** to this point. pub fn init() void { - var memoryStart: u64 = std.math.maxInt(u64); - var memoryEnd: u64 = std.math.minInt(u64); + var memory_start: u64 = std.math.maxInt(u64); + var memory_end: u64 = std.math.minInt(u64); - for (gMemoryRegions.constSlice()) |region| { - if (region.range.start < memoryStart) { - memoryStart = region.range.start; + for (g_memory_regions.constSlice()) |region| { + if (region.range.start < memory_start) { + memory_start = region.range.start; } - if (region.range.end() > memoryEnd) { - memoryEnd = region.range.end(); + if (region.range.end() > memory_end) { + memory_end = region.range.end(); } } - const memoryPages = (memoryEnd - memoryStart) / vmm.PAGE_SIZE; // == bitmap bits required - const pageArrayPages = (memoryPages + PhysicalMemoryManager.RECORDS_PER_PAGE - 1) // + const memory_pages = (memory_end - memory_start) / vmm.PAGE_SIZE; // == bitmap bits required + const page_array_pages = (memory_pages + PhysicalMemoryManager.RECORDS_PER_PAGE - 1) // / PhysicalMemoryManager.RECORDS_PER_PAGE; - const pageArray = allocPageArray(pageArrayPages); - var availablePages: usize = 0; + const page_array = alloc_page_array(page_array_pages); + var available_pages: usize = 0; - for (gMemoryRegions.constSlice()) |region| { - const offset = (region.range.start - memoryStart) / vmm.PAGE_SIZE; + for (g_memory_regions.constSlice()) |region| { + const offset = (region.range.start - memory_start) / vmm.PAGE_SIZE; for (0..region.range.len / vmm.PAGE_SIZE) |i| { - pageArray[offset + i].makeAvailable(); - availablePages += 1; + page_array[offset + i].make_available(); + available_pages += 1; } } - for (gReservedRegions.constSlice()) |region| { - const offset = (region.range.start - memoryStart) / vmm.PAGE_SIZE; + for (g_reserved_regions.constSlice()) |region| { + const offset = (region.range.start - memory_start) / vmm.PAGE_SIZE; for (0..region.range.len / vmm.PAGE_SIZE) |i| { - if (offset + i >= pageArray.len) { + if (offset + i >= page_array.len) { break; } - pageArray[offset + i].makeReserved(); - availablePages -= 1; + page_array[offset + i].make_reserved(); + available_pages -= 1; } } - var sizeFmt: [64]u8 = undefined; - const sizeFmtStr = mem.formatSize(&sizeFmt, availablePages * vmm.PAGE_SIZE); - log.info("Available memory: {s}, page array {*}", .{ sizeFmtStr, pageArray }); + var size_fmt: [64]u8 = undefined; + const size_fmt_str = mem.format_size(&size_fmt, available_pages * vmm.PAGE_SIZE); + log.info("Available memory: {s}, page array {*}", .{ size_fmt_str, page_array }); - gPhysicalMemory.pageArray = pageArray; - gPhysicalMemory.offset = memoryStart; + g_physical_memory.page_array = page_array; + g_physical_memory.offset = memory_start; } fn trace_allocation(count: usize, page: ?mem.PhysicalAddress) void { @@ -262,9 +264,9 @@ fn trace_free(page: mem.PhysicalAddress) void { /// Allocates a single 4KiB physical memory page. pub fn alloc_page() ?mem.PhysicalAddress { - const guard = gPhysicalMemoryLock.lock_irqsave(); + const guard = g_physical_memory_lock.lock_irqsave(); defer guard.release(); - const page = gPhysicalMemory.alloc_page(); + const page = g_physical_memory.alloc_page(); if (comptime kernel.TRACE_PHYSICAL_ALLOCATOR) { trace_allocation(1, page); } @@ -273,9 +275,9 @@ pub fn alloc_page() ?mem.PhysicalAddress { /// Allocates a set of `count` contiguous 4KiB pages. pub fn alloc_pages(count: usize) ?mem.PhysicalAddress { - const guard = gPhysicalMemoryLock.lock_irqsave(); + const guard = g_physical_memory_lock.lock_irqsave(); defer guard.release(); - const pages = gPhysicalMemory.alloc_pages(count); + const pages = g_physical_memory.alloc_pages(count); if (comptime kernel.TRACE_PHYSICAL_ALLOCATOR) { trace_allocation(count, pages); } @@ -293,9 +295,9 @@ pub fn free_page(page: mem.PhysicalAddress) void { if (comptime kernel.TRACE_PHYSICAL_ALLOCATOR) { trace_free(page); } - const guard = gPhysicalMemoryLock.lock_irqsave(); + const guard = g_physical_memory_lock.lock_irqsave(); defer guard.release(); - gPhysicalMemory.free_page(page); + g_physical_memory.free_page(page); } /// Returns a `Page` struct representing the given `page`. @@ -308,5 +310,5 @@ pub fn free_page(page: mem.PhysicalAddress) void { /// /// Will panic if the `page` does not represent a valid managed page. pub fn get_page(page: mem.PhysicalAddress) *Page { - return gPhysicalMemory.get_page(page); + return g_physical_memory.get_page(page); } diff --git a/src/sync.zig b/src/sync.zig index 9c96309..c1e6a64 100644 --- a/src/sync.zig +++ b/src/sync.zig @@ -9,33 +9,33 @@ pub const Spinlock = struct { const Guard = struct { lock: *Spinlock, - irqMask: bool, + irq_mask: bool, /// Releases the `Guard`, restoring the previous IRQ state and releasing the lock used /// to acquire it. pub fn release(self: @This()) void { self.lock.release(); - _ = arch.setInterruptMask(self.irqMask); + _ = arch.set_interrupt_mask(self.irq_mask); } }; /// Acquires a lock over `self`. Returns `false` if the lock is already held by someone else. - pub fn tryLock(self: *@This()) bool { + pub fn try_lock(self: *@This()) bool { return self.state.cmpxchgStrong(false, true, .acquire, .monotonic) orelse false; } /// Acquires a lock over `self`. Will block until a lock can be acquired. pub fn lock(self: *@This()) void { - while (!self.tryLock()) { - arch.spinHint(); + while (!self.try_lock()) { + arch.spin_hint(); } } /// Same as `lock()`, but additionally saves current IRQ state and masks IRQs. pub fn lock_irqsave(self: *@This()) Guard { - const irqMask = arch.setInterruptMask(true); + const irq_mask = arch.set_interrupt_mask(true); self.lock(); - return .{ .irqMask = irqMask, .lock = self }; + return .{ .irq_mask = irq_mask, .lock = self }; } /// Releases a lock over `self`. diff --git a/src/thread.zig b/src/thread.zig index b1984b2..20ad958 100644 --- a/src/thread.zig +++ b/src/thread.zig @@ -17,14 +17,14 @@ pub const Queue = struct { head: ?*Thread = null, /// Pointer to this CPU's thread queue. - pub threadlocal var thisCpu: ?*Queue = null; + pub threadlocal var t_this_cpu: ?*Queue = null; /// Sets up a thread queue for the current CPU. - pub fn initThisCpu(a: *arena.Arena) void { + pub fn init_this_cpu(a: *arena.Arena) void { const idle = arch.Context.idle(); const q = a.create(Queue); q.* = .{ .idle = idle }; - thisCpu = q; + t_this_cpu = q; } /// Enters a task on this CPU. @@ -46,19 +46,19 @@ pub const Queue = struct { // ... to thread if (next != curr) { self.current = next; - next.switchFrom(curr); + next.switch_from(curr); } } else { // ... to idle self.current = null; - self.idle.switchFrom(&curr.archContext); + self.idle.switch_from(&curr.arch_context); } } else { // Switching from idle if (self.head) |gt| { // ... to thread self.current = gt; - gt.archContext.switchFrom(&self.idle); + gt.arch_context.switch_from(&self.idle); return; } // ... back to idle @@ -85,7 +85,7 @@ pub const Thread = struct { /// Arena. allocator: *arena.Arena, /// Architecture-specific task context. - archContext: arch.Context, + arch_context: arch.Context, /// Next thread in the queue. next: ?*Thread = null, @@ -97,19 +97,19 @@ pub const Thread = struct { const thread = a.create(Thread); thread.* = .{ .allocator = a, - .archContext = arch.Context.kernel(pc, arg), + .arch_context = arch.Context.kernel(pc, arg), }; return thread; } /// Enters the thread, does not return. pub fn enter(self: *@This()) noreturn { - self.archContext.enter(); + self.arch_context.enter(); } /// Switches from `from` to `self` thread. - pub fn switchFrom(self: *@This(), from: *@This()) void { - self.archContext.switchFrom(&from.archContext); + pub fn switch_from(self: *@This(), from: *@This()) void { + self.arch_context.switch_from(&from.arch_context); } }; @@ -123,7 +123,7 @@ pub fn KStack(comptime SIZE: usize) type { /// Stack data represented as a slice of `SIZE` machine-sized words. data: *[SIZE]usize, /// Physical base address at which the stack is allocated. - physicalBase: mem.PhysicalAddress, + physical_base: mem.PhysicalAddress, /// Allocates a new kernel stack. /// @@ -131,10 +131,14 @@ pub fn KStack(comptime SIZE: usize) type { /// /// Panics on Out-of-Memory condition. TODO Fix this. pub fn create() @This() { - const physicalBase = mem.phys.alloc_pages(SIZE * @sizeOf(usize) / 0x1000) orelse @panic("OOM"); - const ptr = @as(*[SIZE]usize, @ptrFromInt(physicalBase.virtualize())); + const physical_base = mem.phys.alloc_pages(SIZE * @sizeOf(usize) / 0x1000) orelse @panic("OOM"); + const ptr = @as(*[SIZE]usize, @ptrFromInt(physical_base.virtualize())); - return .{ .data = ptr, .physicalBase = physicalBase, .sp = @ptrFromInt(@intFromPtr(&ptr[0]) + SIZE * @sizeOf(usize)) }; + return .{ + .data = ptr, + .physical_base = physical_base, + .sp = @ptrFromInt(@intFromPtr(&ptr[0]) + SIZE * @sizeOf(usize)), + }; } /// Pushes a machine-sized word onto the stack. @@ -154,15 +158,15 @@ pub fn KStack(comptime SIZE: usize) type { /// Adds a thread to some CPU queue for execution. pub fn enqueue(t: *Thread) void { - Queue.thisCpu.?.enqueue(t); + Queue.t_this_cpu.?.enqueue(t); } /// Enters thread execution on the current CPU. pub fn enter() noreturn { - Queue.thisCpu.?.enter(); + Queue.t_this_cpu.?.enter(); } /// Yields this CPU's execution to a next thread. pub fn yield() void { - Queue.thisCpu.?.yield(); + Queue.t_this_cpu.?.yield(); } diff --git a/src/util/dtb.zig b/src/util/dtb.zig index b0e7e64..52daf5b 100644 --- a/src/util/dtb.zig +++ b/src/util/dtb.zig @@ -4,7 +4,7 @@ const mem = @import("../mem.zig"); const log = @import("../debug.zig").log; const std = @import("std"); -const physMemory = mem.phys; +const phys_memory = mem.phys; const fdt_header = extern struct { magic: u32, @@ -68,13 +68,17 @@ pub const FdtNode = struct { depth: usize, /// Returns an iterator over the node's properties. - pub fn propIterator(self: *const @This()) FdtNodePropIterator { - return .{ .node = self, .tagIter = self.fdt.tagIteratorAt(self.off) }; + pub fn prop_iterator(self: *const @This()) FdtNodePropIterator { + return .{ .node = self, .tag_iter = self.fdt.tag_iterator_at(self.off) }; } /// Returns an iterator over the node's children. pub fn children(self: *const @This()) FdtNodeIterator { - return .{ .tagIter = self.fdt.tagIteratorAt(self.off), .depth = self.depth + 1, .depthLower = self.depth }; + return .{ + .tag_iter = self.fdt.tag_iterator_at(self.off), + .depth = self.depth + 1, + .depth_lower = self.depth, + }; } /// Looks up a child with given `name` within the node. @@ -90,8 +94,8 @@ pub const FdtNode = struct { /// Looks up a property with given `name` within the node. pub fn property(self: *const @This(), name: []const u8) ?FdtNodeProp { - var propIter = self.propIterator(); - while (propIter.next()) |prop| { + var prop_iter = self.prop_iterator(); + while (prop_iter.next()) |prop| { if (std.mem.eql(u8, name, prop.name)) { return prop; } @@ -110,31 +114,31 @@ pub const FdtNodeProp = struct { value: []const u8, /// Interprets the property's value as a list of strings. - pub inline fn getStringArray(self: *const @This()) FdtStringArrayIterator { + pub inline fn get_string_array(self: *const @This()) FdtStringArrayIterator { return .{ .prop = self }; } /// Interprets the property's value as a single string. - pub inline fn getString(self: *const @This()) []const u8 { - var sa = self.getStringArray(); + pub inline fn get_string(self: *const @This()) []const u8 { + var sa = self.get_string_array(); return sa.next() orelse ""; } /// Returns the length of the property in full 32-bit cells. - pub inline fn lenU32(self: *const @This()) usize { + pub inline fn len_cells(self: *const @This()) usize { return self.value.len / @sizeOf(u32); } /// Interprets the property's value as an array of 32-bit cells and returns a cell at a given /// index. - pub fn getU32(self: *const @This(), index: usize) ?u32 { - if (index >= self.lenU32()) { + pub fn get_cell(self: *const @This(), index: usize) ?u32 { + if (index >= self.len_cells()) { return null; } - return self.getU32Unchecked(index); + return self.get_cell_unchecked(index); } - fn getU32Unchecked(self: *const @This(), index: usize) u32 { + fn get_cell_unchecked(self: *const @This(), index: usize) u32 { return std.mem.bigToNative(u32, @as(*const u32, @ptrCast(@alignCast(&self.value[index * 4]))).*); } @@ -147,9 +151,9 @@ pub const FdtNodeProp = struct { /// /// * `index` parameter means a 32-bit cell index, not a tuple index. /// * Tuple length is assumed to be `@min(output.len, sizes.len)`. - pub fn readCells(self: *const @This(), index: usize, output: []u64, sizes: []const usize) bool { + pub fn read_cells(self: *const @This(), index: usize, output: []u64, sizes: []const usize) bool { const count = @min(output.len, sizes.len); - const len = self.lenU32(); + const len = self.len_cells(); var total: usize = 0; for (sizes[0..count]) |s| { total += s; @@ -159,11 +163,11 @@ pub const FdtNodeProp = struct { for (0..count) |i| { switch (sizes[i]) { 1 => { - output[i] = self.getU32Unchecked(offset); + output[i] = self.get_cell_unchecked(offset); }, 2 => { - output[i] = self.getU32Unchecked(offset + 1); - output[i] |= @as(u64, self.getU32Unchecked(offset)) << 32; + output[i] = self.get_cell_unchecked(offset + 1); + output[i] |= @as(u64, self.get_cell_unchecked(offset)) << 32; }, else => @panic("Invalid cell size"), } @@ -196,16 +200,16 @@ pub const FdtStringArrayIterator = struct { /// An iterator over available memory regions described by a device tree. pub const FdtMemoryRegionIterator = struct { - nodeIter: FdtNodeIterator, - cellSizes: [2]usize, + node_iter: FdtNodeIterator, + cell_sizes: [2]usize, pub fn next(self: *FdtMemoryRegionIterator) ?FdtMemoryRegion { - while (self.nodeIter.next()) |node| { + while (self.node_iter.next()) |node| { if (std.mem.startsWith(u8, node.name, "memory@")) { const reg = node.property("reg") orelse continue; var cells: [2]u64 = undefined; - if (reg.readCells(0, &cells, &self.cellSizes)) { + if (reg.read_cells(0, &cells, &self.cell_sizes)) { return .{ .name = node.name, .base = cells[0], @@ -222,11 +226,11 @@ pub const FdtMemoryRegionIterator = struct { /// An iterator over a device tree's node properties. pub const FdtNodePropIterator = struct { node: *const FdtNode, - tagIter: FdtTagIterator, + tag_iter: FdtTagIterator, depth: usize = 0, fn next(self: *FdtNodePropIterator) ?FdtNodeProp { - while (self.tagIter.next()) |tag| { + while (self.tag_iter.next()) |tag| { switch (tag) { .begin_node => |_| { self.depth += 1; @@ -234,7 +238,7 @@ pub const FdtNodePropIterator = struct { .nop => {}, .prop => |prop| { if (self.depth == 0) { - const name = self.node.fdt.stringAt(prop.nameoff); + const name = self.node.fdt.string_at(prop.nameoff); return .{ .node = self.node, .value = prop.data, .name = name }; } }, @@ -257,18 +261,18 @@ pub const FdtNodePropIterator = struct { /// An iterator over a device tree's nodes. pub const FdtNodeIterator = struct { - tagIter: FdtTagIterator, + tag_iter: FdtTagIterator, depth: usize = 0, - depthLower: ?usize = null, + depth_lower: ?usize = null, pub fn next(self: *FdtNodeIterator) ?FdtNode { - while (self.tagIter.next()) |tag| { + while (self.tag_iter.next()) |tag| { switch (tag) { .begin_node => |name| { self.depth += 1; return .{ - .fdt = self.tagIter.fdt, - .off = self.tagIter.off, + .fdt = self.tag_iter.fdt, + .off = self.tag_iter.off, .name = name, .depth = self.depth - 1, }; @@ -276,7 +280,7 @@ pub const FdtNodeIterator = struct { .end_node => { self.depth -= 1; - if (self.depthLower) |lower| { + if (self.depth_lower) |lower| { if (self.depth == lower) { return null; } @@ -306,10 +310,10 @@ pub const FdtTagIterator = struct { switch (tag) { .FDT_BEGIN_NODE => { - const nameCStr: [*c]const u8 = @ptrCast(self.raw[self.off..]); - const nameLength = std.mem.len(nameCStr); - const name = self.raw[self.off .. self.off + nameLength]; - self.off += (nameLength + 4) & ~@as(usize, 3); + const name_cstr: [*c]const u8 = @ptrCast(self.raw[self.off..]); + const name_length = std.mem.len(name_cstr); + const name = self.raw[self.off .. self.off + name_length]; + self.off += (name_length + 4) & ~@as(usize, 3); return .{ .begin_node = name }; }, .FDT_PROP => { @@ -355,7 +359,7 @@ pub const Fdt = struct { /// # Errors /// /// * `invalid_magic` if the address provided does not have a valid magic number in its header. - pub fn fromPhysicalAddress(phys: mem.PhysicalAddress) FdtError!@This() { + pub fn from_physical_address(phys: mem.PhysicalAddress) FdtError!@This() { const virt = phys.virtualize(); const hdr = @as(*const fdt_header, @ptrFromInt(virt)); if (std.mem.bigToNative(u32, hdr.magic) != FDT_MAGIC) { @@ -377,18 +381,18 @@ pub const Fdt = struct { } /// Returns an iterator over the device tree's raw tags. - pub fn tagIterator(self: *const @This()) FdtTagIterator { - return self.tagIteratorAt(0); + pub fn tag_iterator(self: *const @This()) FdtTagIterator { + return self.tag_iterator_at(0); } /// Returns an iterator over the device tree's raw tags at specific byte offset. - pub fn tagIteratorAt(self: *const @This(), off: usize) FdtTagIterator { + pub fn tag_iterator_at(self: *const @This(), off: usize) FdtTagIterator { return .{ .raw = self.data(), .fdt = self, .off = off }; } /// Returns an iterator over the device tree's nodes. - pub fn nodeIterator(self: *const @This()) FdtNodeIterator { - return .{ .tagIter = self.tagIterator() }; + pub fn node_iterator(self: *const @This()) FdtNodeIterator { + return .{ .tag_iter = self.tag_iterator() }; } /// Returns the root node of this device tree. @@ -397,9 +401,9 @@ pub const Fdt = struct { /// /// Panics if the device tree does not have a root node (which means the device tree blob is /// malformed and the OS shouldn't be running anyway). - pub fn rootNode(self: *const @This()) FdtNode { - var nodeIter = self.nodeIterator(); - while (nodeIter.next()) |node| { + pub fn root_node(self: *const @This()) FdtNode { + var node_iter = self.node_iterator(); + while (node_iter.next()) |node| { if (node.depth == 0 and node.name.len == 0) { return node; } @@ -408,46 +412,46 @@ pub const Fdt = struct { } /// Returns an iterator over available memory regions described by the device tree. - pub fn memoryRegionIterator(self: *const @This()) FdtMemoryRegionIterator { - const r = self.rootNode(); - const addressCells = if (r.property("#address-cells")) |o| (if (o.getU32(0)) |p| p else 1) else 1; - const sizeCells = if (r.property("#size-cells")) |o| (if (o.getU32(0)) |p| p else 1) else 1; + pub fn memory_region_iterator(self: *const @This()) FdtMemoryRegionIterator { + const r = self.root_node(); + const address_cells = if (r.property("#address-cells")) |o| (if (o.get_cell(0)) |p| p else 1) else 1; + const size_cells = if (r.property("#size-cells")) |o| (if (o.get_cell(0)) |p| p else 1) else 1; - return .{ .nodeIter = self.nodeIterator(), .cellSizes = .{ addressCells, sizeCells } }; + return .{ .node_iter = self.node_iterator(), .cell_sizes = .{ address_cells, size_cells } }; } - fn stringData(self: *const @This()) [*c]const u8 { - const offStrings = std.mem.bigToNative(u32, self.header().off_dt_strings); - const sizeStrings = std.mem.bigToNative(u32, self.header().off_dt_strings); - const off = @min(offStrings, self.bytes.len); - const len = @min(sizeStrings, self.bytes.len - off); + fn string_data(self: *const @This()) [*c]const u8 { + const off_strings = std.mem.bigToNative(u32, self.header().off_dt_strings); + const size_strings = std.mem.bigToNative(u32, self.header().off_dt_strings); + const off = @min(off_strings, self.bytes.len); + const len = @min(size_strings, self.bytes.len - off); return @ptrCast(self.bytes[off .. off + len]); } /// Returns a string slice at given byte offset into the device tree's strings section. - pub fn stringAt(self: *const @This(), off: usize) []const u8 { - const raw = self.stringData()[off..]; + pub fn string_at(self: *const @This(), off: usize) []const u8 { + const raw = self.string_data()[off..]; const len = std.mem.len(raw); return @ptrCast(raw[0..len]); } /// Adds information about the available and reserved memory regions described in this device /// tree into the physical memory management structures. - pub fn addPhysicalMemoryToSystem(self: *const @This()) void { - var memoryRegions = self.memoryRegionIterator(); + pub fn add_physical_memory_to_system(self: *const @This()) void { + var memory_regions = self.memory_region_iterator(); var cells: [2]u64 = undefined; - while (memoryRegions.next()) |region| { - physMemory.addMemoryRegion(region.name, region.base, region.size); + while (memory_regions.next()) |region| { + phys_memory.add_memory_region(region.name, region.base, region.size); } - const reservedRegions = self.rootNode().child("reserved-memory"); - if (reservedRegions) |resv| { + const reserved_regions = self.root_node().child("reserved-memory"); + if (reserved_regions) |resv| { var children = resv.children(); while (children.next()) |region| { if (region.property("reg")) |reg| { // TODO #address-cells, #size-cells - if (reg.readCells(0, &cells, &.{ 2, 2 })) { - physMemory.addReservedRegion(region.name, cells[0], cells[1]); + if (reg.read_cells(0, &cells, &.{ 2, 2 })) { + phys_memory.add_reserved_region(region.name, cells[0], cells[1]); } } } @@ -456,15 +460,15 @@ pub const Fdt = struct { /// Looks up a `/slash/separated/path` inside the device tree. pub fn find(self: *const @This(), path: []const u8) ?FdtNode { - const trimmedPath = std.mem.trimLeft(u8, path, "/"); - var pathElements = std.mem.splitScalar(u8, trimmedPath, '/'); - var currentNode = self.rootNode(); - if (trimmedPath.len == 0) { - return currentNode; + const trimmed_path = std.mem.trimLeft(u8, path, "/"); + var path_elements = std.mem.splitScalar(u8, trimmed_path, '/'); + var current_node = self.root_node(); + if (trimmed_path.len == 0) { + return current_node; } - while (pathElements.next()) |element| { + while (path_elements.next()) |element| { var found: ?FdtNode = null; - var children = currentNode.children(); + var children = current_node.children(); while (children.next()) |child| { if (std.mem.eql(u8, child.name, element)) { found = child; @@ -473,17 +477,17 @@ pub const Fdt = struct { } if (found) |f| { log.info("{s}", .{element}); - currentNode = f; + current_node = f; } else { return null; } } - return currentNode; + return current_node; } - fn dump_property(property: *const FdtNodeProp, depth: usize, allStrings: bool) void { + fn dump_property(property: *const FdtNodeProp, depth: usize, all_strings: bool) void { for (0..depth) |_| { - log.writeRaw(" "); + log.write_waw(" "); } log.write("{s}", .{property.name}); @@ -494,74 +498,74 @@ pub const Fdt = struct { or std.mem.eql(u8, property.name, "interrupt-parent") // ) { // Dump as a single cell - const v = property.getU32(0) orelse 0; + const v = property.get_cell(0) orelse 0; log.write(" = {}", .{v}); - } else if (allStrings // + } else if (all_strings // or std.mem.eql(u8, property.name, "compatible") // or std.mem.eql(u8, property.name, "model") // or std.mem.endsWith(u8, property.name, "-names") // or std.mem.endsWith(u8, property.name, "stdout-path") // ) { - var v = property.getStringArray(); + var v = property.get_string_array(); var f = true; while (v.next()) |s| { if (f) { - log.writeRaw(" = "); + log.write_waw(" = "); } else { - log.writeRaw(", "); + log.write_waw(", "); } f = false; log.write("\"{s}\"", .{s}); } } else { // Dump the rest as a cell array - const len = property.lenU32(); - log.writeRaw(" = <"); + const len = property.len_cells(); + log.write_waw(" = <"); for (0..len) |i| { if (i != 0) { - log.writeRaw(", "); + log.write_waw(", "); } - log.write("0x{x}", .{property.getU32Unchecked(i)}); + log.write("0x{x}", .{property.get_cell_unchecked(i)}); } - log.writeRaw(">"); + log.write_waw(">"); } - log.writeRaw(";\r\n"); + log.write_waw(";\r\n"); } fn dump_node(node: *const FdtNode, depth: usize) void { - var anyProperties = false; - var firstChild = true; + var any_properties = false; + var first_child = true; for (0..depth) |_| { - log.writeRaw(" "); + log.write_waw(" "); } if (node.name.len != 0) { log.write("{s} ", .{node.name}); } - log.writeRaw("{\r\n"); - var properties = node.propIterator(); - const allStrings = std.mem.eql(u8, node.name, "aliases"); + log.write_waw("{\r\n"); + var properties = node.prop_iterator(); + const all_strings = std.mem.eql(u8, node.name, "aliases"); while (properties.next()) |property| { - dump_property(&property, depth + 1, allStrings); - anyProperties = true; + dump_property(&property, depth + 1, all_strings); + any_properties = true; } var children = node.children(); while (children.next()) |child| { - if (anyProperties and firstChild) { - log.writeRaw("\r\n"); + if (any_properties and first_child) { + log.write_waw("\r\n"); } - firstChild = false; + first_child = false; dump_node(&child, depth + 1); } for (0..depth) |_| { - log.writeRaw(" "); + log.write_waw(" "); } log.write("}},\r\n", .{}); } /// Dumps the structured device tree into the log output. pub fn dump(self: *const @This()) void { - dump_node(&self.rootNode(), 0); + dump_node(&self.root_node(), 0); } };