authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-18 14:16:30-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-18 14:16:30-05:00
log2c24bf2f79af8d258956d3169e0c64ac8e71e51d
tree961a8deb2a18ecc384ed1ce6ad84196e18410975
parent60bb1d4e1c262ff36c18cefe974aa2f773483af4
parentff6ece3811a1cb44a90986d543d1583a40629edf
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #10604 from fifty-six/master

std/os/uefi: additional improvements/fixes

13 files changed, 663 insertions(+), 289 deletions(-)

lib/std/builtin.zig+46-1
......@@ -758,7 +758,52 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
758758 std.os.abort();
759759 },
760760 .uefi => {
761 // TODO look into using the debug info and logging helpful messages
761 const uefi = std.os.uefi;
762
763 const ExitData = struct {
764 pub fn create_exit_data(exit_msg: []const u8, exit_size: *usize) ![*:0]u16 {
765 // Need boot services for pool allocation
766 if (uefi.system_table.boot_services == null) {
767 return error.BootServicesUnavailable;
768 }
769
770 // ExitData buffer must be allocated using boot_services.allocatePool
771 var utf16: []u16 = try uefi.raw_pool_allocator.alloc(u16, 256);
772 errdefer uefi.raw_pool_allocator.free(utf16);
773
774 if (exit_msg.len > 255) {
775 return error.MessageTooLong;
776 }
777
778 var fmt: [256]u8 = undefined;
779 var slice = try std.fmt.bufPrint(&fmt, "\r\nerr: {s}\r\n", .{exit_msg});
780
781 var len = try std.unicode.utf8ToUtf16Le(utf16, slice);
782
783 utf16[len] = 0;
784
785 exit_size.* = 256;
786
787 return @ptrCast([*:0]u16, utf16.ptr);
788 }
789 };
790
791 var exit_size: usize = 0;
792 var exit_data = ExitData.create_exit_data(msg, &exit_size) catch null;
793
794 if (exit_data) |data| {
795 if (uefi.system_table.std_err) |out| {
796 _ = out.setAttribute(uefi.protocols.SimpleTextOutputProtocol.red);
797 _ = out.outputString(data);
798 _ = out.setAttribute(uefi.protocols.SimpleTextOutputProtocol.white);
799 }
800 }
801
802 if (uefi.system_table.boot_services) |bs| {
803 _ = bs.exit(uefi.handle, .Aborted, exit_size, exit_data);
804 }
805
806 // Didn't have boot_services, just fallback to whatever.
762807 std.os.abort();
763808 },
764809 else => {
lib/std/os/uefi.zig+12-2
......@@ -23,6 +23,18 @@ pub var system_table: *tables.SystemTable = undefined;
2323/// A handle to an event structure.
2424pub const Event = *opaque {};
2525
26pub const MacAddress = extern struct {
27 address: [32]u8,
28};
29
30pub const Ipv4Address = extern struct {
31 address: [4]u8,
32};
33
34pub const Ipv6Address = extern struct {
35 address: [16]u8,
36};
37
2638/// GUIDs must be align(8)
2739pub const Guid = extern struct {
2840 time_low: u32,
......@@ -86,7 +98,6 @@ pub const Time = extern struct {
8698
8799 /// 0 - 59
88100 second: u8,
89 _pad1: u8,
90101
91102 /// 0 - 999999999
92103 nanosecond: u32,
......@@ -103,7 +114,6 @@ pub const Time = extern struct {
103114 /// If true, the time is affected by daylight savings time.
104115 adjust_daylight: bool,
105116 },
106 _pad2: u8,
107117
108118 /// Time is to be interpreted as local time
109119 pub const unspecified_timezone: i16 = 0x7ff;
lib/std/os/uefi/protocols.zig+43-99
......@@ -1,100 +1,44 @@
1pub const LoadedImageProtocol = @import("protocols/loaded_image_protocol.zig").LoadedImageProtocol;
2pub const loaded_image_device_path_protocol_guid = @import("protocols/loaded_image_protocol.zig").loaded_image_device_path_protocol_guid;
3
4pub const AcpiDevicePath = @import("protocols/device_path_protocol.zig").AcpiDevicePath;
5pub const BiosBootSpecificationDevicePath = @import("protocols/device_path_protocol.zig").BiosBootSpecificationDevicePath;
6pub const DevicePath = @import("protocols/device_path_protocol.zig").DevicePath;
7pub const DevicePathProtocol = @import("protocols/device_path_protocol.zig").DevicePathProtocol;
8pub const DevicePathType = @import("protocols/device_path_protocol.zig").DevicePathType;
9pub const EndDevicePath = @import("protocols/device_path_protocol.zig").EndDevicePath;
10pub const HardwareDevicePath = @import("protocols/device_path_protocol.zig").HardwareDevicePath;
11pub const MediaDevicePath = @import("protocols/device_path_protocol.zig").MediaDevicePath;
12pub const MessagingDevicePath = @import("protocols/device_path_protocol.zig").MessagingDevicePath;
13
14pub const SimpleFileSystemProtocol = @import("protocols/simple_file_system_protocol.zig").SimpleFileSystemProtocol;
15pub const FileProtocol = @import("protocols/file_protocol.zig").FileProtocol;
16pub const FileInfo = @import("protocols/file_protocol.zig").FileInfo;
17pub const FileSystemInfo = @import("protocols/file_protocol.zig").FileSystemInfo;
18
19pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
20pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
21pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;
22pub const SimpleTextInputProtocol = @import("protocols/simple_text_input_protocol.zig").SimpleTextInputProtocol;
23pub const SimpleTextInputExProtocol = @import("protocols/simple_text_input_ex_protocol.zig").SimpleTextInputExProtocol;
24
25pub const SimpleTextOutputMode = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputMode;
26pub const SimpleTextOutputProtocol = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputProtocol;
27
28pub const SimplePointerMode = @import("protocols/simple_pointer_protocol.zig").SimplePointerMode;
29pub const SimplePointerProtocol = @import("protocols/simple_pointer_protocol.zig").SimplePointerProtocol;
30pub const SimplePointerState = @import("protocols/simple_pointer_protocol.zig").SimplePointerState;
31
32pub const AbsolutePointerMode = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerMode;
33pub const AbsolutePointerProtocol = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerProtocol;
34pub const AbsolutePointerState = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerState;
35
36pub const GraphicsOutputBltPixel = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltPixel;
37pub const GraphicsOutputBltOperation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltOperation;
38pub const GraphicsOutputModeInformation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputModeInformation;
39pub const GraphicsOutputProtocol = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocol;
40pub const GraphicsOutputProtocolMode = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocolMode;
41pub const GraphicsPixelFormat = @import("protocols/graphics_output_protocol.zig").GraphicsPixelFormat;
42pub const PixelBitmask = @import("protocols/graphics_output_protocol.zig").PixelBitmask;
43
44pub const EdidDiscoveredProtocol = @import("protocols/edid_discovered_protocol.zig").EdidDiscoveredProtocol;
45
46pub const EdidActiveProtocol = @import("protocols/edid_active_protocol.zig").EdidActiveProtocol;
47
48pub const EdidOverrideProtocol = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocol;
49pub const EdidOverrideProtocolAttributes = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocolAttributes;
50
51pub const SimpleNetworkProtocol = @import("protocols/simple_network_protocol.zig").SimpleNetworkProtocol;
52pub const MacAddress = @import("protocols/simple_network_protocol.zig").MacAddress;
53pub const SimpleNetworkMode = @import("protocols/simple_network_protocol.zig").SimpleNetworkMode;
54pub const SimpleNetworkReceiveFilter = @import("protocols/simple_network_protocol.zig").SimpleNetworkReceiveFilter;
55pub const SimpleNetworkState = @import("protocols/simple_network_protocol.zig").SimpleNetworkState;
56pub const NetworkStatistics = @import("protocols/simple_network_protocol.zig").NetworkStatistics;
57pub const SimpleNetworkInterruptStatus = @import("protocols/simple_network_protocol.zig").SimpleNetworkInterruptStatus;
58
59pub const ManagedNetworkServiceBindingProtocol = @import("protocols/managed_network_service_binding_protocol.zig").ManagedNetworkServiceBindingProtocol;
60pub const ManagedNetworkProtocol = @import("protocols/managed_network_protocol.zig").ManagedNetworkProtocol;
61pub const ManagedNetworkConfigData = @import("protocols/managed_network_protocol.zig").ManagedNetworkConfigData;
62pub const ManagedNetworkCompletionToken = @import("protocols/managed_network_protocol.zig").ManagedNetworkCompletionToken;
63pub const ManagedNetworkReceiveData = @import("protocols/managed_network_protocol.zig").ManagedNetworkReceiveData;
64pub const ManagedNetworkTransmitData = @import("protocols/managed_network_protocol.zig").ManagedNetworkTransmitData;
65pub const ManagedNetworkFragmentData = @import("protocols/managed_network_protocol.zig").ManagedNetworkFragmentData;
66
67pub const Ip6ServiceBindingProtocol = @import("protocols/ip6_service_binding_protocol.zig").Ip6ServiceBindingProtocol;
68pub const Ip6Protocol = @import("protocols/ip6_protocol.zig").Ip6Protocol;
69pub const Ip6ModeData = @import("protocols/ip6_protocol.zig").Ip6ModeData;
70pub const Ip6ConfigData = @import("protocols/ip6_protocol.zig").Ip6ConfigData;
71pub const Ip6Address = @import("protocols/ip6_protocol.zig").Ip6Address;
72pub const Ip6AddressInfo = @import("protocols/ip6_protocol.zig").Ip6AddressInfo;
73pub const Ip6RouteTable = @import("protocols/ip6_protocol.zig").Ip6RouteTable;
74pub const Ip6NeighborState = @import("protocols/ip6_protocol.zig").Ip6NeighborState;
75pub const Ip6NeighborCache = @import("protocols/ip6_protocol.zig").Ip6NeighborCache;
76pub const Ip6IcmpType = @import("protocols/ip6_protocol.zig").Ip6IcmpType;
77pub const Ip6CompletionToken = @import("protocols/ip6_protocol.zig").Ip6CompletionToken;
78
79pub const Ip6ConfigProtocol = @import("protocols/ip6_config_protocol.zig").Ip6ConfigProtocol;
80pub const Ip6ConfigDataType = @import("protocols/ip6_config_protocol.zig").Ip6ConfigDataType;
81
82pub const Udp6ServiceBindingProtocol = @import("protocols/udp6_service_binding_protocol.zig").Udp6ServiceBindingProtocol;
83pub const Udp6Protocol = @import("protocols/udp6_protocol.zig").Udp6Protocol;
84pub const Udp6ConfigData = @import("protocols/udp6_protocol.zig").Udp6ConfigData;
85pub const Udp6CompletionToken = @import("protocols/udp6_protocol.zig").Udp6CompletionToken;
86pub const Udp6ReceiveData = @import("protocols/udp6_protocol.zig").Udp6ReceiveData;
87pub const Udp6TransmitData = @import("protocols/udp6_protocol.zig").Udp6TransmitData;
88pub const Udp6SessionData = @import("protocols/udp6_protocol.zig").Udp6SessionData;
89pub const Udp6FragmentData = @import("protocols/udp6_protocol.zig").Udp6FragmentData;
90
1// Misc
2pub usingnamespace @import("protocols/loaded_image_protocol.zig");
3pub usingnamespace @import("protocols/device_path_protocol.zig");
4pub usingnamespace @import("protocols/rng_protocol.zig");
5pub usingnamespace @import("protocols/shell_parameters_protocol.zig");
6
7// Files
8pub usingnamespace @import("protocols/simple_file_system_protocol.zig");
9pub usingnamespace @import("protocols/file_protocol.zig");
10
11// Text
12pub usingnamespace @import("protocols/simple_text_input_protocol.zig");
13pub usingnamespace @import("protocols/simple_text_input_ex_protocol.zig");
14pub usingnamespace @import("protocols/simple_text_output_protocol.zig");
15
16// Pointer
17pub usingnamespace @import("protocols/simple_pointer_protocol.zig");
18pub usingnamespace @import("protocols/absolute_pointer_protocol.zig");
19
20pub usingnamespace @import("protocols/graphics_output_protocol.zig");
21
22// edid
23pub usingnamespace @import("protocols/edid_discovered_protocol.zig");
24pub usingnamespace @import("protocols/edid_active_protocol.zig");
25pub usingnamespace @import("protocols/edid_override_protocol.zig");
26
27// Network
28pub usingnamespace @import("protocols/simple_network_protocol.zig");
29pub usingnamespace @import("protocols/managed_network_service_binding_protocol.zig");
30pub usingnamespace @import("protocols/managed_network_protocol.zig");
31
32// ip6
33pub usingnamespace @import("protocols/ip6_service_binding_protocol.zig");
34pub usingnamespace @import("protocols/ip6_protocol.zig");
35pub usingnamespace @import("protocols/ip6_config_protocol.zig");
36
37// udp6
38pub usingnamespace @import("protocols/udp6_service_binding_protocol.zig");
39pub usingnamespace @import("protocols/udp6_protocol.zig");
40
41// hii
9142pub const hii = @import("protocols/hii.zig");
92pub const HIIDatabaseProtocol = @import("protocols/hii_database_protocol.zig").HIIDatabaseProtocol;
93pub const HIIPopupProtocol = @import("protocols/hii_popup_protocol.zig").HIIPopupProtocol;
94pub const HIIPopupStyle = @import("protocols/hii_popup_protocol.zig").HIIPopupStyle;
95pub const HIIPopupType = @import("protocols/hii_popup_protocol.zig").HIIPopupType;
96pub const HIIPopupSelection = @import("protocols/hii_popup_protocol.zig").HIIPopupSelection;
97
98pub const RNGProtocol = @import("protocols/rng_protocol.zig").RNGProtocol;
99
100pub const ShellParametersProtocol = @import("protocols/shell_parameters_protocol.zig").ShellParametersProtocol;
43pub usingnamespace @import("protocols/hii_database_protocol.zig");
44pub usingnamespace @import("protocols/hii_popup_protocol.zig");
lib/std/os/uefi/protocols/absolute_pointer_protocol.zig+2-6
......@@ -40,9 +40,7 @@ pub const AbsolutePointerMode = extern struct {
4040 attributes: packed struct {
4141 supports_alt_active: bool,
4242 supports_pressure_as_z: bool,
43 _pad1: u6,
44 _pad2: u8,
45 _pad3: u16,
43 _pad: u30 = 0,
4644 },
4745};
4846
......@@ -53,8 +51,6 @@ pub const AbsolutePointerState = extern struct {
5351 active_buttons: packed struct {
5452 touch_active: bool,
5553 alt_active: bool,
56 _pad1: u6,
57 _pad2: u8,
58 _pad3: u16,
54 _pad: u30 = 0,
5955 },
6056};
lib/std/os/uefi/protocols/device_path_protocol.zig+349-91
......@@ -72,63 +72,39 @@ pub const DevicePathProtocol = packed struct {
7272 }
7373
7474 pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath {
75 return switch (self.type) {
76 .Hardware => blk: {
77 const hardware: ?HardwareDevicePath = switch (@intToEnum(HardwareDevicePath.Subtype, self.subtype)) {
78 .Pci => .{ .Pci = @ptrCast(*const HardwareDevicePath.PciDevicePath, self) },
79 .PcCard => .{ .PcCard = @ptrCast(*const HardwareDevicePath.PcCardDevicePath, self) },
80 .MemoryMapped => .{ .MemoryMapped = @ptrCast(*const HardwareDevicePath.MemoryMappedDevicePath, self) },
81 .Vendor => .{ .Vendor = @ptrCast(*const HardwareDevicePath.VendorDevicePath, self) },
82 .Controller => .{ .Controller = @ptrCast(*const HardwareDevicePath.ControllerDevicePath, self) },
83 .Bmc => .{ .Bmc = @ptrCast(*const HardwareDevicePath.BmcDevicePath, self) },
84 _ => null,
85 };
86 break :blk if (hardware) |h| .{ .Hardware = h } else null;
87 },
88 .Acpi => blk: {
89 const acpi: ?AcpiDevicePath = switch (@intToEnum(AcpiDevicePath.Subtype, self.subtype)) {
90 else => null, // TODO
91 };
92 break :blk if (acpi) |a| .{ .Acpi = a } else null;
93 },
94 .Messaging => blk: {
95 const messaging: ?MessagingDevicePath = switch (@intToEnum(MessagingDevicePath.Subtype, self.subtype)) {
96 else => null, // TODO
97 };
98 break :blk if (messaging) |m| .{ .Messaging = m } else null;
99 },
100 .Media => blk: {
101 const media: ?MediaDevicePath = switch (@intToEnum(MediaDevicePath.Subtype, self.subtype)) {
102 .HardDrive => .{ .HardDrive = @ptrCast(*const MediaDevicePath.HardDriveDevicePath, self) },
103 .Cdrom => .{ .Cdrom = @ptrCast(*const MediaDevicePath.CdromDevicePath, self) },
104 .Vendor => .{ .Vendor = @ptrCast(*const MediaDevicePath.VendorDevicePath, self) },
105 .FilePath => .{ .FilePath = @ptrCast(*const MediaDevicePath.FilePathDevicePath, self) },
106 .MediaProtocol => .{ .MediaProtocol = @ptrCast(*const MediaDevicePath.MediaProtocolDevicePath, self) },
107 .PiwgFirmwareFile => .{ .PiwgFirmwareFile = @ptrCast(*const MediaDevicePath.PiwgFirmwareFileDevicePath, self) },
108 .PiwgFirmwareVolume => .{ .PiwgFirmwareVolume = @ptrCast(*const MediaDevicePath.PiwgFirmwareVolumeDevicePath, self) },
109 .RelativeOffsetRange => .{ .RelativeOffsetRange = @ptrCast(*const MediaDevicePath.RelativeOffsetRangeDevicePath, self) },
110 .RamDisk => .{ .RamDisk = @ptrCast(*const MediaDevicePath.RamDiskDevicePath, self) },
111 _ => null,
112 };
113 break :blk if (media) |m| .{ .Media = m } else null;
114 },
115 .BiosBootSpecification => blk: {
116 const bbs: ?BiosBootSpecificationDevicePath = switch (@intToEnum(BiosBootSpecificationDevicePath.Subtype, self.subtype)) {
117 .BBS101 => .{ .BBS101 = @ptrCast(*const BiosBootSpecificationDevicePath.BBS101DevicePath, self) },
118 _ => null,
119 };
120 break :blk if (bbs) |b| .{ .BiosBootSpecification = b } else null;
121 },
122 .End => blk: {
123 const end: ?EndDevicePath = switch (@intToEnum(EndDevicePath.Subtype, self.subtype)) {
124 .EndEntire => .{ .EndEntire = @ptrCast(*const EndDevicePath.EndEntireDevicePath, self) },
125 .EndThisInstance => .{ .EndThisInstance = @ptrCast(*const EndDevicePath.EndThisInstanceDevicePath, self) },
126 _ => null,
127 };
128 break :blk if (end) |e| .{ .End = e } else null;
129 },
130 _ => null,
131 };
75 inline for (@typeInfo(DevicePath).Union.fields) |ufield| {
76 const enum_value = std.meta.stringToEnum(DevicePathType, ufield.name);
77
78 // Got the associated union type for self.type, now
79 // we need to initialize it and its subtype
80 if (self.type == enum_value) {
81 var subtype = self.initSubtype(ufield.field_type);
82
83 if (subtype) |sb| {
84 // e.g. return .{ .Hardware = .{ .Pci = @ptrCast(...) } }
85 return @unionInit(DevicePath, ufield.name, sb);
86 }
87 }
88 }
89
90 return null;
91 }
92
93 pub fn initSubtype(self: *const DevicePathProtocol, comptime TUnion: type) ?TUnion {
94 const type_info = @typeInfo(TUnion).Union;
95 const TTag = type_info.tag_type.?;
96
97 inline for (type_info.fields) |subtype| {
98 // The tag names match the union names, so just grab that off the enum
99 const tag_val: u8 = @enumToInt(@field(TTag, subtype.name));
100
101 if (self.subtype == tag_val) {
102 // e.g. expr = .{ .Pci = @ptrCast(...) }
103 return @unionInit(TUnion, subtype.name, @ptrCast(subtype.field_type, self));
104 }
105 }
106
107 return null;
132108 }
133109};
134110
......@@ -173,79 +149,113 @@ pub const HardwareDevicePath = union(Subtype) {
173149 type: DevicePathType,
174150 subtype: Subtype,
175151 length: u16,
176 // TODO
152 function: u8,
153 device: u8,
177154 };
178155
179156 pub const PcCardDevicePath = packed struct {
180157 type: DevicePathType,
181158 subtype: Subtype,
182159 length: u16,
183 // TODO
160 function_number: u8,
184161 };
185162
186163 pub const MemoryMappedDevicePath = packed struct {
187164 type: DevicePathType,
188165 subtype: Subtype,
189166 length: u16,
190 // TODO
167 memory_type: u32,
168 start_address: u64,
169 end_address: u64,
191170 };
192171
193172 pub const VendorDevicePath = packed struct {
194173 type: DevicePathType,
195174 subtype: Subtype,
196175 length: u16,
197 // TODO
176 vendor_guid: Guid,
198177 };
199178
200179 pub const ControllerDevicePath = packed struct {
201180 type: DevicePathType,
202181 subtype: Subtype,
203182 length: u16,
204 // TODO
183 controller_number: u32,
205184 };
206185
207186 pub const BmcDevicePath = packed struct {
208187 type: DevicePathType,
209188 subtype: Subtype,
210189 length: u16,
211 // TODO
190 interface_type: u8,
191 base_address: usize,
212192 };
213193};
214194
215195pub const AcpiDevicePath = union(Subtype) {
216 Acpi: void, // TODO
217 ExpandedAcpi: void, // TODO
218 Adr: void, // TODO
219 Nvdimm: void, // TODO
196 Acpi: *const BaseAcpiDevicePath,
197 ExpandedAcpi: *const ExpandedAcpiDevicePath,
198 Adr: *const AdrDevicePath,
220199
221200 pub const Subtype = enum(u8) {
222201 Acpi = 1,
223202 ExpandedAcpi = 2,
224203 Adr = 3,
225 Nvdimm = 4,
226204 _,
227205 };
206
207 pub const BaseAcpiDevicePath = packed struct {
208 type: DevicePathType,
209 subtype: Subtype,
210 length: u16,
211 hid: u32,
212 uid: u32,
213 };
214
215 pub const ExpandedAcpiDevicePath = packed struct {
216 type: DevicePathType,
217 subtype: Subtype,
218 length: u16,
219 hid: u32,
220 uid: u32,
221 cid: u32,
222 // variable length u16[*:0] strings
223 // hid_str, uid_str, cid_str
224 };
225
226 pub const AdrDevicePath = packed struct {
227 type: DevicePathType,
228 subtype: Subtype,
229 length: u16,
230 adr: u32,
231 // multiple adr entries can optionally follow
232 pub fn adrs(self: *const AdrDevicePath) []const u32 {
233 // self.length is a minimum of 8 with one adr which is size 4.
234 var entries = (self.length - 4) / @sizeOf(u32);
235 return @ptrCast([*]const u32, &self.adr)[0..entries];
236 }
237 };
228238};
229239
230240pub const MessagingDevicePath = union(Subtype) {
231 Atapi: void, // TODO
232 Scsi: void, // TODO
233 FibreChannel: void, // TODO
234 FibreChannelEx: void, // TODO
235 @"1394": void, // TODO
236 Usb: void, // TODO
237 Sata: void, // TODO
238 UsbWwid: void, // TODO
239 Lun: void, // TODO
240 UsbClass: void, // TODO
241 I2o: void, // TODO
242 MacAddress: void, // TODO
243 Ipv4: void, // TODO
244 Ipv6: void, // TODO
245 Vlan: void, // TODO
246 InfiniBand: void, // TODO
247 Uart: void, // TODO
248 Vendor: void, // TODO
241 Atapi: *const AtapiDevicePath,
242 Scsi: *const ScsiDevicePath,
243 FibreChannel: *const FibreChannelDevicePath,
244 FibreChannelEx: *const FibreChannelExDevicePath,
245 @"1394": *const F1394DevicePath,
246 Usb: *const UsbDevicePath,
247 Sata: *const SataDevicePath,
248 UsbWwid: *const UsbWwidDevicePath,
249 Lun: *const DeviceLogicalUnitDevicePath,
250 UsbClass: *const UsbClassDevicePath,
251 I2o: *const I2oDevicePath,
252 MacAddress: *const MacAddressDevicePath,
253 Ipv4: *const Ipv4DevicePath,
254 Ipv6: *const Ipv6DevicePath,
255 Vlan: *const VlanDevicePath,
256 InfiniBand: *const InfiniBandDevicePath,
257 Uart: *const UartDevicePath,
258 Vendor: *const VendorDefinedDevicePath,
249259
250260 pub const Subtype = enum(u8) {
251261 Atapi = 1,
......@@ -268,6 +278,232 @@ pub const MessagingDevicePath = union(Subtype) {
268278 Vendor = 10,
269279 _,
270280 };
281
282 pub const AtapiDevicePath = packed struct {
283 const Role = enum(u8) {
284 Master = 0,
285 Slave = 1,
286 };
287
288 const Rank = enum(u8) {
289 Primary = 0,
290 Secondary = 1,
291 };
292
293 type: DevicePathType,
294 subtype: Subtype,
295 length: u16,
296 primary_secondary: Rank,
297 slave_master: Role,
298 logical_unit_number: u16,
299 };
300
301 pub const ScsiDevicePath = packed struct {
302 type: DevicePathType,
303 subtype: Subtype,
304 length: u16,
305 target_id: u16,
306 logical_unit_number: u16,
307 };
308
309 pub const FibreChannelDevicePath = packed struct {
310 type: DevicePathType,
311 subtype: Subtype,
312 length: u16,
313 reserved: u32,
314 world_wide_name: u64,
315 logical_unit_number: u64,
316 };
317
318 pub const FibreChannelExDevicePath = packed struct {
319 type: DevicePathType,
320 subtype: Subtype,
321 length: u16,
322 reserved: u32,
323 world_wide_name: [8]u8,
324 logical_unit_number: [8]u8,
325 };
326
327 pub const F1394DevicePath = packed struct {
328 type: DevicePathType,
329 subtype: Subtype,
330 length: u16,
331 reserved: u32,
332 guid: u64,
333 };
334
335 pub const UsbDevicePath = packed struct {
336 type: DevicePathType,
337 subtype: Subtype,
338 length: u16,
339 parent_port_number: u8,
340 interface_number: u8,
341 };
342
343 pub const SataDevicePath = packed struct {
344 type: DevicePathType,
345 subtype: Subtype,
346 length: u16,
347 hba_port_number: u16,
348 port_multiplier_port_number: u16,
349 logical_unit_number: u16,
350 };
351
352 pub const UsbWwidDevicePath = packed struct {
353 type: DevicePathType,
354 subtype: Subtype,
355 length: u16,
356 interface_number: u16,
357 device_vendor_id: u16,
358 device_product_id: u16,
359
360 pub fn serial_number(self: *const UsbWwidDevicePath) []const u16 {
361 var serial_len = (self.length - @sizeOf(UsbWwidDevicePath)) / @sizeOf(u16);
362 return @ptrCast([*]u16, @ptrCast([*]u8, self) + @sizeOf(UsbWwidDevicePath))[0..serial_len];
363 }
364 };
365
366 pub const DeviceLogicalUnitDevicePath = packed struct {
367 type: DevicePathType,
368 subtype: Subtype,
369 length: u16,
370 lun: u8,
371 };
372
373 pub const UsbClassDevicePath = packed struct {
374 type: DevicePathType,
375 subtype: Subtype,
376 length: u16,
377 vendor_id: u16,
378 product_id: u16,
379 device_class: u8,
380 device_subclass: u8,
381 device_protocol: u8,
382 };
383
384 pub const I2oDevicePath = packed struct {
385 type: DevicePathType,
386 subtype: Subtype,
387 length: u16,
388 tid: u32,
389 };
390
391 pub const MacAddressDevicePath = packed struct {
392 type: DevicePathType,
393 subtype: Subtype,
394 length: u16,
395 mac_address: uefi.MacAddress,
396 if_type: u8,
397 };
398
399 pub const Ipv4DevicePath = packed struct {
400 pub const IpType = enum(u8) {
401 Dhcp = 0,
402 Static = 1,
403 };
404
405 type: DevicePathType,
406 subtype: Subtype,
407 length: u16,
408 local_ip_address: uefi.Ipv4Address,
409 remote_ip_address: uefi.Ipv4Address,
410 local_port: u16,
411 remote_port: u16,
412 network_protocol: u16,
413 static_ip_address: IpType,
414 gateway_ip_address: u32,
415 subnet_mask: u32,
416 };
417
418 pub const Ipv6DevicePath = packed struct {
419 pub const Origin = enum(u8) {
420 Manual = 0,
421 AssignedStateless = 1,
422 AssignedStateful = 2,
423 };
424
425 type: DevicePathType,
426 subtype: Subtype,
427 length: u16,
428 local_ip_address: uefi.Ipv6Address,
429 remote_ip_address: uefi.Ipv6Address,
430 local_port: u16,
431 remote_port: u16,
432 protocol: u16,
433 ip_address_origin: Origin,
434 prefix_length: u8,
435 gateway_ip_address: uefi.Ipv6Address,
436 };
437
438 pub const VlanDevicePath = packed struct {
439 type: DevicePathType,
440 subtype: Subtype,
441 length: u16,
442 vlan_id: u16,
443 };
444
445 pub const InfiniBandDevicePath = packed struct {
446 pub const ResourceFlags = packed struct {
447 pub const ControllerType = enum(u1) {
448 Ioc = 0,
449 Service = 1,
450 };
451
452 ioc_or_service: ControllerType,
453 extend_boot_environment: bool,
454 console_protocol: bool,
455 storage_protocol: bool,
456 network_protocol: bool,
457
458 // u1 + 4 * bool = 5 bits, we need a total of 32 bits
459 reserved: u27,
460 };
461
462 type: DevicePathType,
463 subtype: Subtype,
464 length: u16,
465 resource_flags: ResourceFlags,
466 port_gid: [16]u8,
467 service_id: u64,
468 target_port_id: u64,
469 device_id: u64,
470 };
471
472 pub const UartDevicePath = packed struct {
473 pub const Parity = enum(u8) {
474 Default = 0,
475 None = 1,
476 Even = 2,
477 Odd = 3,
478 Mark = 4,
479 Space = 5,
480 _,
481 };
482
483 pub const StopBits = enum(u8) {
484 Default = 0,
485 One = 1,
486 OneAndAHalf = 2,
487 Two = 3,
488 _,
489 };
490
491 type: DevicePathType,
492 subtype: Subtype,
493 length: u16,
494 reserved: u16,
495 baud_rate: u32,
496 data_bits: u8,
497 parity: Parity,
498 stop_bits: StopBits,
499 };
500
501 pub const VendorDefinedDevicePath = packed struct {
502 type: DevicePathType,
503 subtype: Subtype,
504 length: u16,
505 vendor_guid: Guid,
506 };
271507};
272508
273509pub const MediaDevicePath = union(Subtype) {
......@@ -295,24 +531,44 @@ pub const MediaDevicePath = union(Subtype) {
295531 };
296532
297533 pub const HardDriveDevicePath = packed struct {
534 pub const Format = enum(u8) {
535 LegacyMbr = 0x01,
536 GuidPartitionTable = 0x02,
537 };
538
539 pub const SignatureType = enum(u8) {
540 NoSignature = 0x00,
541 /// "32-bit signature from address 0x1b8 of the type 0x01 MBR"
542 MbrSignature = 0x01,
543 GuidSignature = 0x02,
544 };
545
298546 type: DevicePathType,
299547 subtype: Subtype,
300548 length: u16,
301 // TODO
549 partition_number: u32,
550 partition_start: u64,
551 partition_size: u64,
552 partition_signature: [16]u8,
553 partition_format: Format,
554 signature_type: SignatureType,
302555 };
303556
304557 pub const CdromDevicePath = packed struct {
305558 type: DevicePathType,
306559 subtype: Subtype,
307560 length: u16,
308 // TODO
561 boot_entry: u32,
562 partition_start: u64,
563 partition_size: u64,
309564 };
310565
311566 pub const VendorDevicePath = packed struct {
312567 type: DevicePathType,
313568 subtype: Subtype,
314569 length: u16,
315 // TODO
570 guid: Guid,
571 // vendor-defined variable data
316572 };
317573
318574 pub const FilePathDevicePath = packed struct {
......@@ -329,19 +585,21 @@ pub const MediaDevicePath = union(Subtype) {
329585 type: DevicePathType,
330586 subtype: Subtype,
331587 length: u16,
332 // TODO
588 guid: Guid,
333589 };
334590
335591 pub const PiwgFirmwareFileDevicePath = packed struct {
336592 type: DevicePathType,
337593 subtype: Subtype,
338594 length: u16,
595 fv_filename: Guid,
339596 };
340597
341598 pub const PiwgFirmwareVolumeDevicePath = packed struct {
342599 type: DevicePathType,
343600 subtype: Subtype,
344601 length: u16,
602 fv_name: Guid,
345603 };
346604
347605 pub const RelativeOffsetRangeDevicePath = packed struct {
......@@ -359,7 +617,7 @@ pub const MediaDevicePath = union(Subtype) {
359617 length: u16,
360618 start: u64,
361619 end: u64,
362 disk_type: uefi.Guid,
620 disk_type: Guid,
363621 instance: u16,
364622 };
365623};
lib/std/os/uefi/protocols/edid_override_protocol.zig+3-6
......@@ -8,9 +8,8 @@ pub const EdidOverrideProtocol = extern struct {
88 _get_edid: fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) callconv(.C) Status,
99
1010 /// Returns policy information and potentially a replacement EDID for the specified video output device.
11 /// attributes must be align(4)
1211 pub fn getEdid(self: *const EdidOverrideProtocol, handle: Handle, attributes: *EdidOverrideProtocolAttributes, edid_size: *usize, edid: *?[*]u8) Status {
13 return self._get_edid(self, handle, attributes, edid_size, edid);
12 return self._get_edid(self, handle, @ptrCast(*u32, attributes), edid_size, edid);
1413 }
1514
1615 pub const guid align(8) = Guid{
......@@ -24,9 +23,7 @@ pub const EdidOverrideProtocol = extern struct {
2423};
2524
2625pub const EdidOverrideProtocolAttributes = packed struct {
27 dont_override: bool,
26 dont_override: bool align(4),
2827 enable_hot_plug: bool,
29 _pad1: u6,
30 _pad2: u8,
31 _pad3: u16,
28 _pad: u30 = 0,
3229};
lib/std/os/uefi/protocols/hii.zig+2-2
......@@ -48,7 +48,7 @@ pub const NarrowGlyph = extern struct {
4848 attributes: packed struct {
4949 non_spacing: bool,
5050 wide: bool,
51 _pad: u6,
51 _pad: u6 = 0,
5252 },
5353 glyph_col_1: [19]u8,
5454};
......@@ -62,7 +62,7 @@ pub const WideGlyph = extern struct {
6262 },
6363 glyph_col_1: [19]u8,
6464 glyph_col_2: [19]u8,
65 _pad: [3]u8,
65 _pad: [3]u8 = [_]u8{0} ** 3,
6666};
6767
6868pub const HIIStringPackage = extern struct {
lib/std/os/uefi/protocols/simple_network_protocol.zig+2-6
......@@ -126,9 +126,7 @@ pub const SimpleNetworkReceiveFilter = packed struct {
126126 receive_broadcast: bool,
127127 receive_promiscuous: bool,
128128 receive_promiscuous_multicast: bool,
129 _pad1: u3 = undefined,
130 _pad2: u8 = undefined,
131 _pad3: u16 = undefined,
129 _pad: u27 = 0,
132130};
133131
134132pub const SimpleNetworkState = enum(u32) {
......@@ -171,7 +169,5 @@ pub const SimpleNetworkInterruptStatus = packed struct {
171169 transmit_interrupt: bool,
172170 command_interrupt: bool,
173171 software_interrupt: bool,
174 _pad1: u4,
175 _pad2: u8,
176 _pad3: u16,
172 _pad: u28 = 0,
177173};
lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig+2-2
......@@ -64,14 +64,14 @@ pub const KeyState = extern struct {
6464 left_logo_pressed: bool,
6565 menu_key_pressed: bool,
6666 sys_req_pressed: bool,
67 _pad1: u21,
67 _pad: u21 = 0,
6868 shift_state_valid: bool,
6969 },
7070 key_toggle_state: packed struct {
7171 scroll_lock_active: bool,
7272 num_lock_active: bool,
7373 caps_lock_active: bool,
74 _pad1: u3,
74 _pad: u3 = 0,
7575 key_state_exposed: bool,
7676 toggle_state_valid: bool,
7777 },
lib/std/os/uefi/status.zig+62
......@@ -1,3 +1,5 @@
1const testing = @import("std").testing;
2
13const high_bit = 1 << @typeInfo(usize).Int.bits - 1;
24
35pub const Status = enum(usize) {
......@@ -139,4 +141,64 @@ pub const Status = enum(usize) {
139141 WarnResetRequired = 7,
140142
141143 _,
144
145 pub const EfiError = error{
146 LoadError,
147 InvalidParameter,
148 Unsupported,
149 BadBufferSize,
150 BufferTooSmall,
151 NotReady,
152 DeviceError,
153 WriteProtected,
154 OutOfResources,
155 VolumeCorrupted,
156 VolumeFull,
157 NoMedia,
158 MediaChanged,
159 NotFound,
160 AccessDenied,
161 NoResponse,
162 NoMapping,
163 Timeout,
164 NotStarted,
165 AlreadyStarted,
166 Aborted,
167 IcmpError,
168 TftpError,
169 ProtocolError,
170 IncompatibleVersion,
171 SecurityViolation,
172 CrcError,
173 EndOfMedia,
174 EndOfFile,
175 InvalidLanguage,
176 CompromisedData,
177 IpAddressConflict,
178 HttpError,
179 NetworkUnreachable,
180 HostUnreachable,
181 ProtocolUnreachable,
182 PortUnreachable,
183 ConnectionFin,
184 ConnectionReset,
185 ConnectionRefused,
186 };
187
188 pub fn err(self: Status) EfiError!void {
189 inline for (@typeInfo(EfiError).ErrorSet.?) |efi_err| {
190 if (self == @field(Status, efi_err.name)) {
191 return @field(EfiError, efi_err.name);
192 }
193 }
194 // self is .Success or Warning
195 }
142196};
197
198test "status" {
199 var st: Status = .DeviceError;
200 try testing.expectError(error.DeviceError, st.err());
201
202 st = .Success;
203 try st.err();
204}
lib/std/os/uefi/tables.zig+5-14
......@@ -1,14 +1,5 @@
1pub const AllocateType = @import("tables/boot_services.zig").AllocateType;
2pub const BootServices = @import("tables/boot_services.zig").BootServices;
3pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;
4pub const global_variable align(8) = @import("tables/runtime_services.zig").global_variable;
5pub const LocateSearchType = @import("tables/boot_services.zig").LocateSearchType;
6pub const MemoryDescriptor = @import("tables/boot_services.zig").MemoryDescriptor;
7pub const MemoryType = @import("tables/boot_services.zig").MemoryType;
8pub const OpenProtocolAttributes = @import("tables/boot_services.zig").OpenProtocolAttributes;
9pub const ProtocolInformationEntry = @import("tables/boot_services.zig").ProtocolInformationEntry;
10pub const ResetType = @import("tables/runtime_services.zig").ResetType;
11pub const RuntimeServices = @import("tables/runtime_services.zig").RuntimeServices;
12pub const SystemTable = @import("tables/system_table.zig").SystemTable;
13pub const TableHeader = @import("tables/table_header.zig").TableHeader;
14pub const TimerDelay = @import("tables/boot_services.zig").TimerDelay;
1pub usingnamespace @import("tables/boot_services.zig");
2pub usingnamespace @import("tables/runtime_services.zig");
3pub usingnamespace @import("tables/configuration_table.zig");
4pub usingnamespace @import("tables/system_table.zig");
5pub usingnamespace @import("tables/table_header.zig");
lib/std/os/uefi/tables/boot_services.zig+89-46
......@@ -21,120 +21,159 @@ pub const BootServices = extern struct {
2121 hdr: TableHeader,
2222
2323 /// Raises a task's priority level and returns its previous level.
24 raiseTpl: fn (usize) callconv(.C) usize,
24 raiseTpl: fn (new_tpl: usize) callconv(.C) usize,
2525
2626 /// Restores a task's priority level to its previous value.
27 restoreTpl: fn (usize) callconv(.C) void,
27 restoreTpl: fn (old_tpl: usize) callconv(.C) void,
2828
2929 /// Allocates memory pages from the system.
30 allocatePages: fn (AllocateType, MemoryType, usize, *[*]align(4096) u8) callconv(.C) Status,
30 allocatePages: fn (alloc_type: AllocateType, mem_type: MemoryType, pages: usize, memory: *[*]align(4096) u8) callconv(.C) Status,
3131
3232 /// Frees memory pages.
33 freePages: fn ([*]align(4096) u8, usize) callconv(.C) Status,
33 freePages: fn (memory: [*]align(4096) u8, pages: usize) callconv(.C) Status,
3434
3535 /// Returns the current memory map.
36 getMemoryMap: fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) callconv(.C) Status,
36 getMemoryMap: fn (mmap_size: *usize, mmap: [*]MemoryDescriptor, mapKey: *usize, descriptor_size: *usize, descriptor_version: *u32) callconv(.C) Status,
3737
3838 /// Allocates pool memory.
39 allocatePool: fn (MemoryType, usize, *[*]align(8) u8) callconv(.C) Status,
39 allocatePool: fn (pool_type: MemoryType, size: usize, buffer: *[*]align(8) u8) callconv(.C) Status,
4040
4141 /// Returns pool memory to the system.
42 freePool: fn ([*]align(8) u8) callconv(.C) Status,
42 freePool: fn (buffer: [*]align(8) u8) callconv(.C) Status,
4343
4444 /// Creates an event.
45 createEvent: fn (u32, usize, ?fn (Event, ?*anyopaque) callconv(.C) void, ?*const anyopaque, *Event) callconv(.C) Status,
45 createEvent: fn (type: u32, notify_tpl: usize, notify_func: ?fn (Event, ?*anyopaque) callconv(.C) void, notifyCtx: ?*const anyopaque, event: *Event) callconv(.C) Status,
4646
4747 /// Sets the type of timer and the trigger time for a timer event.
48 setTimer: fn (Event, TimerDelay, u64) callconv(.C) Status,
48 setTimer: fn (event: Event, type: TimerDelay, triggerTime: u64) callconv(.C) Status,
4949
5050 /// Stops execution until an event is signaled.
51 waitForEvent: fn (usize, [*]const Event, *usize) callconv(.C) Status,
51 waitForEvent: fn (event_len: usize, events: [*]const Event, index: *usize) callconv(.C) Status,
5252
5353 /// Signals an event.
54 signalEvent: fn (Event) callconv(.C) Status,
54 signalEvent: fn (event: Event) callconv(.C) Status,
5555
5656 /// Closes an event.
57 closeEvent: fn (Event) callconv(.C) Status,
57 closeEvent: fn (event: Event) callconv(.C) Status,
5858
5959 /// Checks whether an event is in the signaled state.
60 checkEvent: fn (Event) callconv(.C) Status,
60 checkEvent: fn (event: Event) callconv(.C) Status,
6161
62 installProtocolInterface: Status, // TODO
63 reinstallProtocolInterface: Status, // TODO
64 uninstallProtocolInterface: Status, // TODO
62 /// Installs a protocol interface on a device handle. If the handle does not exist, it is created
63 /// and added to the list of handles in the system. installMultipleProtocolInterfaces()
64 /// performs more error checking than installProtocolInterface(), so its use is recommended over this.
65 installProtocolInterface: fn (handle: Handle, protocol: *align(8) const Guid, interface_type: EfiInterfaceType, interface: *anyopaque) callconv(.C) Status,
66
67 /// Reinstalls a protocol interface on a device handle
68 reinstallProtocolInterface: fn (handle: Handle, protocol: *align(8) const Guid, old_interface: *anyopaque, new_interface: *anyopaque) callconv(.C) Status,
69
70 /// Removes a protocol interface from a device handle. Usage of
71 /// uninstallMultipleProtocolInterfaces is recommended over this.
72 uninstallProtocolInterface: fn (handle: Handle, protocol: *align(8) const Guid, interface: *anyopaque) callconv(.C) Status,
6573
6674 /// Queries a handle to determine if it supports a specified protocol.
67 handleProtocol: fn (Handle, *align(8) const Guid, *?*anyopaque) callconv(.C) Status,
75 handleProtocol: fn (handle: Handle, protocol: *align(8) const Guid, interface: *?*anyopaque) callconv(.C) Status,
6876
6977 reserved: *anyopaque,
7078
71 registerProtocolNotify: Status, // TODO
79 /// Creates an event that is to be signaled whenever an interface is installed for a specified protocol.
80 registerProtocolNotify: fn (protocol: *align(8) const Guid, event: Event, registration: **anyopaque) callconv(.C) Status,
7281
7382 /// Returns an array of handles that support a specified protocol.
74 locateHandle: fn (LocateSearchType, ?*align(8) const Guid, ?*const anyopaque, *usize, [*]Handle) callconv(.C) Status,
83 locateHandle: fn (search_type: LocateSearchType, protocol: ?*align(8) const Guid, search_key: ?*const anyopaque, bufferSize: *usize, buffer: [*]Handle) callconv(.C) Status,
7584
7685 /// Locates the handle to a device on the device path that supports the specified protocol
77 locateDevicePath: fn (*align(8) const Guid, **const DevicePathProtocol, *?Handle) callconv(.C) Status,
78 installConfigurationTable: Status, // TODO
86 locateDevicePath: fn (protocols: *align(8) const Guid, device_path: **const DevicePathProtocol, device: *?Handle) callconv(.C) Status,
87
88 /// Adds, updates, or removes a configuration table entry from the EFI System Table.
89 installConfigurationTable: fn (guid: *align(8) const Guid, table: ?*anyopaque) callconv(.C) Status,
7990
8091 /// Loads an EFI image into memory.
81 loadImage: fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) callconv(.C) Status,
92 loadImage: fn (boot_policy: bool, parent_image_handle: Handle, device_path: ?*const DevicePathProtocol, source_buffer: ?[*]const u8, source_size: usize, imageHandle: *?Handle) callconv(.C) Status,
8293
8394 /// Transfers control to a loaded image's entry point.
84 startImage: fn (Handle, ?*usize, ?*[*]u16) callconv(.C) Status,
95 startImage: fn (image_handle: Handle, exit_data_size: ?*usize, exit_data: ?*[*]u16) callconv(.C) Status,
8596
8697 /// Terminates a loaded EFI image and returns control to boot services.
87 exit: fn (Handle, Status, usize, ?*const anyopaque) callconv(.C) Status,
98 exit: fn (image_handle: Handle, exit_status: Status, exit_data_size: usize, exit_data: ?*const anyopaque) callconv(.C) Status,
8899
89100 /// Unloads an image.
90 unloadImage: fn (Handle) callconv(.C) Status,
101 unloadImage: fn (image_handle: Handle) callconv(.C) Status,
91102
92103 /// Terminates all boot services.
93 exitBootServices: fn (Handle, usize) callconv(.C) Status,
104 exitBootServices: fn (image_handle: Handle, map_key: usize) callconv(.C) Status,
94105
95106 /// Returns a monotonically increasing count for the platform.
96 getNextMonotonicCount: fn (*u64) callconv(.C) Status,
107 getNextMonotonicCount: fn (count: *u64) callconv(.C) Status,
97108
98109 /// Induces a fine-grained stall.
99 stall: fn (usize) callconv(.C) Status,
110 stall: fn (microseconds: usize) callconv(.C) Status,
100111
101112 /// Sets the system's watchdog timer.
102 setWatchdogTimer: fn (usize, u64, usize, ?[*]const u16) callconv(.C) Status,
113 setWatchdogTimer: fn (timeout: usize, watchdogCode: u64, data_size: usize, watchdog_data: ?[*]const u16) callconv(.C) Status,
103114
104 connectController: Status, // TODO
105 disconnectController: Status, // TODO
115 /// Connects one or more drives to a controller.
116 connectController: fn (controller_handle: Handle, driver_image_handle: ?Handle, remaining_device_path: ?*DevicePathProtocol, recursive: bool) callconv(.C) Status,
117
118 // Disconnects one or more drivers from a controller
119 disconnectController: fn (controller_handle: Handle, driver_image_handle: ?Handle, child_handle: ?Handle) callconv(.C) Status,
106120
107121 /// Queries a handle to determine if it supports a specified protocol.
108 openProtocol: fn (Handle, *align(8) const Guid, *?*anyopaque, ?Handle, ?Handle, OpenProtocolAttributes) callconv(.C) Status,
122 openProtocol: fn (handle: Handle, protocol: *align(8) const Guid, interface: *?*anyopaque, agent_handle: ?Handle, controller_handle: ?Handle, attributes: OpenProtocolAttributes) callconv(.C) Status,
109123
110124 /// Closes a protocol on a handle that was opened using openProtocol().
111 closeProtocol: fn (Handle, *align(8) const Guid, Handle, ?Handle) callconv(.C) Status,
125 closeProtocol: fn (handle: Handle, protocol: *align(8) const Guid, agentHandle: Handle, controller_handle: ?Handle) callconv(.C) Status,
112126
113127 /// Retrieves the list of agents that currently have a protocol interface opened.
114 openProtocolInformation: fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) callconv(.C) Status,
128 openProtocolInformation: fn (handle: Handle, protocol: *align(8) const Guid, entry_buffer: *[*]ProtocolInformationEntry, entry_count: *usize) callconv(.C) Status,
115129
116130 /// Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated from pool.
117 protocolsPerHandle: fn (Handle, *[*]*align(8) const Guid, *usize) callconv(.C) Status,
131 protocolsPerHandle: fn (handle: Handle, protocol_buffer: *[*]*align(8) const Guid, protocol_buffer_count: *usize) callconv(.C) Status,
118132
119133 /// Returns an array of handles that support the requested protocol in a buffer allocated from pool.
120 locateHandleBuffer: fn (LocateSearchType, ?*align(8) const Guid, ?*const anyopaque, *usize, *[*]Handle) callconv(.C) Status,
134 locateHandleBuffer: fn (search_type: LocateSearchType, protocol: ?*align(8) const Guid, search_key: ?*const anyopaque, num_handles: *usize, buffer: *[*]Handle) callconv(.C) Status,
121135
122136 /// Returns the first protocol instance that matches the given protocol.
123 locateProtocol: fn (*align(8) const Guid, ?*const anyopaque, *?*anyopaque) callconv(.C) Status,
137 locateProtocol: fn (protocol: *align(8) const Guid, registration: ?*const anyopaque, interface: *?*anyopaque) callconv(.C) Status,
138
139 /// Installs one or more protocol interfaces into the boot services environment
140 installMultipleProtocolInterfaces: fn (handle: *Handle, ...) callconv(.C) Status,
124141
125 installMultipleProtocolInterfaces: Status, // TODO
126 uninstallMultipleProtocolInterfaces: Status, // TODO
142 /// Removes one or more protocol interfaces into the boot services environment
143 uninstallMultipleProtocolInterfaces: fn (handle: *Handle, ...) callconv(.C) Status,
127144
128145 /// Computes and returns a 32-bit CRC for a data buffer.
129 calculateCrc32: fn ([*]const u8, usize, *u32) callconv(.C) Status,
146 calculateCrc32: fn (data: [*]const u8, data_size: usize, *u32) callconv(.C) Status,
130147
131148 /// Copies the contents of one buffer to another buffer
132 copyMem: fn ([*]u8, [*]const u8, usize) callconv(.C) void,
149 copyMem: fn (dest: [*]u8, src: [*]const u8, len: usize) callconv(.C) void,
133150
134151 /// Fills a buffer with a specified value
135 setMem: fn ([*]u8, usize, u8) callconv(.C) void,
152 setMem: fn (buffer: [*]u8, size: usize, value: u8) callconv(.C) void,
153
154 /// Creates an event in a group.
155 createEventEx: fn (type: u32, notify_tpl: usize, notify_func: EfiEventNotify, notify_ctx: *const anyopaque, event_group: *align(8) const Guid, event: *Event) callconv(.C) Status,
136156
137 createEventEx: Status, // TODO
157 /// Opens a protocol with a structure as the loaded image for a UEFI application
158 pub fn openProtocolSt(self: *BootServices, comptime protocol: type, handle: Handle) !*protocol {
159 if (!@hasDecl(protocol, "guid"))
160 @compileError("Protocol is missing guid!");
161
162 var ptr: ?*protocol = undefined;
163
164 try self.openProtocol(
165 handle,
166 &protocol.guid,
167 @ptrCast(*?*anyopaque, &ptr),
168 // Invoking handle (loaded image)
169 uefi.handle,
170 // Control handle (null as not a driver)
171 null,
172 uefi.tables.OpenProtocolAttributes{ .by_handle_protocol = true },
173 ).err();
174
175 return ptr.?;
176 }
138177
139178 pub const signature: u64 = 0x56524553544f4f42;
140179
......@@ -151,6 +190,8 @@ pub const BootServices = extern struct {
151190 pub const tpl_high_level: usize = 31;
152191};
153192
193pub const EfiEventNotify = fn (event: Event, ctx: *anyopaque) callconv(.C) void;
194
154195pub const TimerDelay = enum(u32) {
155196 TimerCancel,
156197 TimerPeriodic,
......@@ -219,9 +260,7 @@ pub const OpenProtocolAttributes = packed struct {
219260 by_child_controller: bool = false,
220261 by_driver: bool = false,
221262 exclusive: bool = false,
222 _pad1: u2 = undefined,
223 _pad2: u8 = undefined,
224 _pad3: u16 = undefined,
263 _pad: u26 = 0,
225264};
226265
227266pub const ProtocolInformationEntry = extern struct {
......@@ -231,6 +270,10 @@ pub const ProtocolInformationEntry = extern struct {
231270 open_count: u32,
232271};
233272
273pub const EfiInterfaceType = enum(u32) {
274 EfiNativeInterface,
275};
276
234277pub const AllocateType = enum(u32) {
235278 AllocateAnyPages,
236279 AllocateMaxAddress,
lib/std/os/uefi/tables/runtime_services.zig+46-14
......@@ -18,39 +18,71 @@ pub const RuntimeServices = extern struct {
1818 hdr: TableHeader,
1919
2020 /// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.
21 getTime: fn (*uefi.Time, ?*TimeCapabilities) callconv(.C) Status,
21 getTime: fn (time: *uefi.Time, capabilities: ?*TimeCapabilities) callconv(.C) Status,
2222
23 setTime: Status, // TODO
24 getWakeupTime: Status, // TODO
25 setWakeupTime: Status, // TODO
23 /// Sets the current local time and date information
24 setTime: fn (time: *uefi.Time) callconv(.C) Status,
25
26 /// Returns the current wakeup alarm clock setting
27 getWakeupTime: fn (enabled: *bool, pending: *bool, time: *uefi.Time) callconv(.C) Status,
28
29 /// Sets the system wakeup alarm clock time
30 setWakeupTime: fn (enable: *bool, time: ?*uefi.Time) callconv(.C) Status,
2631
2732 /// Changes the runtime addressing mode of EFI firmware from physical to virtual.
28 setVirtualAddressMap: fn (usize, usize, u32, [*]MemoryDescriptor) callconv(.C) Status,
33 setVirtualAddressMap: fn (mmap_size: usize, descriptor_size: usize, descriptor_version: u32, virtual_map: [*]MemoryDescriptor) callconv(.C) Status,
2934
3035 /// Determines the new virtual address that is to be used on subsequent memory accesses.
31 convertPointer: fn (usize, **anyopaque) callconv(.C) Status,
36 convertPointer: fn (debug_disposition: usize, address: **anyopaque) callconv(.C) Status,
3237
3338 /// Returns the value of a variable.
34 getVariable: fn ([*:0]const u16, *align(8) const Guid, ?*u32, *usize, ?*anyopaque) callconv(.C) Status,
39 getVariable: fn (var_name: [*:0]const u16, vendor_guid: *align(8) const Guid, attributes: ?*u32, data_size: *usize, data: ?*anyopaque) callconv(.C) Status,
3540
3641 /// Enumerates the current variable names.
37 getNextVariableName: fn (*usize, [*:0]u16, *align(8) Guid) callconv(.C) Status,
42 getNextVariableName: fn (var_name_size: *usize, var_name: [*:0]u16, vendor_guid: *align(8) Guid) callconv(.C) Status,
3843
3944 /// Sets the value of a variable.
40 setVariable: fn ([*:0]const u16, *align(8) const Guid, u32, usize, *anyopaque) callconv(.C) Status,
45 setVariable: fn (var_name: [*:0]const u16, vendor_guid: *align(8) const Guid, attributes: u32, data_size: usize, data: *anyopaque) callconv(.C) Status,
4146
42 getNextHighMonotonicCount: Status, // TODO
47 /// Return the next high 32 bits of the platform's monotonic counter
48 getNextHighMonotonicCount: fn (high_count: *u32) callconv(.C) Status,
4349
4450 /// Resets the entire platform.
45 resetSystem: fn (ResetType, Status, usize, ?*const anyopaque) callconv(.C) noreturn,
51 resetSystem: fn (reset_type: ResetType, reset_status: Status, data_size: usize, reset_data: ?*const anyopaque) callconv(.C) noreturn,
52
53 /// Passes capsules to the firmware with both virtual and physical mapping.
54 /// Depending on the intended consumption, the firmware may process the capsule immediately.
55 /// If the payload should persist across a system reset, the reset value returned from
56 /// `queryCapsuleCapabilities` must be passed into resetSystem and will cause the capsule
57 /// to be processed by the firmware as part of the reset process.
58 updateCapsule: fn (capsule_header_array: **CapsuleHeader, capsule_count: usize, scatter_gather_list: EfiPhysicalAddress) callconv(.C) Status,
4659
47 updateCapsule: Status, // TODO
48 queryCapsuleCapabilities: Status, // TODO
49 queryVariableInfo: Status, // TODO
60 /// Returns if the capsule can be supported via `updateCapsule`
61 queryCapsuleCapabilities: fn (capsule_header_array: **CapsuleHeader, capsule_count: usize, maximum_capsule_size: *usize, resetType: ResetType) callconv(.C) Status,
62
63 /// Returns information about the EFI variables
64 queryVariableInfo: fn (attributes: *u32, maximum_variable_storage_size: *u64, remaining_variable_storage_size: *u64, maximum_variable_size: *u64) callconv(.C) Status,
5065
5166 pub const signature: u64 = 0x56524553544e5552;
5267};
5368
69const EfiPhysicalAddress = u64;
70
71pub const CapsuleHeader = extern struct {
72 capsuleGuid: Guid align(8),
73 headerSize: u32,
74 flags: u32,
75 capsuleImageSize: u32,
76};
77
78pub const UefiCapsuleBlockDescriptor = extern struct {
79 length: u64,
80 address: union {
81 dataBlock: EfiPhysicalAddress,
82 continuationPointer: EfiPhysicalAddress,
83 },
84};
85
5486pub const ResetType = enum(u32) {
5587 ResetCold,
5688 ResetWarm,