const std = @import("std");
const uefi = std.os.uefi;
const Event = uefi.Event;
const Guid = uefi.Guid;
const Handle = uefi.Handle;
const Status = uefi.Status;
const TableHeader = uefi.tables.TableHeader;
const DevicePathProtocol = uefi.protocols.DevicePathProtocol;
pub const BootServices = extern struct {
hdr: TableHeader,
raiseTpl: *const fn (new_tpl: usize) callconv(.C) usize,
restoreTpl: *const fn (old_tpl: usize) callconv(.C) void,
allocatePages: *const fn (alloc_type: AllocateType, mem_type: MemoryType, pages: usize, memory: *[*]align(4096) u8) callconv(.C) Status,
freePages: *const fn (memory: [*]align(4096) u8, pages: usize) callconv(.C) Status,
getMemoryMap: *const fn (mmap_size: *usize, mmap: ?[*]MemoryDescriptor, mapKey: *usize, descriptor_size: *usize, descriptor_version: *u32) callconv(.C) Status,
allocatePool: *const fn (pool_type: MemoryType, size: usize, buffer: *[*]align(8) u8) callconv(.C) Status,
freePool: *const fn (buffer: [*]align(8) u8) callconv(.C) Status,
createEvent: *const fn (type: u32, notify_tpl: usize, notify_func: ?*const fn (Event, ?*anyopaque) callconv(.C) void, notifyCtx: ?*const anyopaque, event: *Event) callconv(.C) Status,
setTimer: *const fn (event: Event, type: TimerDelay, triggerTime: u64) callconv(.C) Status,
waitForEvent: *const fn (event_len: usize, events: [*]const Event, index: *usize) callconv(.C) Status,
signalEvent: *const fn (event: Event) callconv(.C) Status,
closeEvent: *const fn (event: Event) callconv(.C) Status,
checkEvent: *const fn (event: Event) callconv(.C) Status,
installProtocolInterface: *const fn (handle: Handle, protocol: *align(8) const Guid, interface_type: EfiInterfaceType, interface: *anyopaque) callconv(.C) Status,
reinstallProtocolInterface: *const fn (handle: Handle, protocol: *align(8) const Guid, old_interface: *anyopaque, new_interface: *anyopaque) callconv(.C) Status,
uninstallProtocolInterface: *const fn (handle: Handle, protocol: *align(8) const Guid, interface: *anyopaque) callconv(.C) Status,
handleProtocol: *const fn (handle: Handle, protocol: *align(8) const Guid, interface: *?*anyopaque) callconv(.C) Status,
reserved: *anyopaque,
registerProtocolNotify: *const fn (protocol: *align(8) const Guid, event: Event, registration: **anyopaque) callconv(.C) Status,
locateHandle: *const fn (search_type: LocateSearchType, protocol: ?*align(8) const Guid, search_key: ?*const anyopaque, bufferSize: *usize, buffer: [*]Handle) callconv(.C) Status,
locateDevicePath: *const fn (protocols: *align(8) const Guid, device_path: **const DevicePathProtocol, device: *?Handle) callconv(.C) Status,
installConfigurationTable: *const fn (guid: *align(8) const Guid, table: ?*anyopaque) callconv(.C) Status,
loadImage: *const fn (boot_policy: bool, parent_image_handle: Handle, device_path: ?*const DevicePathProtocol, source_buffer: ?[*]const u8, source_size: usize, imageHandle: *?Handle) callconv(.C) Status,
startImage: *const fn (image_handle: Handle, exit_data_size: ?*usize, exit_data: ?*[*]u16) callconv(.C) Status,
exit: *const fn (image_handle: Handle, exit_status: Status, exit_data_size: usize, exit_data: ?*const anyopaque) callconv(.C) Status,
unloadImage: *const fn (image_handle: Handle) callconv(.C) Status,
exitBootServices: *const fn (image_handle: Handle, map_key: usize) callconv(.C) Status,
getNextMonotonicCount: *const fn (count: *u64) callconv(.C) Status,
stall: *const fn (microseconds: usize) callconv(.C) Status,
setWatchdogTimer: *const fn (timeout: usize, watchdogCode: u64, data_size: usize, watchdog_data: ?[*]const u16) callconv(.C) Status,
connectController: *const fn (controller_handle: Handle, driver_image_handle: ?Handle, remaining_device_path: ?*DevicePathProtocol, recursive: bool) callconv(.C) Status,
disconnectController: *const fn (controller_handle: Handle, driver_image_handle: ?Handle, child_handle: ?Handle) callconv(.C) Status,
openProtocol: *const fn (handle: Handle, protocol: *align(8) const Guid, interface: *?*anyopaque, agent_handle: ?Handle, controller_handle: ?Handle, attributes: OpenProtocolAttributes) callconv(.C) Status,
closeProtocol: *const fn (handle: Handle, protocol: *align(8) const Guid, agentHandle: Handle, controller_handle: ?Handle) callconv(.C) Status,
openProtocolInformation: *const fn (handle: Handle, protocol: *align(8) const Guid, entry_buffer: *[*]ProtocolInformationEntry, entry_count: *usize) callconv(.C) Status,
protocolsPerHandle: *const fn (handle: Handle, protocol_buffer: *[*]*align(8) const Guid, protocol_buffer_count: *usize) callconv(.C) Status,
locateHandleBuffer: *const fn (search_type: LocateSearchType, protocol: ?*align(8) const Guid, search_key: ?*const anyopaque, num_handles: *usize, buffer: *[*]Handle) callconv(.C) Status,
locateProtocol: *const fn (protocol: *align(8) const Guid, registration: ?*const anyopaque, interface: *?*anyopaque) callconv(.C) Status,
installMultipleProtocolInterfaces: *const fn (handle: *Handle, ...) callconv(.C) Status,
uninstallMultipleProtocolInterfaces: *const fn (handle: *Handle, ...) callconv(.C) Status,
calculateCrc32: *const fn (data: [*]const u8, data_size: usize, *u32) callconv(.C) Status,
copyMem: *const fn (dest: [*]u8, src: [*]const u8, len: usize) callconv(.C) void,
setMem: *const fn (buffer: [*]u8, size: usize, value: u8) callconv(.C) void,
createEventEx: *const fn (type: u32, notify_tpl: usize, notify_func: EfiEventNotify, notify_ctx: *const anyopaque, event_group: *align(8) const Guid, event: *Event) callconv(.C) Status,
pub fn openProtocolSt(self: *BootServices, comptime protocol: type, handle: Handle) !*protocol {
if (!@hasDecl(protocol, "guid"))
@compileError("Protocol is missing guid!");
var ptr: ?*protocol = undefined;
try self.openProtocol(
handle,
&protocol.guid,
@ptrCast(*?*anyopaque, &ptr),
uefi.handle,
null,
uefi.tables.OpenProtocolAttributes{ .by_handle_protocol = true },
).err();
return ptr.?;
}
pub const signature: u64 = 0x56524553544f4f42;
pub const event_timer: u32 = 0x80000000;
pub const event_runtime: u32 = 0x40000000;
pub const event_notify_wait: u32 = 0x00000100;
pub const event_notify_signal: u32 = 0x00000200;
pub const event_signal_exit_boot_services: u32 = 0x00000201;
pub const event_signal_virtual_address_change: u32 = 0x00000202;
pub const tpl_application: usize = 4;
pub const tpl_callback: usize = 8;
pub const tpl_notify: usize = 16;
pub const tpl_high_level: usize = 31;
};
pub const EfiEventNotify = *const fn (event: Event, ctx: *anyopaque) callconv(.C) void;
pub const TimerDelay = enum(u32) {
TimerCancel,
TimerPeriodic,
TimerRelative,
};
pub const MemoryType = enum(u32) {
ReservedMemoryType,
LoaderCode,
LoaderData,
BootServicesCode,
BootServicesData,
RuntimeServicesCode,
RuntimeServicesData,
ConventionalMemory,
UnusableMemory,
ACPIReclaimMemory,
ACPIMemoryNVS,
MemoryMappedIO,
MemoryMappedIOPortSpace,
PalCode,
PersistentMemory,
MaxMemoryType,
_,
};
pub const MemoryDescriptorAttribute = packed struct(u64) {
uc: bool,
wc: bool,
wt: bool,
wb: bool,
uce: bool,
_pad1: u7 = 0,
wp: bool,
rp: bool,
xp: bool,
nv: bool,
more_reliable: bool,
ro: bool,
sp: bool,
cpu_crypto: bool,
_pad2: u43 = 0,
memory_runtime: bool,
};
pub const MemoryDescriptor = extern struct {
type: MemoryType,
physical_start: u64,
virtual_start: u64,
number_of_pages: u64,
attribute: MemoryDescriptorAttribute,
};
pub const LocateSearchType = enum(u32) {
AllHandles,
ByRegisterNotify,
ByProtocol,
};
pub const OpenProtocolAttributes = packed struct(u32) {
by_handle_protocol: bool = false,
get_protocol: bool = false,
test_protocol: bool = false,
by_child_controller: bool = false,
by_driver: bool = false,
exclusive: bool = false,
reserved: u26 = 0,
};
pub const ProtocolInformationEntry = extern struct {
agent_handle: ?Handle,
controller_handle: ?Handle,
attributes: OpenProtocolAttributes,
open_count: u32,
};
pub const EfiInterfaceType = enum(u32) {
EfiNativeInterface,
};
pub const AllocateType = enum(u32) {
AllocateAnyPages,
AllocateMaxAddress,
AllocateAddress,
};