-
-
Notifications
You must be signed in to change notification settings - Fork 3k
std.os.uefi.tables: ziggify boot and runtime services #23441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
std.os.uefi.tables: ziggify boot and runtime services #23441
Conversation
It is appreciated! :^) |
ee41a75
to
e4487d5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a thorough review, LGTM at a high level
|
||
/// Returns the current memory map. | ||
getMemoryMap: *const fn (mmap_size: *usize, mmap: ?[*]MemoryDescriptor, map_key: *usize, descriptor_size: *usize, descriptor_version: *u32) callconv(cc) Status, | ||
_getMemoryMap: *const fn (mmap_size: *usize, mmap: [*]MemoryDescriptor, map_key: *MemoryMapKey, descriptor_size: *usize, descriptor_version: *u32) callconv(cc) Status, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i figured it's safer to obscure map_key
values since as far as i can tell it's meant to be assigned by the system (only retrievable via getMemoryMap
)
interfaces: anytype, | ||
) InstallProtocolInterfacesError!Handle { | ||
var hdl: ?Handle = handle; | ||
const args_tuple = protocolInterfaces(&hdl, interfaces); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i couldn't find an easier way to manage dynamically constructing a tuple than this helper :/
}; | ||
|
||
fn protocolInterfaces( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function is kinda gross :/ suggestions are welcome
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor nitpicks, but since we're overhauling boot services it's time we remove [*]MemoryDescriptor
and []MemoryDescriptor
from std.os.uefi, they are never valid because the size of the zig struct is almost never the size of the descriptor the firmware returns.
e4487d5
to
5ad806e
Compare
raiseTpl: *const fn (new_tpl: usize) callconv(cc) usize, | ||
raiseTpl: *const fn (new_tpl: TaskPriorityLevel) callconv(cc) TaskPriorityLevel, | ||
|
||
/// Restores a task's priority level to its previous value. | ||
restoreTpl: *const fn (old_tpl: usize) callconv(cc) void, | ||
restoreTpl: *const fn (old_tpl: TaskPriorityLevel) callconv(cc) void, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't make sense to define wrappers for these functions imo
|
||
/// Opens a protocol with a structure as the loaded image for a UEFI application | ||
pub fn openProtocolSt(self: *BootServices, comptime protocol: type, handle: Handle) !*protocol { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function is now basically the handleProtocol
function
50823da
to
0733531
Compare
@@ -639,7 +639,8 @@ pub fn defaultPanic( | |||
// 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(); | |||
@memcpy(exit_data, exit_msg[0..exit_data.len]); // Includes null terminator. | |||
_ = bs.exit(uefi.handle, .aborted, exit_data.len, exit_data.ptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaict this was a bug 😬 exit_data.len
for number of u16s but the spec says it's the number of bytes
i feel like this is ready for a final review :) i haven't tried it with my own project yet though, i'll tackle that later |
@@ -134,7 +134,7 @@ pub const BootServices = extern struct { | |||
_setWatchdogTimer: *const fn (timeout: usize, watchdog_code: u64, data_size: usize, watchdog_data: ?[*]const u16) callconv(cc) Status, | |||
|
|||
/// Connects one or more drives to a controller. | |||
_connectController: *const fn (controller_handle: Handle, driver_image_handle: ?[*:null]Handle, remaining_device_path: ?*const DevicePathProtocol, recursive: bool) callconv(cc) Status, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
really feels like [*:null]*anyopaque
should work :(
haven't forgotten or abandoned this, I'm dealing with immigration stuffs :) I'll pick it up again soon |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/std/os/uefi.zig
Outdated
/// A handle to an event structure. | ||
pub const Event = *opaque {}; | ||
|
||
pub const EventRegistration = opaque {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to not keep this as *const opaque{}
since it might be nice to have the namespace eventually? idk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually feel like it'd be handy to do that for Event
eventually 🙃
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standard describes an event registration as a VOID*
, and the standard provides absolutely no methods to operate on the registration value other than passing around the VOID*
, so I say it makes no sense to change this from a *opaque{}
.
If for some reason someone finds a good reason to make this a namespace that would be a better time to make this change.
46d8e68
to
d37be42
Compare
ah sorry i think i rebased and didn't mean to push the rebase 😅 here's the changes link for commits from last night: https://github.com/ziglang/zig/pull/23441/files/13858228112d8ee6798dd51032728f68c512bc5f..d37be4284b844684cd1f39b2fd543d8003dcb348 |
lib/std/os/uefi.zig
Outdated
/// A handle to an event structure. | ||
pub const Event = *opaque {}; | ||
|
||
pub const EventRegistration = opaque {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standard describes an event registration as a VOID*
, and the standard provides absolutely no methods to operate on the registration value other than passing around the VOID*
, so I say it makes no sense to change this from a *opaque{}
.
If for some reason someone finds a good reason to make this a namespace that would be a better time to make this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
decided to include a pattern that i've been experimenting with in another PR i'm working on for std.elf, wdyt?
lib/std/os/uefi/tables.zig
Outdated
pub const InvalidValue = math.IntFittingRange( | ||
@intFromEnum(MemoryType.invalid_start), | ||
@intFromEnum(MemoryType.invalid_end), | ||
); | ||
pub const OemValue = math.IntFittingRange( | ||
@intFromEnum(MemoryType.oem_start), | ||
@intFromEnum(MemoryType.oem_end), | ||
); | ||
pub const VendorValue = math.IntFittingRange( | ||
@intFromEnum(MemoryType.vendor_start), | ||
@intFromEnum(MemoryType.vendor_end), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- define
IntFittingRange
for the relevant value range
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh wait the start
should be 0 😅 and the end
should be _start - _end
😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_end - _start
*
lib/std/os/uefi/tables.zig
Outdated
pub fn invalid(value: InvalidValue) MemoryType { | ||
const invalid_start = @intFromEnum(MemoryType.invalid_start); | ||
return @enumFromInt(invalid_start + value); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- function for constructing such values ie
pub const my_invalid: MemoryType = .invalid(0x2);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we constructing invalid memory types?
lib/std/os/uefi/tables.zig
Outdated
pub fn getInvalid(memtype: MemoryType) ?InvalidValue { | ||
const as_int = @intFromEnum(memtype); | ||
const invalid_start = @intFromEnum(MemoryType.invalid_start); | ||
if (as_int < invalid_start) return null; | ||
if (as_int > @intFromEnum(MemoryType.invalid_end)) return null; | ||
return @truncate(as_int - invalid_start); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- function for retrieving the value relative to the range's start
IMO, it is also a good idea to use |
Not that that's a bad idea for the special case of exactly 4K alignment, I definitely would need a source to back up that |
I don't have an exact source to back this up, but testing on some hardware I have available I found that allocatePage is significantly slower than allocatePool. |
This backs out commit cdd9bd6.
51ed5dc
to
819a6c6
Compare
rebased to latest master :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did another full review, I have only nitpicks left. Tested locally against a small UEFI app - not nearly exhaustive, but builds. Happy to merge after this!
3065959
to
819a6c6
Compare
^ tried to rebase on latest master but the diff got nasty, i'll merge. reverted the rebase-push |
CI is failing |
yup, just saw that lol, looking into it now |
Thanks for your patience with this! Let's merge 🎉 |
LFG, glad to see this. I hope we can get #22226 next. I'll rebase it tonight after work, feel free to review. |
* std.os.uefi.tables: ziggify boot and runtime services * avoid T{} syntax Co-authored-by: linusg <[email protected]> * 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 <[email protected]> * 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 <[email protected]> Co-authored-by: truemedian <[email protected]>
this PR updates
BootServices
andRuntimeServices
to an idiomatic interface similar to the pattern used instd.os.uefi.protocol
. Part of my crusade towards makingstd.os.uefi
more idiomatic