Skip to content

Conversation

dotcarmen
Copy link
Contributor

this PR updates BootServices and RuntimeServices to an idiomatic interface similar to the pattern used in std.os.uefi.protocol. Part of my crusade towards making std.os.uefi more idiomatic

@dotcarmen
Copy link
Contributor Author

@linusg
image

@linusg
Copy link
Collaborator

linusg commented Apr 2, 2025

another-one.png

It is appreciated! :^)

@dotcarmen dotcarmen force-pushed the ziggify-uefi-boot-runtime-services branch from ee41a75 to e4487d5 Compare April 2, 2025 17:22
Copy link
Collaborator

@linusg linusg left a 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,
Copy link
Contributor Author

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);
Copy link
Contributor Author

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(
Copy link
Contributor Author

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

Copy link
Contributor

@truemedian truemedian left a 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.

Comment on lines -35 to +48
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,
Copy link
Contributor Author

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 {
Copy link
Contributor Author

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

@dotcarmen dotcarmen force-pushed the ziggify-uefi-boot-runtime-services branch from 50823da to 0733531 Compare April 4, 2025 14:02
@@ -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);
Copy link
Contributor Author

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

@dotcarmen
Copy link
Contributor Author

dotcarmen commented Apr 4, 2025

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,
Copy link
Contributor Author

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 :(

@dotcarmen
Copy link
Contributor Author

haven't forgotten or abandoned this, I'm dealing with immigration stuffs :) I'll pick it up again soon

Copy link
Contributor Author

@dotcarmen dotcarmen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok i may have gone a little overboard with 7372d65 so i partly reverted it in 04e3728 to keep the number of files in the diff small :) those align(8)s aren't an error or anything, they're just unnecessary now :)

otherwise the rest of the PR comments have been addressed!

/// A handle to an event structure.
pub const Event = *opaque {};

pub const EventRegistration = opaque {};
Copy link
Contributor Author

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

Copy link
Contributor Author

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 🙃

Copy link
Contributor

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.

@dotcarmen dotcarmen force-pushed the ziggify-uefi-boot-runtime-services branch from 46d8e68 to d37be42 Compare April 13, 2025 21:45
@dotcarmen
Copy link
Contributor Author

dotcarmen commented Apr 14, 2025

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

/// A handle to an event structure.
pub const Event = *opaque {};

pub const EventRegistration = opaque {};
Copy link
Contributor

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.

Copy link
Contributor Author

@dotcarmen dotcarmen left a 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?

Comment on lines 25 to 32
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),
);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. define IntFittingRange for the relevant value range

Copy link
Contributor Author

@dotcarmen dotcarmen Apr 18, 2025

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 😅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_end - _start *

Comment on lines 71 to 70
pub fn invalid(value: InvalidValue) MemoryType {
const invalid_start = @intFromEnum(MemoryType.invalid_start);
return @enumFromInt(invalid_start + value);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. function for constructing such values ie pub const my_invalid: MemoryType = .invalid(0x2);

Copy link
Contributor

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?

Comment on lines 76 to 82
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);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. function for retrieving the value relative to the range's start

@kouosi
Copy link
Contributor

kouosi commented Apr 18, 2025

IMO, it is also a good idea to use _allocatePage in pool_allocator if alignment is 4096, as _allocatePool is slow.

@truemedian
Copy link
Contributor

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 allocatePool is significantly slower than allocatePages on at least a few firmware UEFI implementations

@kouosi
Copy link
Contributor

kouosi commented Apr 18, 2025

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 allocatePool is significantly slower than allocatePages on at least a few firmware UEFI implementations

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.

@dotcarmen dotcarmen force-pushed the ziggify-uefi-boot-runtime-services branch from 51ed5dc to 819a6c6 Compare July 2, 2025 11:10
@dotcarmen
Copy link
Contributor Author

rebased to latest master :)

Copy link
Collaborator

@linusg linusg left a 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!

@dotcarmen dotcarmen force-pushed the ziggify-uefi-boot-runtime-services branch 3 times, most recently from 3065959 to 819a6c6 Compare July 11, 2025 19:42
@dotcarmen
Copy link
Contributor Author

^ tried to rebase on latest master but the diff got nasty, i'll merge. reverted the rebase-push

@linusg
Copy link
Collaborator

linusg commented Jul 12, 2025

CI is failing

@dotcarmen
Copy link
Contributor Author

yup, just saw that lol, looking into it now

@linusg
Copy link
Collaborator

linusg commented Jul 12, 2025

Thanks for your patience with this! Let's merge 🎉

@linusg linusg enabled auto-merge (squash) July 12, 2025 11:40
@linusg linusg merged commit 5b4e982 into ziglang:master Jul 12, 2025
12 checks passed
@RossComputerGuy
Copy link
Contributor

LFG, glad to see this. I hope we can get #22226 next. I'll rebase it tonight after work, feel free to review.

dasimmet pushed a commit to dasimmet/zig that referenced this pull request Aug 4, 2025
* 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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants