Skip to content

Commit 5b4e982

Browse files
dotcarmenlinusgtruemedian
authored
std.os.uefi.tables: ziggify boot and runtime services (#23441)
* std.os.uefi.tables: ziggify boot and runtime services * avoid T{} syntax Co-authored-by: linusg <mail@linusgroh.de> * misc fixes * work * self-review quickfixes * dont make MemoryMapSlice generic * more review fixes, work * more work * more work * review fixes * update boot/runtime services references throughout codebase * self-review fixes * couple of fixes i forgot to commit earlier * fixes from integrating in my own project * fixes from refAllDeclsRecursive * Apply suggestions from code review Co-authored-by: truemedian <truemedian@gmail.com> * more fixes from review * fixes from project integration * make natural alignment of Guid align-8 * EventRegistration is a new opaque type * fix getNextHighMonotonicCount * fix locateProtocol * fix exit * partly revert 7372d65 * oops exit data_len is num of bytes * fixes from project integration * MapInfo consistency, MemoryType update per review * turn EventRegistration back into a pointer * forgot to finish updating MemoryType methods * fix IntFittingRange calls * set uefi.Page nat alignment * Back out "set uefi.Page nat alignment" This backs out commit cdd9bd6. * get rid of some error.NotFound-s * fix .exit call in panic * review comments, add format method * fix resetSystem data alignment * oops, didnt do a final refAllDeclsRecursive i guess * review comments * writergate update MemoryType.format * fix rename --------- Co-authored-by: linusg <mail@linusgroh.de> Co-authored-by: truemedian <truemedian@gmail.com>
1 parent bd97b66 commit 5b4e982

File tree

10 files changed

+1898
-145
lines changed

10 files changed

+1898
-145
lines changed

lib/std/Thread.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub fn sleep(nanoseconds: u64) void {
5858
const boot_services = std.os.uefi.system_table.boot_services.?;
5959
const us_from_ns = nanoseconds / std.time.ns_per_us;
6060
const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
61-
_ = boot_services.stall(us);
61+
boot_services.stall(us) catch unreachable;
6262
return;
6363
}
6464

lib/std/debug.zig

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -654,9 +654,8 @@ pub fn defaultPanic(
654654

655655
if (uefi.system_table.boot_services) |bs| {
656656
// ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220)
657-
const exit_data: []u16 = uefi.raw_pool_allocator.alloc(u16, exit_msg.len + 1) catch @trap();
658-
@memcpy(exit_data, exit_msg[0..exit_data.len]); // Includes null terminator.
659-
_ = bs.exit(uefi.handle, .aborted, exit_data.len, exit_data.ptr);
657+
const exit_data = uefi.raw_pool_allocator.dupeZ(u16, exit_msg) catch @trap();
658+
bs.exit(uefi.handle, .aborted, exit_data) catch {};
660659
}
661660
@trap();
662661
},

lib/std/os/uefi.zig

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,51 @@ pub var handle: Handle = undefined;
2424
/// A pointer to the EFI System Table that is passed to the EFI image's entry point.
2525
pub var system_table: *tables.SystemTable = undefined;
2626

27+
/// UEFI's memory interfaces exclusively act on 4096-byte pages.
28+
pub const Page = [4096]u8;
29+
2730
/// A handle to an event structure.
2831
pub const Event = *opaque {};
2932

33+
pub const EventRegistration = *const opaque {};
34+
35+
pub const EventType = packed struct(u32) {
36+
lo_context: u8 = 0,
37+
/// If an event of this type is not already in the signaled state, then
38+
/// the event’s NotificationFunction will be queued at the event’s NotifyTpl
39+
/// whenever the event is being waited on via EFI_BOOT_SERVICES.WaitForEvent()
40+
/// or EFI_BOOT_SERVICES.CheckEvent() .
41+
wait: bool = false,
42+
/// The event’s NotifyFunction is queued whenever the event is signaled.
43+
signal: bool = false,
44+
hi_context: u20 = 0,
45+
/// The event is allocated from runtime memory. If an event is to be signaled
46+
/// after the call to EFI_BOOT_SERVICES.ExitBootServices() the event’s data
47+
/// structure and notification function need to be allocated from runtime
48+
/// memory.
49+
runtime: bool = false,
50+
timer: bool = false,
51+
52+
/// This event should not be combined with any other event types. This event
53+
/// type is functionally equivalent to the EFI_EVENT_GROUP_EXIT_BOOT_SERVICES
54+
/// event group.
55+
pub const signal_exit_boot_services: EventType = .{
56+
.signal = true,
57+
.lo_context = 1,
58+
};
59+
60+
/// The event is to be notified by the system when SetVirtualAddressMap()
61+
/// is performed. This event type is a composite of EVT_NOTIFY_SIGNAL,
62+
/// EVT_RUNTIME, and EVT_RUNTIME_CONTEXT and should not be combined with
63+
/// any other event types.
64+
pub const signal_virtual_address_change: EventType = .{
65+
.runtime = true,
66+
.hi_context = 0x20000,
67+
.signal = true,
68+
.lo_context = 2,
69+
};
70+
};
71+
3072
/// The calling convention used for all external functions part of the UEFI API.
3173
pub const cc: std.builtin.CallingConvention = switch (@import("builtin").target.cpu.arch) {
3274
.x86_64 => .{ .x86_64_win = .{} },
@@ -52,15 +94,19 @@ pub const IpAddress = extern union {
5294

5395
/// GUIDs are align(8) unless otherwise specified.
5496
pub const Guid = extern struct {
55-
time_low: u32,
97+
comptime {
98+
std.debug.assert(std.mem.Alignment.of(Guid) == .@"8");
99+
}
100+
101+
time_low: u32 align(8),
56102
time_mid: u16,
57103
time_high_and_version: u16,
58104
clock_seq_high_and_reserved: u8,
59105
clock_seq_low: u8,
60106
node: [6]u8,
61107

62108
/// Format GUID into hexadecimal lowercase xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
63-
pub fn format(self: @This(), writer: *std.io.Writer) std.io.Writer.Error!void {
109+
pub fn format(self: Guid, writer: *std.io.Writer) std.io.Writer.Error!void {
64110
const time_low = @byteSwap(self.time_low);
65111
const time_mid = @byteSwap(self.time_mid);
66112
const time_high_and_version = @byteSwap(self.time_high_and_version);
@@ -75,7 +121,7 @@ pub const Guid = extern struct {
75121
});
76122
}
77123

78-
pub fn eql(a: std.os.uefi.Guid, b: std.os.uefi.Guid) bool {
124+
pub fn eql(a: Guid, b: Guid) bool {
79125
return a.time_low == b.time_low and
80126
a.time_mid == b.time_mid and
81127
a.time_high_and_version == b.time_high_and_version and

lib/std/os/uefi/pool_allocator.zig

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ const UefiPoolAllocator = struct {
2828

2929
const full_len = metadata_len + len;
3030

31-
var unaligned_ptr: [*]align(8) u8 = undefined;
32-
if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, full_len, &unaligned_ptr) != .success) return null;
31+
const unaligned_slice = uefi.system_table.boot_services.?.allocatePool(
32+
uefi.efi_pool_memory_type,
33+
full_len,
34+
) catch return null;
3335

34-
const unaligned_addr = @intFromPtr(unaligned_ptr);
36+
const unaligned_addr = @intFromPtr(unaligned_slice.ptr);
3537
const aligned_addr = mem.alignForward(usize, unaligned_addr + @sizeOf(usize), ptr_align);
3638

37-
const aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr);
38-
getHeader(aligned_ptr).* = unaligned_ptr;
39+
const aligned_ptr = unaligned_slice.ptr + (aligned_addr - unaligned_addr);
40+
getHeader(aligned_ptr).* = unaligned_slice.ptr;
3941

4042
return aligned_ptr;
4143
}
@@ -76,7 +78,7 @@ const UefiPoolAllocator = struct {
7678
) void {
7779
_ = alignment;
7880
_ = ret_addr;
79-
_ = uefi.system_table.boot_services.?.freePool(getHeader(buf.ptr).*);
81+
uefi.system_table.boot_services.?.freePool(getHeader(buf.ptr).*) catch unreachable;
8082
}
8183
};
8284

@@ -117,10 +119,12 @@ fn uefi_alloc(
117119

118120
std.debug.assert(@intFromEnum(alignment) <= 3);
119121

120-
var ptr: [*]align(8) u8 = undefined;
121-
if (uefi.system_table.boot_services.?.allocatePool(uefi.efi_pool_memory_type, len, &ptr) != .success) return null;
122+
const slice = uefi.system_table.boot_services.?.allocatePool(
123+
uefi.efi_pool_memory_type,
124+
len,
125+
) catch return null;
122126

123-
return ptr;
127+
return slice.ptr;
124128
}
125129

126130
fn uefi_resize(
@@ -161,5 +165,5 @@ fn uefi_free(
161165
) void {
162166
_ = alignment;
163167
_ = ret_addr;
164-
_ = uefi.system_table.boot_services.?.freePool(@alignCast(buf.ptr));
168+
uefi.system_table.boot_services.?.freePool(@alignCast(buf.ptr)) catch unreachable;
165169
}

0 commit comments

Comments
 (0)