Skip to content

Commit

Permalink
Make the compiler build for UEFI
Browse files Browse the repository at this point in the history
  • Loading branch information
RossComputerGuy committed Apr 19, 2024
1 parent 10ea022 commit d096792
Show file tree
Hide file tree
Showing 15 changed files with 318 additions and 27 deletions.
4 changes: 2 additions & 2 deletions lib/std/Build/Cache.zig
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ pub const Manifest = struct {
// WASI does not currently support flock, so we bypass it here.
// TODO: If/when flock is supported on WASI, this check should be removed.
// See https://github.com/WebAssembly/wasi-filesystem/issues/2
if (builtin.os.tag != .wasi or std.process.can_spawn or !builtin.single_threaded) {
if (builtin.os.tag != .wasi or builtin.os.tag != .uefi or std.process.can_spawn or !builtin.single_threaded) {
const manifest_file = self.manifest_file.?;
try manifest_file.downgradeLock();
}
Expand All @@ -945,7 +945,7 @@ pub const Manifest = struct {
// WASI does not currently support flock, so we bypass it here.
// TODO: If/when flock is supported on WASI, this check should be removed.
// See https://github.com/WebAssembly/wasi-filesystem/issues/2
if (builtin.os.tag != .wasi or std.process.can_spawn or !builtin.single_threaded) {
if (builtin.os.tag != .wasi or builtin.os.tag != .uefi or std.process.can_spawn or !builtin.single_threaded) {
const manifest_file = self.manifest_file.?;
// Here we intentionally have a period where the lock is released, in case there are
// other processes holding a shared lock.
Expand Down
22 changes: 17 additions & 5 deletions lib/std/child_process.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const native_os = builtin.os.tag;
pub const ChildProcess = struct {
pub const Id = switch (native_os) {
.windows => windows.HANDLE,
.wasi => void,
.wasi, .uefi => void,
else => posix.pid_t,
};

Expand Down Expand Up @@ -47,10 +47,16 @@ pub const ChildProcess = struct {
stderr_behavior: StdIo,

/// Set to change the user id when spawning the child process.
uid: if (native_os == .windows or native_os == .wasi) void else ?posix.uid_t,
uid: switch (native_os) {
.windows, .wasi, .uefi => void,
else => ?posix.uid_t,
},

/// Set to change the group id when spawning the child process.
gid: if (native_os == .windows or native_os == .wasi) void else ?posix.gid_t,
gid: switch (native_os) {
.windows, .wasi, .uefi => void,
else => ?posix.gid_t,
},

/// Set to change the current working directory when spawning the child process.
cwd: ?[]const u8,
Expand Down Expand Up @@ -169,8 +175,14 @@ pub const ChildProcess = struct {
.term = null,
.env_map = null,
.cwd = null,
.uid = if (native_os == .windows or native_os == .wasi) {} else null,
.gid = if (native_os == .windows or native_os == .wasi) {} else null,
.uid = switch (native_os) {
.windows, .wasi, .uefi => {},
else => null,
},
.gid = switch (native_os) {
.windows, .wasi, .uefi => {},
else => null,
},
.stdin = null,
.stdout = null,
.stderr = null,
Expand Down
19 changes: 19 additions & 0 deletions lib/std/fs/Dir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,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 @@ -641,6 +657,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
1 change: 1 addition & 0 deletions lib/std/fs/get_app_data_dir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDi
else => return error.AppDataDirUnavailable,
}
},
.uefi => return std.process.getCwdAlloc(allocator) catch error.AppDataDirUnavailable,
else => @compileError("Unsupported OS"),
}
}
Expand Down
4 changes: 2 additions & 2 deletions lib/std/fs/path.zig
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ test resolveUefi {
// Keep relative paths relative.
try testResolveUefi(&[_][]const u8{"a\\b"}, "a\\b");
try testResolveUefi(&[_][]const u8{"."}, ".");
try testResolveUefi(&[_][]const u8{".", "src\\test.zig", "..", "..\\test\\cases.zig"}, "test\\cases.zig");
try testResolveUefi(&[_][]const u8{ ".", "src\\test.zig", "..", "..\\test\\cases.zig" }, "test\\cases.zig");
}

fn testResolveWindows(paths: []const []const u8, expected: []const u8) !void {
Expand Down Expand Up @@ -1487,7 +1487,7 @@ test relative {
try testRelativePosix("/baz", "/baz-quux", "../baz-quux");

try testRelativeUefi("\\var\\lib", "\\var", "..");
try testRelativeUefi("\\var\\lib", "\\bin", "..\\..\\bin");
try testRelativeUefi("\\var\\lib", "\\bin", "..\\..\\bin");
try testRelativeUefi("\\var\\lib", "\\var\\lib", "");
try testRelativeUefi("\\var\\lib", "\\var\\apache", "..\\apache");
try testRelativeUefi("\\var\\", "\\var\\lib", "lib");
Expand Down
1 change: 1 addition & 0 deletions lib/std/net.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const windows = std.os.windows;
// first release to support them.
pub const has_unix_sockets = switch (native_os) {
.windows => builtin.os.version_range.windows.isAtLeast(.win10_rs4) orelse false,
.uefi => true,
else => true,
};

Expand Down
11 changes: 11 additions & 0 deletions lib/std/os/uefi.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub const PoolAllocator = allocator.PoolAllocator;
pub const RawPoolAllocator = allocator.RawPoolAllocator;

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

/// The EFI image's handle that is passed to its entry point.
pub var handle: bits.Handle = undefined;
Expand Down Expand Up @@ -78,6 +79,16 @@ pub fn cwd() fd_t {
return .none;
}

pub const ListEntry = struct {
forward_link: ?*ListEntry,
backward_link: ?*ListEntry,
};

const uctx = @import("uefi/ucontext.zig");
pub const getcontext = uctx.getcontext;
pub const ucontext_t = uctx.ucontext_t;
pub const REG = uctx.REG;

test {
_ = table;
_ = protocol;
Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/uefi/bits.zig
Original file line number Diff line number Diff line change
Expand Up @@ -521,4 +521,4 @@ pub const FileSystemVolumeLabel = extern struct {

test {
std.testing.refAllDecls(@This());
}
}
2 changes: 1 addition & 1 deletion lib/std/os/uefi/protocol.zig
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ pub const Rng = @import("protocol/rng.zig").Rng;

// ** EFI Shell Specification Version 2.2, January 26, 2016

// Shell
pub const Shell = @import("protocol/shell.zig").Shell;
pub const ShellParameters = @import("protocol/shell_parameters.zig").ShellParameters;
// ShellDynamicCommand

Expand Down
2 changes: 1 addition & 1 deletion lib/std/os/uefi/protocol/media/file.zig
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub const File = extern struct {
}

/// Closes and deletes a file. This can fail, but the descriptor will still be closed.
///
///
/// Returns `true` if the file was successfully deleted, `false` otherwise.
pub fn delete(self: *const File) bool {
return self._delete(self) == .success;
Expand Down
70 changes: 70 additions & 0 deletions lib/std/os/uefi/protocol/shell.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
const uefi = @import("std").os.uefi;
const Status = uefi.Status;
const Handle = uefi.bits.Handle;
const Guid = uefi.bits.Guid;
const cc = uefi.bits.cc;

pub const Shell = extern struct {
execute: *const fn (parent_img_hndl: Handle, cmdline: ?[*:0]const u16, env: ?[*:null]const ?[*:0]const u16, status: *Status) callconv(cc) Status,
getEnv: *const fn (name: ?[*:0]const u16) callconv(cc) ?[*:0]const u16,
setEnv: *const fn (name: [*:0]const u16, value: [*:0]const u16, voltlie: bool) callconv(cc) Status,
getAlias: *const fn (alias: [*:0]const u16, voltlie: *bool) callconv(cc) ?[*:0]const u16,
setAlias: *const fn (cmd: [*:0]const u16, alias: [*:0]const u16, replace: bool, voltlie: bool) callconv(cc) Status,
getHelpText: *const fn (cmd: [*:0]const u16, sections: ?[*:0]const u16, helpText: *[*:0]u16) callconv(cc) Status,
getDevicePathFromMap: *const fn (mapping: [*:0]const u16) callconv(cc) ?*uefi.protocol.DevicePath,
getMapFromDevicePath: *const fn (devicePath: **const uefi.protocol.DevicePath) callconv(cc) ?[*:0]const u16,
getDevicePathFromFilePath: *const fn (path: [*:0]const u16) callconv(cc) *uefi.protocol.DevicePath,
getFilePathFromDevicePath: *const fn (devicePath: *uefi.protocol.DevicePath) callconv(cc) [*:0]const u16,
setMap: *const fn (devicePath: *uefi.protocol.DevicePath, mapping: [*:0]const u16) callconv(cc) Status,
getCurDir: *const fn (fsmap: ?[*:0]const u16) callconv(cc) ?[*:0]const u16,
setCurDir: *const fn (fs: ?[*:0]const u16, dir: [*:0]const u16) callconv(cc) Status,
openFileList: *const fn (path: [*:0]const u16, openMode: u64, fileList: **FileInfo) callconv(cc) Status,
freeFileList: *const fn (fileList: **FileInfo) callconv(cc) Status,
removeDupInFileList: *const fn (fileList: **FileInfo) callconv(cc) Status,
batchIsActive: *const fn () callconv(cc) bool,
isRootShell: *const fn () callconv(cc) bool,
enablePageBreak: *const fn () callconv(cc) void,
disablePageBreak: *const fn () callconv(cc) void,
getPageBreak: *const fn () callconv(cc) bool,
getDeviceName: *const fn (handle: Handle, flags: u32, lang: [*:0]const u8, bestDeviceName: *?[*:0]u16) callconv(cc) Status,
getFileInfo: *const fn (handle: FileHandle) callconv(cc) ?*uefi.bits.FileInfo,
setFileInfo: *const fn (handle: FileHandle, info: *const uefi.bits.FileInfo) callconv(cc) Status,
openFileByName: *const fn (filename: [*:0]const u16, handle: *FileHandle, mode: u64) callconv(cc) Status,
closeFile: *const fn (handle: FileHandle) callconv(cc) Status,
createFile: *const fn (filename: [*:0]const u16, attribs: u64, handle: *FileHandle) callconv(cc) Status,
readFile: *const fn (handle: FileHandle, size: *usize, buff: [*]u8) callconv(cc) Status,
writeFile: *const fn (handle: FileHandle, size: *usize, buff: [*]const u8) callconv(cc) Status,
deleteFile: *const fn (handle: FileHandle) callconv(cc) Status,
deleteFileByName: *const fn (filename: [*:0]const u16) callconv(cc) Status,
getFilePosition: *const fn (handle: FileHandle, pos: *u64) callconv(cc) Status,
setFilePosition: *const fn (handle: FileHandle, pos: u64) callconv(cc) Status,
flushFile: *const fn (handle: FileHandle) callconv(cc) Status,
findFiles: *const fn (pattern: [*:0]const u16, fileList: *?*FileInfo) callconv(cc) Status,
findFilesInDir: *const fn (handle: FileHandle, fileList: *?*FileInfo) callconv(cc) Status,
getFileSize: *const fn (handle: FileHandle, size: *u64) callconv(cc) Status,
openRoot: *const fn (devicePath: *uefi.protocol.DevicePath, handle: *FileHandle) callconv(cc) Status,
openRootByHandle: *const fn (deviceHandle: *Handle, fileHandle: *FileHandle) callconv(cc) Status,
executionBreak: uefi.bits.Event,
majorVersion: u32,
minorVersion: u32,

pub const FileHandle = *opaque {};

pub const FileInfo = struct {
link: uefi.ListEntry,
status: Status,
fullname: [*:0]const u16,
filename: [*:0]const u16,
handle: FileHandle,
info: *uefi.bits.FileInfo,
};

pub const guid align(8) = Guid{
.time_low = 0x6302d008,
.time_mid = 0x7f9b,
.time_high_and_version = 0x4f30,
.clock_seq_high_and_reserved = 0x87,
.clock_seq_low = 0xac,
.node = [_]u8{ 0x60, 0xc9, 0xfe, 0xf5, 0xda, 0x4e },
};
};
107 changes: 107 additions & 0 deletions lib/std/os/uefi/ucontext.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
const builtin = @import("builtin");
const std = @import("../../std.zig");

pub const REG = switch (builtin.cpu.arch) {
.x86_64 => struct {
pub const RAX = 0;
pub const RBX = 1;
pub const RCX = 2;
pub const RDX = 3;
pub const RSI = 4;
pub const RDI = 5;
pub const RBP = 6;
pub const RSP = 7;
pub const R8 = 8;
pub const R9 = 9;
pub const R10 = 10;
pub const R11 = 11;
pub const R12 = 12;
pub const R13 = 13;
pub const R14 = 14;
pub const R15 = 15;
pub const RIP = 16;
pub const EFL = 17;
},
else => @compileError("arch not supported"),
};

pub const fpregset = struct {
fcw: u16,
fsw: u16,
ftw: u8,
reserved1: u8,
fop: u16,
fip: u64,
fdp: u64,
mxcsr: u32,
mxcsr_mask: u32,
st: [8]u128,
xmm: [16]u128,
reserved2: [96]u8,
};

pub const mcontext_t = struct {
gregs: [18]usize,
fpregs: fpregset,
};

pub const ucontext_t = struct {
mcontext: mcontext_t,
};

fn gpRegisterOffset(comptime reg_index: comptime_int) usize {
return @offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "gregs") + @sizeOf(usize) * reg_index;
}

pub inline fn getcontext(context: *ucontext_t) usize {
switch (builtin.cpu.arch) {
.x86_64 => {
asm volatile (
\\ movq %%r8, %[r8_offset:c](%[context])
\\ movq %%r9, %[r9_offset:c](%[context])
\\ movq %%r10, %[r10_offset:c](%[context])
\\ movq %%r11, %[r11_offset:c](%[context])
\\ movq %%r12, %[r12_offset:c](%[context])
\\ movq %%r13, %[r13_offset:c](%[context])
\\ movq %%r14, %[r14_offset:c](%[context])
\\ movq %%r15, %[r15_offset:c](%[context])
\\ movq %%rdi, %[rdi_offset:c](%[context])
\\ movq %%rsi, %[rsi_offset:c](%[context])
\\ movq %%rbx, %[rbx_offset:c](%[context])
\\ movq %%rdx, %[rdx_offset:c](%[context])
\\ movq %%rax, %[rax_offset:c](%[context])
\\ movq %%rcx, %[rcx_offset:c](%[context])
\\ movq %%rbp, %[rbp_offset:c](%[context])
\\ movq %%rsp, %[rsp_offset:c](%[context])
\\ leaq (%%rip), %%rcx
\\ movq %%rcx, %[rip_offset:c](%[context])
\\ pushfq
\\ popq %[efl_offset:c](%[context])
:
: [context] "{rdi}" (context),
[r8_offset] "i" (comptime gpRegisterOffset(REG.R8)),
[r9_offset] "i" (comptime gpRegisterOffset(REG.R9)),
[r10_offset] "i" (comptime gpRegisterOffset(REG.R10)),
[r11_offset] "i" (comptime gpRegisterOffset(REG.R11)),
[r12_offset] "i" (comptime gpRegisterOffset(REG.R12)),
[r13_offset] "i" (comptime gpRegisterOffset(REG.R13)),
[r14_offset] "i" (comptime gpRegisterOffset(REG.R14)),
[r15_offset] "i" (comptime gpRegisterOffset(REG.R15)),
[rax_offset] "i" (comptime gpRegisterOffset(REG.RAX)),
[rbx_offset] "i" (comptime gpRegisterOffset(REG.RBX)),
[rcx_offset] "i" (comptime gpRegisterOffset(REG.RCX)),
[rdx_offset] "i" (comptime gpRegisterOffset(REG.RDX)),
[rsi_offset] "i" (comptime gpRegisterOffset(REG.RSI)),
[rdi_offset] "i" (comptime gpRegisterOffset(REG.RDI)),
[rsp_offset] "i" (comptime gpRegisterOffset(REG.RSP)),
[rbp_offset] "i" (comptime gpRegisterOffset(REG.RBP)),
[rip_offset] "i" (comptime gpRegisterOffset(REG.RIP)),
[efl_offset] "i" (comptime gpRegisterOffset(REG.EFL)),
: "cc", "memory", "rcx"
);
},
else => {},
}

return 0;
}
2 changes: 1 addition & 1 deletion lib/std/posix.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5842,7 +5842,7 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
pub fn uname() utsname {
if (native_os == .uefi)
return uefi.posix.uname();

var uts: utsname = undefined;
switch (errno(system.uname(&uts))) {
.SUCCESS => return uts,
Expand Down
Loading

0 comments on commit d096792

Please sign in to comment.