From 9e27cc6c70b5a30ab3f2ec8307a8721c5bf6a197 Mon Sep 17 00:00:00 2001 From: Asherah Connor Date: Wed, 8 Feb 2023 21:18:49 +1100 Subject: [PATCH] dainboot: building Working? No idea. --- Makefile | 2 + common/dbuild.zig | 21 ++++--- common/dcommon.zig | 5 +- common/ddtb.zig | 4 +- dainboot/build.zig | 50 ++++++++++------ dainboot/build.zig.zon | 4 ++ dainboot/src/arch.zig | 5 +- dainboot/src/dainboot.zig | 122 +++++++++++++++++++------------------- dainboot/src/riscv64.zig | 16 +++-- daintree.code-workspace | 4 +- dtb | 2 +- 11 files changed, 137 insertions(+), 98 deletions(-) create mode 100644 dainboot/build.zig.zon diff --git a/Makefile b/Makefile index 559318f..887899b 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,8 @@ QEMU_ARGS := \ # qemu-system-riscv64: FDT: Failed to create subnode /fw-cfg@10100000: FDT_ERR_EXISTS QEMU_DTB_ARGS := EFI_BOOTLOADER_NAME := BOOTRISCV64 +else +$(error ARCH must be set to arm64 or riscv64) endif QEMU_ACCEL := tcg diff --git a/common/dbuild.zig b/common/dbuild.zig index 9808743..4297e09 100644 --- a/common/dbuild.zig +++ b/common/dbuild.zig @@ -1,7 +1,9 @@ const std = @import("std"); const build = std.build; -usingnamespace @import("dcommon.zig"); +const dcommon = @import("dcommon.zig"); +const Arch = dcommon.Arch; +const Board = dcommon.Board; pub fn getBoard(b: *build.Builder) !Board { return b.option(Board, "board", "Target board.") orelse @@ -47,15 +49,18 @@ pub fn efiTagFor(cpu_arch: std.Target.Cpu.Arch) []const u8 { }; } -pub fn addBuildOptions(b: *build.Builder, exe: *build.LibExeObjStep, board: Board) !void { - exe.addBuildOption([:0]const u8, "version", try b.allocator.dupeZ(u8, try getVersion(b))); - exe.addBuildOption([:0]const u8, "board", try b.allocator.dupeZ(u8, @tagName(board))); +pub fn addBuildOptions(b: *build.Builder, exe: *build.CompileStep, board: Board) !void { + const options = b.addOptions(); + options.addOption([]const u8, "version", try b.allocator.dupe(u8, try getVersion(b))); + options.addOption([]const u8, "board", try b.allocator.dupe(u8, @tagName(board))); + exe.addOptions("build_options", options); } // adapted from Zig's own build.zig: // https://github.com/ziglang/zig/blob/a021c7b1b2428ecda85e79e281d43fa1c92f8c94/build.zig#L140-L188 fn getVersion(b: *build.Builder) ![]u8 { - const version_string = b.fmt("{d}.{d}.{d}", .{ daintree_version.major, daintree_version.minor, daintree_version.patch }); + const version = dcommon.version; + const version_string = b.fmt("{d}.{d}.{d}", .{ version.major, version.minor, version.patch }); var code: u8 = undefined; const git_describe_untrimmed = b.execAllowFail(&[_][]const u8{ @@ -76,14 +81,14 @@ fn getVersion(b: *build.Builder) ![]u8 { }, 2 => { // Untagged development build (e.g. 0.7.0-684-gbbe2cca1a). - var it = std.mem.split(git_describe, "-"); + var it = std.mem.split(u8, git_describe, "-"); const tagged_ancestor = it.next() orelse unreachable; const commit_height = it.next() orelse unreachable; const commit_id = it.next() orelse unreachable; const ancestor_ver = try std.builtin.Version.parse(tagged_ancestor); - if (daintree_version.order(ancestor_ver) != .gt) { - std.debug.print("Daintree version '{}' must be greater than tagged ancestor '{}'\n", .{ daintree_version, ancestor_ver }); + if (version.order(ancestor_ver) != .gt) { + std.debug.print("Daintree version '{}' must be greater than tagged ancestor '{}'\n", .{ version, ancestor_ver }); std.process.exit(1); } diff --git a/common/dcommon.zig b/common/dcommon.zig index 0288378..f2473ed 100644 --- a/common/dcommon.zig +++ b/common/dcommon.zig @@ -1,13 +1,14 @@ const std = @import("std"); +const builtin = @import("builtin"); -pub const daintree_version = std.builtin.Version{ .major = 0, .minor = 0, .patch = 2 }; +pub const version = std.builtin.Version{ .major = 0, .minor = 0, .patch = 2 }; pub const Arch = enum { arm64, riscv64, }; -pub const daintree_arch: Arch = switch (std.builtin.target.cpu.arch) { +pub const daintree_arch: Arch = switch (builtin.target.cpu.arch) { .aarch64 => .arm64, .riscv64 => .riscv64, else => @panic("unsupported arch"), diff --git a/common/ddtb.zig b/common/ddtb.zig index 6dcc64f..4fdb2ca 100644 --- a/common/ddtb.zig +++ b/common/ddtb.zig @@ -30,8 +30,8 @@ pub fn searchForUart(dtb: []const u8) Error!Uart { var address_cells: ?u32 = null; var size_cells: ?u32 = null; - var ev = try traverser.next(); - while (ev != .End) : (ev = try traverser.next()) { + var ev = try traverser.event(); + while (ev != .End) : (ev = try traverser.event()) { if (!in_node) { switch (ev) { .BeginNode => |name| { diff --git a/dainboot/build.zig b/dainboot/build.zig index f4a231d..eae7820 100644 --- a/dainboot/build.zig +++ b/dainboot/build.zig @@ -1,10 +1,10 @@ const std = @import("std"); -const Builder = std.build.Builder; +const Build = std.Build; const dbuild = @import("src/common/dbuild.zig"); const dcommon = @import("src/common/dcommon.zig"); -pub fn build(b: *Builder) !void { +pub fn build(b: *Build) !void { const board = try dbuild.getBoard(b); var target = dbuild.crossTargetFor(board); target.os_tag = .uefi; @@ -14,29 +14,45 @@ pub fn build(b: *Builder) !void { return; } - const exe = b.addExecutable(bootName(b, board, target), "src/dainboot.zig"); - exe.setTarget(target); - exe.setBuildMode(b.standardReleaseOptions()); + const exe = b.addExecutable(.{ + .name = bootName(b, board, target), + .root_source_file = .{ .path = "src/dainboot.zig" }, + .target = target, + .optimize = b.standardOptimizeOption(.{}), + }); try dbuild.addBuildOptions(b, exe, board); - exe.addPackagePath("dtb", "../dtb/src/dtb.zig"); + b.addModule(.{ + .name = "dtb", + .source_file = .{ .path = "../dtb/src/dtb.zig" }, + }); + exe.addModule("dtb", b.modules.get("dtb").?); + exe.install(); b.default_step.dependOn(&exe.step); } -fn buildRiscv64(b: *Builder, board: dcommon.Board, target: std.zig.CrossTarget) !void { - const crt0 = b.addAssemble("crt0-efi-riscv64", "src/crt0-efi-riscv64.S"); - crt0.setTarget(std.zig.CrossTarget{ - .cpu_arch = target.cpu_arch, - .os_tag = .freestanding, +fn buildRiscv64(b: *Build, board: dcommon.Board, target: std.zig.CrossTarget) !void { + const crt0 = b.addAssembly(.{ + .name = "crt0-efi-riscv64", + .source_file = .{ .path = "src/crt0-efi-riscv64.S" }, + .target = .{ + .cpu_arch = target.cpu_arch, + .os_tag = .freestanding, + }, + .optimize = b.standardOptimizeOption(.{}), }); - crt0.setBuildMode(b.standardReleaseOptions()); - const obj = b.addObject(bootName(b, board, target), "src/dainboot.zig"); - obj.setTarget(target); - obj.setBuildMode(b.standardReleaseOptions()); + const obj = b.addObject(.{ + .name = bootName(b, board, target), + .root_source_file = .{ .path = "src/dainboot.zig" }, + .target = target, + .optimize = b.standardOptimizeOption(.{}), + }); try dbuild.addBuildOptions(b, obj, board); - obj.addPackagePath("dtb", "../dtb/src/dtb.zig"); + + const dtb_pkg = b.dependency("dtb", .{}); + obj.addModule("dtb", dtb_pkg.module("dbt")); const combined = b.addSystemCommand(&.{ "ld.lld", @@ -87,6 +103,6 @@ fn buildRiscv64(b: *Builder, board: dcommon.Board, target: std.zig.CrossTarget) b.default_step.dependOn(&efi.step); } -fn bootName(b: *Builder, board: dcommon.Board, target: std.zig.CrossTarget) []const u8 { +fn bootName(b: *Build, board: dcommon.Board, target: std.zig.CrossTarget) []const u8 { return b.fmt("BOOT{s}.{s}", .{ dbuild.efiTagFor(target.cpu_arch.?), @tagName(board) }); } diff --git a/dainboot/build.zig.zon b/dainboot/build.zig.zon new file mode 100644 index 0000000..9e11ce3 --- /dev/null +++ b/dainboot/build.zig.zon @@ -0,0 +1,4 @@ +.{ + .name = "dainboot", + .version = "0.0.0", +} diff --git a/dainboot/src/arch.zig b/dainboot/src/arch.zig index 03eb485..49e2526 100644 --- a/dainboot/src/arch.zig +++ b/dainboot/src/arch.zig @@ -1,3 +1,6 @@ const dcommon = @import("common/dcommon.zig"); -pub usingnamespace @import(@tagName(dcommon.daintree_arch) ++ ".zig"); +pub usingnamespace switch (dcommon.daintree_arch) { + .arm64 => @import("arm64.zig"), + .riscv64 => @import("riscv64.zig"), +}; diff --git a/dainboot/src/dainboot.zig b/dainboot/src/dainboot.zig index a8ac81a..eceeb01 100644 --- a/dainboot/src/dainboot.zig +++ b/dainboot/src/dainboot.zig @@ -6,26 +6,28 @@ const dtblib = @import("dtb"); const ddtb = @import("common/ddtb.zig"); const arch = @import("arch.zig"); -usingnamespace @import("util.zig"); +const u = @import("util.zig"); var boot_services: *uefi.tables.BootServices = undefined; -pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace) noreturn { - printf("panic: {s}\r\n", .{msg}); +pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn { + _ = error_return_trace; + _ = ret_addr; + u.printf("panic: {s}\r\n", .{msg}); arch.halt(); } pub fn main() void { - con_out = uefi.system_table.con_out.?; + u.con_out = uefi.system_table.con_out.?; boot_services = uefi.system_table.boot_services.?; - printf("daintree bootloader {s} on {s}\r\n", .{ build_options.version, build_options.board }); + u.printf("daintree bootloader {s} on {s}\r\n", .{ build_options.version, build_options.board }); var load_context = LoadContext{}; var options_buffer: [256]u8 = [_]u8{undefined} ** 256; if (getLoadOptions(&options_buffer)) |options| { - printf("load options: \"{s}\"\r\n", .{options}); + u.printf("load options: \"{s}\"\r\n", .{options}); load_context.handleOptions(options); } @@ -38,12 +40,12 @@ pub fn main() void { } const dtb = load_context.dtb orelse { - printf("\r\nDTB not found\r\n", .{}); + u.printf("\r\nDTB not found\r\n", .{}); _ = boot_services.stall(5 * 1000 * 1000); return; }; const dainkrnl = load_context.dainkrnl orelse { - printf("\r\nDAINKRNL not found\r\n", .{}); + u.printf("\r\nDAINKRNL not found\r\n", .{}); _ = boot_services.stall(5 * 1000 * 1000); return; }; @@ -58,19 +60,19 @@ const LoadContext = struct { dainkrnl: ?[]const u8 = null, fn handleOptions(self: *Self, options: []const u8) void { - var it = std.mem.tokenize(options, " "); + var it = std.mem.tokenize(u8, options, " "); loop: while (it.next()) |opt_name| { if (std.mem.eql(u8, opt_name, "dtb")) { const loc = handleOptionsLoc("dtb", &it) orelse continue :loop; - printf("using dtb in ramdisk at 0x{x:0>16} ({} bytes)\r\n", .{ loc.offset, loc.len }); + u.printf("using dtb in ramdisk at 0x{x:0>16} ({} bytes)\r\n", .{ loc.offset, loc.len }); self.dtb = @intToPtr([*]u8, loc.offset)[0..loc.len]; } else if (std.mem.eql(u8, opt_name, "kernel")) { const loc = handleOptionsLoc("kernel", &it) orelse continue :loop; - printf("using kernel in ramdisk at 0x{x:0>16} ({} bytes)\r\n", .{ loc.offset, loc.len }); + u.printf("using kernel in ramdisk at 0x{x:0>16} ({} bytes)\r\n", .{ loc.offset, loc.len }); self.dainkrnl = @intToPtr([*]u8, loc.offset)[0..loc.len]; } else { - printf("unknown option '{s}'\r\n", .{opt_name}); + u.printf("unknown option '{s}'\r\n", .{opt_name}); } } } @@ -88,10 +90,10 @@ const LoadContext = struct { for (uefi.system_table.configuration_table[0..uefi.system_table.number_of_table_entries]) |table| { if (table.vendor_guid.eql(fdt_table_guid)) { if (dtblib.totalSize(table.vendor_table)) |size| { - printf("found FDT in UEFI\n", .{}); + u.printf("found FDT in UEFI\n", .{}); self.dtb = @ptrCast([*]const u8, table.vendor_table)[0..size]; return; - } else |err| {} + } else |_| {} } } } @@ -106,7 +108,7 @@ const LoadContext = struct { &handle_list_size, handle_list, ) == .BufferTooSmall) { - check("allocatePool", boot_services.allocatePool( + u.check("allocatePool", boot_services.allocatePool( uefi.tables.MemoryType.BootServicesData, handle_list_size, @ptrCast(*[*]align(8) u8, &handle_list), @@ -114,36 +116,36 @@ const LoadContext = struct { } if (handle_list_size == 0) { - printf("no simple file system protocols found\r\n", .{}); + u.printf("no simple file system protocols found\r\n", .{}); return; } const handle_count = handle_list_size / @sizeOf(uefi.Handle); - printf("searching for <", .{}); + u.printf("searching for <", .{}); if (self.dtb == null) { - printf("DTB", .{}); - if (self.dainkrnl == null) printf(" ", .{}); + u.printf("DTB", .{}); + if (self.dainkrnl == null) u.printf(" ", .{}); } - if (self.dainkrnl == null) printf("DAINKRNL.{s}", .{@tagName(dcommon.daintree_arch)}); - printf("> on {} volume(s) ", .{handle_count}); + if (self.dainkrnl == null) u.printf("DAINKRNL.{s}", .{@tagName(dcommon.daintree_arch)}); + u.printf("> on {} volume(s) ", .{handle_count}); for (handle_list[0..handle_count]) |handle| { var sfs_proto: ?*uefi.protocols.SimpleFileSystemProtocol = undefined; - check("openProtocol", boot_services.openProtocol( + u.check("openProtocol", boot_services.openProtocol( handle, &uefi.protocols.SimpleFileSystemProtocol.guid, - @ptrCast(*?*c_void, &sfs_proto), + @ptrCast(*?*anyopaque, &sfs_proto), uefi.handle, null, .{ .get_protocol = true }, )); - printf(".", .{}); + u.printf(".", .{}); var f_proto: *uefi.protocols.FileProtocol = undefined; - check("openVolume", sfs_proto.?.openVolume(&f_proto)); + u.check("openVolume", sfs_proto.?.openVolume(&f_proto)); if (self.dainkrnl == null) { self.dainkrnl = tryLoadFromFileProtocol(f_proto, "dainkrnl." ++ @tagName(dcommon.daintree_arch)); @@ -167,22 +169,22 @@ const LoadContext = struct { len: u64, }; - fn handleOptionsLoc(comptime opt_name: []const u8, it: *std.mem.TokenIterator) ?Loc { + fn handleOptionsLoc(comptime opt_name: []const u8, it: *std.mem.TokenIterator(u8)) ?Loc { const offset_s = it.next() orelse { - printf(opt_name ++ ": missing offset argument\r\n", .{}); + u.printf(opt_name ++ ": missing offset argument\r\n", .{}); return null; }; const len_s = it.next() orelse { - printf(opt_name ++ ": missing length argument\r\n", .{}); + u.printf(opt_name ++ ": missing length argument\r\n", .{}); return null; }; const offset = std.fmt.parseInt(u64, offset_s, 0) catch |err| { - printf(opt_name ++ ": parse offset '{s}' error: {}\r\n", .{ offset_s, err }); + u.printf(opt_name ++ ": parse offset '{s}' error: {}\r\n", .{ offset_s, err }); return null; }; const len = std.fmt.parseInt(u64, len_s, 0) catch |err| { - printf(opt_name ++ ": parse len '{s}' error: {}\r\n", .{ len_s, err }); + u.printf(opt_name ++ ": parse len '{s}' error: {}\r\n", .{ len_s, err }); return null; }; return Loc{ .offset = offset, .len = len }; @@ -194,7 +196,7 @@ fn getLoadOptions(buffer: *[256]u8) ?[]const u8 { if (boot_services.openProtocol( uefi.handle, &uefi.protocols.LoadedImageProtocol.guid, - @ptrCast(*?*c_void, &li_proto), + @ptrCast(*?*anyopaque, &li_proto), uefi.handle, null, .{ .get_protocol = true }, @@ -215,7 +217,7 @@ fn getLoadOptions(buffer: *[256]u8) ?[]const u8 { } return options; } else |err| { - printf("failed utf16leToUtf8: {}\r\n", .{err}); + u.printf("failed utf16leToUtf8: {}\r\n", .{err}); return null; } } @@ -237,36 +239,36 @@ fn tryLoadFromFileProtocol(f_proto: *uefi.protocols.FileProtocol, comptime file_ return null; } - check("setPosition", proto.setPosition(uefi.protocols.FileProtocol.efi_file_position_end_of_file)); - check("getPosition", proto.getPosition(&size)); - printf(" \"{s}\" {} bytes ", .{ file_name, size }); + u.check("setPosition", proto.setPosition(uefi.protocols.FileProtocol.efi_file_position_end_of_file)); + u.check("getPosition", proto.getPosition(&size)); + u.printf(" \"{s}\" {} bytes ", .{ file_name, size }); - check("setPosition", proto.setPosition(0)); + u.check("setPosition", proto.setPosition(0)); - check("allocatePool", boot_services.allocatePool( + u.check("allocatePool", boot_services.allocatePool( .BootServicesData, size, @ptrCast(*[*]align(8) u8, &mem), )); - check("read", proto.read(&size, mem)); + u.check("read", proto.read(&size, mem)); return mem[0..size]; } fn parseElf(bytes: []const u8) std.elf.Header { if (bytes.len < @sizeOf(std.elf.Elf64_Ehdr)) { - printf("found {} byte(s), too small for ELF header ({} bytes)\r\n", .{ bytes.len, @sizeOf(std.elf.Elf64_Ehdr) }); + u.printf("found {} byte(s), too small for ELF header ({} bytes)\r\n", .{ bytes.len, @sizeOf(std.elf.Elf64_Ehdr) }); arch.halt(); } var buffer = std.io.fixedBufferStream(bytes); var elf_header = std.elf.Header.read(&buffer) catch |err| { - printf("failed to parse ELF: {}\r\n", .{err}); + u.printf("failed to parse ELF: {}\r\n", .{err}); arch.halt(); }; const bits: u8 = if (elf_header.is_64) 64 else 32; const endian_ch = if (elf_header.endian == .Big) @as(u8, 'B') else @as(u8, 'L'); - printf("ELF entrypoint: {x:0>16} ({}-bit {c}E {s})\r\n", .{ + u.printf("ELF entrypoint: {x:0>16} ({}-bit {c}E {s})\r\n", .{ elf_header.entry, bits, endian_ch, @@ -278,8 +280,8 @@ fn parseElf(bytes: []const u8) std.elf.Header { }); var it = elf_header.program_header_iterator(&buffer); - while (it.next() catch haltMsg("iterating phdr")) |phdr| { - printf(" * type={x:0>8} off={x:0>16} vad={x:0>16} pad={x:0>16} fsz={x:0>16} msz={x:0>16}\r\n", .{ phdr.p_type, phdr.p_offset, phdr.p_vaddr, phdr.p_paddr, phdr.p_filesz, phdr.p_memsz }); + while (it.next() catch u.haltMsg("iterating phdr")) |phdr| { + u.printf(" * type={x:0>8} off={x:0>16} vad={x:0>16} pad={x:0>16} fsz={x:0>16} msz={x:0>16}\r\n", .{ phdr.p_type, phdr.p_offset, phdr.p_vaddr, phdr.p_paddr, phdr.p_filesz, phdr.p_memsz }); } return elf_header; @@ -291,13 +293,13 @@ fn exitBootServices(dainkrnl: []const u8, dtb: []const u8) noreturn { var kernel_size: u64 = 0; { var it = dainkrnl_elf.program_header_iterator(&elf_source); - while (it.next() catch haltMsg("iterating phdrs (2)")) |phdr| { + while (it.next() catch u.haltMsg("iterating phdrs (2)")) |phdr| { if (phdr.p_type == std.elf.PT_LOAD) { const target = phdr.p_vaddr - dcommon.daintree_kernel_start; const load_bytes = std.math.min(phdr.p_filesz, phdr.p_memsz); - printf("will load 0x{x:0>16} bytes at 0x{x:0>16} into offset+0x{x:0>16}\r\n", .{ load_bytes, phdr.p_vaddr, target }); + u.printf("will load 0x{x:0>16} bytes at 0x{x:0>16} into offset+0x{x:0>16}\r\n", .{ load_bytes, phdr.p_vaddr, target }); if (phdr.p_memsz > phdr.p_filesz) { - printf(" and zeroing {} bytes at end\r\n", .{phdr.p_memsz - phdr.p_filesz}); + u.printf(" and zeroing {} bytes at end\r\n", .{phdr.p_memsz - phdr.p_filesz}); } kernel_size = std.math.max(kernel_size, target + phdr.p_memsz); } @@ -309,22 +311,22 @@ fn exitBootServices(dainkrnl: []const u8, dtb: []const u8) noreturn { var fb_horiz: u32 = 0; { var graphics: *uefi.protocols.GraphicsOutputProtocol = undefined; - const result = boot_services.locateProtocol(&uefi.protocols.GraphicsOutputProtocol.guid, null, @ptrCast(*?*c_void, &graphics)); + const result = boot_services.locateProtocol(&uefi.protocols.GraphicsOutputProtocol.guid, null, @ptrCast(*?*anyopaque, &graphics)); if (result == .Success) { fb = @intToPtr([*]u32, graphics.mode.frame_buffer_base); fb_vert = graphics.mode.info.vertical_resolution; fb_horiz = graphics.mode.info.horizontal_resolution; - printf("{}x{} framebuffer located at {*}\n", .{ fb_horiz, fb_vert, fb }); + u.printf("{}x{} framebuffer located at {*}\n", .{ fb_horiz, fb_vert, fb }); } else { - printf("no framebuffer found: {}\n", .{result}); + u.printf("no framebuffer found: {}\n", .{result}); } } var dtb_scratch_ptr: [*]u8 = undefined; - check("allocatePool", boot_services.allocatePool(uefi.tables.MemoryType.BootServicesData, 128 * 1024, @ptrCast(*[*]align(8) u8, &dtb_scratch_ptr))); - var dtb_scratch = dtb_scratch_ptr[0 .. 128 * 1024]; + u.check("allocatePool", boot_services.allocatePool(uefi.tables.MemoryType.BootServicesData, 128 * 1024, @ptrCast(*[*]align(8) u8, &dtb_scratch_ptr))); + // var dtb_scratch = dtb_scratch_ptr[0 .. 128 * 1024]; - printf("looking up serial base in DTB ... ", .{}); + u.printf("looking up serial base in DTB ... ", .{}); var uart_base: u64 = 0; var uart_width: u3 = 0; if (ddtb.searchForUart(dtb)) |uart| { @@ -336,13 +338,13 @@ fn exitBootServices(dainkrnl: []const u8, dtb: []const u8) noreturn { else => 1, }; } else |err| { - printf("failed to parse dtb: {}", .{err}); + u.printf("failed to parse dtb: {}", .{err}); } - printf("0x{x:0>8}~{}\r\n", .{ uart_base, uart_width }); + u.printf("0x{x:0>8}~{}\r\n", .{ uart_base, uart_width }); - printf("we will clean d/i$ for 0x{x} bytes\r\n", .{kernel_size}); + u.printf("we will clean d/i$ for 0x{x} bytes\r\n", .{kernel_size}); - printf("going quiet before obtaining memory map\r\n", .{}); + u.printf("going quiet before obtaining memory map\r\n", .{}); // ***************************************************************** // * Minimise logging between here and boot services exit. * @@ -362,7 +364,7 @@ fn exitBootServices(dainkrnl: []const u8, dtb: []const u8) noreturn { &descriptor_size, &descriptor_version, ) == .BufferTooSmall) { - check("allocatePool", boot_services.allocatePool( + u.check("allocatePool", boot_services.allocatePool( uefi.tables.MemoryType.BootServicesData, memory_map_size, @ptrCast(*[*]align(8) u8, &memory_map), @@ -398,7 +400,7 @@ fn exitBootServices(dainkrnl: []const u8, dtb: []const u8) noreturn { // to conventional_start now. var it = dainkrnl_elf.program_header_iterator(&elf_source); - while (it.next() catch haltMsg("iterating phdrs (2)")) |phdr| { + while (it.next() catch u.haltMsg("iterating phdrs (2)")) |phdr| { if (phdr.p_type == std.elf.PT_LOAD) { const target = phdr.p_vaddr - dcommon.daintree_kernel_start + conventional_start; std.mem.copy(u8, @intToPtr([*]u8, target)[0..phdr.p_filesz], dainkrnl[phdr.p_offset .. phdr.p_offset + phdr.p_filesz]); @@ -427,11 +429,11 @@ fn exitBootServices(dainkrnl: []const u8, dtb: []const u8) noreturn { // I'd love to change this back to "..., kernel_size);" at some point. arch.cleanInvalidateDCacheICache(conventional_start, conventional_bytes); - printf("{x} {x} ", .{ conventional_start, @ptrToInt(&entry_data) }); + u.printf("{x} {x} ", .{ conventional_start, @ptrToInt(&entry_data) }); const adjusted_entry = dainkrnl_elf.entry - dcommon.daintree_kernel_start + conventional_start; - check("exitBootServices", boot_services.exitBootServices(uefi.handle, memory_map_key)); + u.check("exitBootServices", boot_services.exitBootServices(uefi.handle, memory_map_key)); if (fb) |base| { var x: usize = 0; diff --git a/dainboot/src/riscv64.zig b/dainboot/src/riscv64.zig index 52030a5..b045efa 100644 --- a/dainboot/src/riscv64.zig +++ b/dainboot/src/riscv64.zig @@ -12,20 +12,24 @@ pub fn halt() noreturn { unreachable; } -pub fn transfer(entry_data: *dcommon.EntryData, uart_base: u64, adjusted_entry: u64) callconv(.Inline) noreturn { +pub inline fn transfer(entry_data: *dcommon.EntryData, uart_base: u64, adjusted_entry: u64) noreturn { // Supervisor mode, MMU disabled. (SATP = 0) + _ = uart_base; asm volatile ( \\ret : : [entry_data] "{a0}" (entry_data), - [entry] "{ra}" (adjusted_entry) + [entry] "{ra}" (adjusted_entry), : "memory" ); unreachable; } -pub fn cleanInvalidateDCacheICache(start: u64, len: u64) callconv(.Inline) void { +pub inline fn cleanInvalidateDCacheICache(start: u64, len: u64) void { + _ = start; + _ = len; + // I think this does enough. asm volatile ( \\fence.i @@ -75,7 +79,7 @@ export fn relocate(ldbase: u64, dyn: [*]elf.Elf64_Dyn) uefi.Status { : [r_info] "{t0}" (relp.r_info), [dyn] "{t1}" (@ptrToInt(dyn)), [i] "{t2}" (i), - [rel] "{t3}" (@ptrToInt(rel)) + [rel] "{t3}" (@ptrToInt(rel)), : "memory" ); } @@ -89,12 +93,12 @@ export fn relocate(ldbase: u64, dyn: [*]elf.Elf64_Dyn) uefi.Status { // For whatever reason, memset and memcpy implementations aren't being // included, and it's adding a PLT and GOT to have them looked up later. They // aren't being provided by anyone else, so we must. -export fn memset(b: *c_void, c: c_int, len: usize) *c_void { +export fn memset(b: *anyopaque, c: c_int, len: usize) *anyopaque { std.mem.set(u8, @ptrCast([*]u8, b)[0..len], @truncate(u8, std.math.absCast(c))); return b; } -export fn memcpy(dst: *c_void, src: *const c_void, n: usize) *c_void { +export fn memcpy(dst: *anyopaque, src: *const anyopaque, n: usize) *anyopaque { std.mem.copy(u8, @ptrCast([*]u8, dst)[0..n], @ptrCast([*]const u8, src)[0..n]); return dst; } diff --git a/daintree.code-workspace b/daintree.code-workspace index 5c583df..16cbae2 100644 --- a/daintree.code-workspace +++ b/daintree.code-workspace @@ -7,5 +7,7 @@ "path": "../zig" } ], - "settings": {} + "settings": { + "zig.buildFilePath": "${workspaceFolder}/dainboot/build.zig" + } } diff --git a/dtb b/dtb index cc059b0..c477b06 160000 --- a/dtb +++ b/dtb @@ -1 +1 @@ -Subproject commit cc059b0c99736fb1cd056ece80eaa892e72c0f8f +Subproject commit c477b063f40492db56d33425282d7f05847eb815