Skip to content

Commit

Permalink
std: implement basic io and improve alloc in uefi
Browse files Browse the repository at this point in the history
  • Loading branch information
RossComputerGuy committed Dec 19, 2024
1 parent a68119f commit cb18f91
Show file tree
Hide file tree
Showing 19 changed files with 1,263 additions and 157 deletions.
8 changes: 8 additions & 0 deletions lib/std/Thread.zig
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ else if (native_os == .linux)
LinuxThreadImpl
else if (native_os == .wasi)
WasiThreadImpl
else if (native_os == .uefi)
UefiThreadImpl
else
UnsupportedImpl;

Expand Down Expand Up @@ -1124,6 +1126,12 @@ const WasiThreadImpl = struct {
}
};

const UefiThreadImpl = struct {
fn getCurrentId() Id {
return 1;
}
};

const LinuxThreadImpl = struct {
const linux = std.os.linux;

Expand Down
2 changes: 1 addition & 1 deletion lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ pub fn defaultPanic(

if (uefi.system_table.boot_services) |bs| {
// ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220)
const exit_data: []u16 = uefi.raw_pool_allocator.alloc(u16, exit_msg.len + 1) catch @trap();
const exit_data: []u16 = uefi.global_pool_allocator.allocator().alloc(u16, exit_msg.len + 1) catch @trap();
@memcpy(exit_data, exit_msg[0..exit_data.len]); // Includes null terminator.
_ = bs.exit(uefi.handle, .Aborted, exit_data.len, exit_data.ptr);
}
Expand Down
10 changes: 10 additions & 0 deletions lib/std/debug/SelfInfo.zig
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ pub fn getModuleForAddress(self: *SelfInfo, address: usize) !*Module {
return self.lookupModuleHaiku(address);
} else if (comptime builtin.target.isWasm()) {
return self.lookupModuleWasm(address);
} else if (native_os == .uefi) {
return self.lookupModuleUefi(address);
} else {
return self.lookupModuleDl(address);
}
Expand All @@ -146,6 +148,8 @@ pub fn getModuleNameForAddress(self: *SelfInfo, address: usize) ?[]const u8 {
return null;
} else if (comptime builtin.target.isWasm()) {
return null;
} else if (native_os == .uefi) {
return null;
} else {
return self.lookupModuleNameDl(address);
}
Expand Down Expand Up @@ -500,6 +504,12 @@ fn lookupModuleWasm(self: *SelfInfo, address: usize) !*Module {
@panic("TODO implement lookup module for Wasm");
}

fn lookupModuleUefi(self: *SelfInfo, address: usize) !*Module {
_ = self;
_ = address;
@panic("TODO implement lookup module for UEFI");
}

pub const Module = switch (native_os) {
.macos, .ios, .watchos, .tvos, .visionos => struct {
base_address: usize,
Expand Down
4 changes: 2 additions & 2 deletions lib/std/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub const File = @import("fs/File.zig");
pub const path = @import("fs/path.zig");

pub const has_executable_bit = switch (native_os) {
.windows, .wasi => false,
.windows, .wasi, .uefi => false,
else => true,
};

Expand Down Expand Up @@ -52,7 +52,7 @@ pub const MAX_PATH_BYTES = @compileError("deprecated; renamed to max_path_bytes"
/// * On other platforms, `[]u8` file paths are opaque sequences of bytes with
/// no particular encoding.
pub const max_path_bytes = switch (native_os) {
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten, .wasi => posix.PATH_MAX,
.linux, .macos, .ios, .freebsd, .openbsd, .netbsd, .dragonfly, .haiku, .solaris, .illumos, .plan9, .emscripten, .wasi, .uefi => posix.PATH_MAX,
// Each WTF-16LE code unit may be expanded to 3 WTF-8 bytes.
// If it would require 4 WTF-8 bytes, then there would be a surrogate
// pair in the WTF-16LE, and we (over)account 3 bytes for it that way.
Expand Down
21 changes: 20 additions & 1 deletion lib/std/fs/Dir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,22 @@ pub const Iterator = switch (native_os) {
self.cookie = std.os.wasi.DIRCOOKIE_START;
}
},
.uefi => struct {
dir: Dir,

const Self = @This();

pub const Error = IteratorError;

pub fn next(self: *Self) Error!?Entry {
_ = self;
return null;
}

pub fn reset(self: *Self) void {
_ = self;
}
},
else => @compileError("unimplemented"),
};

Expand Down Expand Up @@ -643,6 +659,9 @@ fn iterateImpl(self: Dir, first_iter_start_value: bool) Iterator {
.end_index = 0,
.buf = undefined,
},
.uefi => return Iterator{
.dir = self,
},
else => @compileError("unimplemented"),
}
}
Expand Down Expand Up @@ -2787,4 +2806,4 @@ const assert = std.debug.assert;
const linux = std.os.linux;
const windows = std.os.windows;
const native_os = builtin.os.tag;
const have_flock = @TypeOf(posix.system.flock) != void;
const have_flock = @hasDecl(posix.system, "flock") and @TypeOf(posix.system.flock) != void;
3 changes: 3 additions & 0 deletions lib/std/fs/File.zig
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ pub fn supportsAnsiEscapeCodes(self: File) bool {
// stderr is always sanitized.
return false;
}
if (builtin.os.tag == .uefi) {
return false;
}
if (self.isTty()) {
if (self.handle == posix.STDOUT_FILENO or self.handle == posix.STDERR_FILENO) {
if (posix.getenvZ("TERM")) |term| {
Expand Down
2 changes: 2 additions & 0 deletions lib/std/heap.zig
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ else if (builtin.target.os.tag == .plan9)
.ptr = undefined,
.vtable = &SbrkAllocator(std.os.plan9.sbrk).vtable,
}
else if (builtin.target.os.tag == .uefi)
std.os.uefi.global_page_allocator.allocator()
else
Allocator{
.ptr = undefined,
Expand Down
13 changes: 13 additions & 0 deletions lib/std/io.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const builtin = @import("builtin");
const root = @import("root");
const c = std.c;
const is_windows = builtin.os.tag == .windows;
const is_uefi = builtin.os.tag == .uefi;
const windows = std.os.windows;
const posix = std.posix;

Expand All @@ -23,6 +24,10 @@ fn getStdOutHandle() posix.fd_t {
return windows.peb().ProcessParameters.hStdOutput;
}

if (is_uefi) {
return .{ .simple_output = std.os.uefi.system_table.con_out.? };
}

if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdOutHandle")) {
return root.os.io.getStdOutHandle();
}
Expand All @@ -43,6 +48,10 @@ fn getStdErrHandle() posix.fd_t {
return windows.peb().ProcessParameters.hStdError;
}

if (is_uefi) {
return .{ .simple_output = std.os.uefi.system_table.std_err.? };
}

if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdErrHandle")) {
return root.os.io.getStdErrHandle();
}
Expand All @@ -63,6 +72,10 @@ fn getStdInHandle() posix.fd_t {
return windows.peb().ProcessParameters.hStdInput;
}

if (is_uefi) {
return .{ .simple_output = std.os.uefi.system_table.con_in.? };
}

if (@hasDecl(root, "os") and @hasDecl(root.os, "io") and @hasDecl(root.os.io, "getStdInHandle")) {
return root.os.io.getStdInHandle();
}
Expand Down
29 changes: 27 additions & 2 deletions lib/std/os/uefi.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const std = @import("../std.zig");

pub const posix = @import("uefi/posix.zig");

/// A protocol is an interface identified by a GUID.
pub const protocol = @import("uefi/protocol.zig");
pub const DevicePath = @import("uefi/device_path.zig").DevicePath;
Expand All @@ -13,8 +15,31 @@ pub const tables = @import("uefi/tables.zig");
/// Defaults to .LoaderData, the default data allocation type
/// used by UEFI applications to allocate pool memory.
pub var efi_pool_memory_type: tables.MemoryType = .LoaderData;
pub const pool_allocator = @import("uefi/pool_allocator.zig").pool_allocator;
pub const raw_pool_allocator = @import("uefi/pool_allocator.zig").raw_pool_allocator;

const allocator = @import("uefi/allocator.zig");
pub const PageAllocator = allocator.Page;
pub const PoolAllocator = allocator.Pool;
pub const RawPoolAllocator = allocator.RawPool;

pub var global_page_allocator = PageAllocator{};
pub var global_pool_allocator = PoolAllocator{};

pub var working_directory: fd_t = .none;

pub const AT = posix.AT;
pub const CLOCK = posix.CLOCK;
pub const LOCK = posix.LOCK;
pub const NAME_MAX = posix.NAME_MAX;
pub const O = posix.O;
pub const PATH_MAX = posix.PATH_MAX;
pub const PATH_MAX_WIDE = posix.PATH_MAX_WIDE;
pub const S = posix.S;

pub const utsname = posix.utsname;
pub const Stat = posix.Stat;
pub const fd_t = posix.fd_t;
pub const ino_t = posix.ino_t;
pub const mode_t = posix.mode_t;

/// The EFI image's handle that is passed to its entry point.
pub var handle: Handle = undefined;
Expand Down
Loading

0 comments on commit cb18f91

Please sign in to comment.