master
1const std = @import("std");
2const uefi = std.os.uefi;
3const Handle = uefi.Handle;
4const Event = uefi.Event;
5const Guid = uefi.Guid;
6const cc = uefi.cc;
7const math = std.math;
8const assert = std.debug.assert;
9
10pub const BootServices = @import("tables/boot_services.zig").BootServices;
11pub const RuntimeServices = @import("tables/runtime_services.zig").RuntimeServices;
12pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;
13pub const SystemTable = @import("tables/system_table.zig").SystemTable;
14pub const TableHeader = @import("tables/table_header.zig").TableHeader;
15
16pub const EventNotify = *const fn (event: Event, ctx: *anyopaque) callconv(cc) void;
17
18pub const TimerDelay = enum(u32) {
19 cancel,
20 periodic,
21 relative,
22};
23
24pub const MemoryType = enum(u32) {
25 pub const Oem = math.IntFittingRange(
26 0,
27 @intFromEnum(MemoryType.oem_end) - @intFromEnum(MemoryType.oem_start),
28 );
29 pub const Vendor = math.IntFittingRange(
30 0,
31 @intFromEnum(MemoryType.vendor_end) - @intFromEnum(MemoryType.vendor_start),
32 );
33
34 /// can only be allocated using .allocate_any_pages mode unless you are explicitly targeting an interface that states otherwise
35 reserved_memory_type,
36 loader_code,
37 loader_data,
38 boot_services_code,
39 boot_services_data,
40 /// can only be allocated using .allocate_any_pages mode unless you are explicitly targeting an interface that states otherwise
41 runtime_services_code,
42 /// can only be allocated using .allocate_any_pages mode unless you are explicitly targeting an interface that states otherwise
43 runtime_services_data,
44 conventional_memory,
45 unusable_memory,
46 /// can only be allocated using .allocate_any_pages mode unless you are explicitly targeting an interface that states otherwise
47 acpi_reclaim_memory,
48 /// can only be allocated using .allocate_any_pages mode unless you are explicitly targeting an interface that states otherwise
49 acpi_memory_nvs,
50 memory_mapped_io,
51 memory_mapped_io_port_space,
52 pal_code,
53 persistent_memory,
54 unaccepted_memory,
55 max_memory_type,
56 invalid_start,
57 invalid_end = 0x6FFFFFFF,
58 /// MemoryType values in the range 0x70000000..0x7FFFFFFF are reserved for OEM use.
59 oem_start = 0x70000000,
60 oem_end = 0x7FFFFFFF,
61 /// MemoryType values in the range 0x80000000..0xFFFFFFFF are reserved for use by UEFI
62 /// OS loaders that are provided by operating system vendors.
63 vendor_start = 0x80000000,
64 vendor_end = 0xFFFFFFFF,
65 _,
66
67 pub fn fromOem(value: Oem) MemoryType {
68 const oem_start = @intFromEnum(MemoryType.oem_start);
69 return @enumFromInt(oem_start + value);
70 }
71
72 pub fn toOem(memtype: MemoryType) ?Oem {
73 const as_int = @intFromEnum(memtype);
74 const oem_start = @intFromEnum(MemoryType.oem_start);
75 if (as_int < oem_start) return null;
76 if (as_int > @intFromEnum(MemoryType.oem_end)) return null;
77 return @truncate(as_int - oem_start);
78 }
79
80 pub fn fromVendor(value: Vendor) MemoryType {
81 const vendor_start = @intFromEnum(MemoryType.vendor_start);
82 return @enumFromInt(vendor_start + value);
83 }
84
85 pub fn toVendor(memtype: MemoryType) ?Vendor {
86 const as_int = @intFromEnum(memtype);
87 const vendor_start = @intFromEnum(MemoryType.vendor_start);
88 if (as_int < @intFromEnum(MemoryType.vendor_end)) return null;
89 if (as_int > @intFromEnum(MemoryType.vendor_end)) return null;
90 return @truncate(as_int - vendor_start);
91 }
92
93 pub fn format(self: MemoryType, w: *std.Io.Writer) std.Io.Writer.Error!void {
94 if (self.toOem()) |oemval|
95 try w.print("OEM({X})", .{oemval})
96 else if (self.toVendor()) |vendorval|
97 try w.print("Vendor({X})", .{vendorval})
98 else if (std.enums.tagName(MemoryType, self)) |name|
99 try w.print("{s}", .{name})
100 else
101 try w.print("INVALID({X})", .{@intFromEnum(self)});
102 }
103};
104
105pub const MemoryDescriptorAttribute = packed struct(u64) {
106 uc: bool,
107 wc: bool,
108 wt: bool,
109 wb: bool,
110 uce: bool,
111 _pad1: u7 = 0,
112 wp: bool,
113 rp: bool,
114 xp: bool,
115 nv: bool,
116 more_reliable: bool,
117 ro: bool,
118 sp: bool,
119 cpu_crypto: bool,
120 _pad2: u43 = 0,
121 memory_runtime: bool,
122};
123
124pub const MemoryMapKey = enum(usize) { _ };
125
126pub const MemoryDescriptor = extern struct {
127 type: MemoryType,
128 physical_start: u64,
129 virtual_start: u64,
130 number_of_pages: u64,
131 attribute: MemoryDescriptorAttribute,
132};
133
134pub const MemoryMapInfo = struct {
135 key: MemoryMapKey,
136 descriptor_size: usize,
137 descriptor_version: u32,
138 /// The number of descriptors in the map.
139 len: usize,
140};
141
142pub const MemoryMapSlice = struct {
143 info: MemoryMapInfo,
144 ptr: [*]align(@alignOf(MemoryDescriptor)) u8,
145
146 pub fn iterator(self: MemoryMapSlice) MemoryDescriptorIterator {
147 return .{ .ctx = self };
148 }
149
150 pub fn get(self: MemoryMapSlice, index: usize) ?*MemoryDescriptor {
151 if (index >= self.info.len) return null;
152 return self.getUnchecked(index);
153 }
154
155 pub fn getUnchecked(self: MemoryMapSlice, index: usize) *MemoryDescriptor {
156 const offset: usize = index * self.info.descriptor_size;
157 return @ptrCast(@alignCast(self.ptr[offset..]));
158 }
159};
160
161pub const MemoryDescriptorIterator = struct {
162 ctx: MemoryMapSlice,
163 index: usize = 0,
164
165 pub fn next(self: *MemoryDescriptorIterator) ?*MemoryDescriptor {
166 const md = self.ctx.get(self.index) orelse return null;
167 self.index += 1;
168 return md;
169 }
170};
171
172pub const LocateSearchType = enum(u32) {
173 all_handles,
174 by_register_notify,
175 by_protocol,
176};
177
178pub const LocateSearch = union(LocateSearchType) {
179 all_handles,
180 by_register_notify: uefi.EventRegistration,
181 by_protocol: *const Guid,
182};
183
184pub const OpenProtocolAttributes = enum(u32) {
185 pub const Bits = packed struct(u32) {
186 by_handle_protocol: bool = false,
187 get_protocol: bool = false,
188 test_protocol: bool = false,
189 by_child_controller: bool = false,
190 by_driver: bool = false,
191 exclusive: bool = false,
192 reserved: u26 = 0,
193 };
194
195 by_handle_protocol = @bitCast(Bits{ .by_handle_protocol = true }),
196 get_protocol = @bitCast(Bits{ .get_protocol = true }),
197 test_protocol = @bitCast(Bits{ .test_protocol = true }),
198 by_child_controller = @bitCast(Bits{ .by_child_controller = true }),
199 by_driver = @bitCast(Bits{ .by_driver = true }),
200 by_driver_exclusive = @bitCast(Bits{ .by_driver = true, .exclusive = true }),
201 exclusive = @bitCast(Bits{ .exclusive = true }),
202 _,
203
204 pub fn fromBits(bits: Bits) OpenProtocolAttributes {
205 return @bitCast(bits);
206 }
207
208 pub fn toBits(self: OpenProtocolAttributes) Bits {
209 return @bitCast(self);
210 }
211};
212
213pub const OpenProtocolArgs = union(OpenProtocolAttributes) {
214 /// Used in the implementation of `handleProtocol`.
215 by_handle_protocol: struct { agent: ?Handle = null, controller: ?Handle = null },
216 /// Used by a driver to get a protocol interface from a handle. Care must be
217 /// taken when using this open mode because the driver that opens a protocol
218 /// interface in this manner will not be informed if the protocol interface
219 /// is uninstalled or reinstalled. The caller is also not required to close
220 /// the protocol interface with `closeProtocol`.
221 get_protocol: struct { agent: ?Handle = null, controller: ?Handle = null },
222 /// Used by a driver to test for the existence of a protocol interface on a
223 /// handle. The caller only use the return status code. The caller is also
224 /// not required to close the protocol interface with `closeProtocol`.
225 test_protocol: struct { agent: ?Handle = null, controller: ?Handle = null },
226 /// Used by bus drivers to show that a protocol interface is being used by one
227 /// of the child controllers of a bus. This information is used by
228 /// `BootServices.connectController` to recursively connect all child controllers
229 /// and by `BootServices.disconnectController` to get the list of child
230 /// controllers that a bus driver created.
231 by_child_controller: struct { agent: Handle, controller: Handle },
232 /// Used by a driver to gain access to a protocol interface. When this mode
233 /// is used, the driver’s Stop() function will be called by
234 /// `BootServices.disconnectController` if the protocol interface is reinstalled
235 /// or uninstalled. Once a protocol interface is opened by a driver with this
236 /// attribute, no other drivers will be allowed to open the same protocol interface
237 /// with the `.by_driver` attribute.
238 by_driver: struct { agent: Handle, controller: Handle },
239 /// Used by a driver to gain exclusive access to a protocol interface. If any
240 /// other drivers have the protocol interface opened with an attribute of
241 /// `.by_driver`, then an attempt will be made to remove them with
242 /// `BootServices.disconnectController`.
243 by_driver_exclusive: struct { agent: Handle, controller: Handle },
244 /// Used by applications to gain exclusive access to a protocol interface. If
245 /// any drivers have the protocol interface opened with an attribute of
246 /// `.by_driver`, then an attempt will be made to remove them by calling the
247 /// driver’s Stop() function.
248 exclusive: struct { agent: Handle, controller: ?Handle = null },
249};
250
251pub const ProtocolInformationEntry = extern struct {
252 agent_handle: ?Handle,
253 controller_handle: ?Handle,
254 attributes: OpenProtocolAttributes,
255 open_count: u32,
256};
257
258pub const InterfaceType = enum(u32) {
259 native,
260};
261
262pub const AllocateLocation = union(AllocateType) {
263 any,
264 max_address: [*]align(4096) uefi.Page,
265 address: [*]align(4096) uefi.Page,
266};
267
268pub const AllocateType = enum(u32) {
269 any,
270 max_address,
271 address,
272};
273
274pub const PhysicalAddress = u64;
275
276pub const CapsuleHeader = extern struct {
277 capsule_guid: Guid,
278 header_size: u32,
279 flags: u32,
280 capsule_image_size: u32,
281};
282
283pub const UefiCapsuleBlockDescriptor = extern struct {
284 length: u64,
285 address: extern union {
286 data_block: PhysicalAddress,
287 continuation_pointer: PhysicalAddress,
288 },
289};
290
291pub const ResetType = enum(u32) {
292 cold,
293 warm,
294 shutdown,
295 platform_specific,
296};
297
298pub const global_variable = Guid{
299 .time_low = 0x8be4df61,
300 .time_mid = 0x93ca,
301 .time_high_and_version = 0x11d2,
302 .clock_seq_high_and_reserved = 0xaa,
303 .clock_seq_low = 0x0d,
304 .node = [_]u8{ 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c },
305};
306
307test {
308 std.testing.refAllDeclsRecursive(@This());
309}