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...@@ -758,7 +758,52 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
758 std.os.abort();758 std.os.abort();
759 },759 },
760 .uefi => {760 .uefi => {
761 // TODO look into using the debug info and logging helpful messages761 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.
762 std.os.abort();807 std.os.abort();
763 },808 },
764 else => {809 else => {
lib/std/os/uefi.zig+12-2
...@@ -23,6 +23,18 @@ pub var system_table: *tables.SystemTable = undefined;...@@ -23,6 +23,18 @@ pub var system_table: *tables.SystemTable = undefined;
23/// A handle to an event structure.23/// A handle to an event structure.
24pub const Event = *opaque {};24pub 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
26/// GUIDs must be align(8)38/// GUIDs must be align(8)
27pub const Guid = extern struct {39pub const Guid = extern struct {
28 time_low: u32,40 time_low: u32,
...@@ -86,7 +98,6 @@ pub const Time = extern struct {...@@ -86,7 +98,6 @@ pub const Time = extern struct {
8698
87 /// 0 - 5999 /// 0 - 59
88 second: u8,100 second: u8,
89 _pad1: u8,
90101
91 /// 0 - 999999999102 /// 0 - 999999999
92 nanosecond: u32,103 nanosecond: u32,
...@@ -103,7 +114,6 @@ pub const Time = extern struct {...@@ -103,7 +114,6 @@ pub const Time = extern struct {
103 /// If true, the time is affected by daylight savings time.114 /// If true, the time is affected by daylight savings time.
104 adjust_daylight: bool,115 adjust_daylight: bool,
105 },116 },
106 _pad2: u8,
107117
108 /// Time is to be interpreted as local time118 /// Time is to be interpreted as local time
109 pub const unspecified_timezone: i16 = 0x7ff;119 pub const unspecified_timezone: i16 = 0x7ff;
lib/std/os/uefi/protocols.zig+43-99
...@@ -1,100 +1,44 @@...@@ -1,100 +1,44 @@
1pub const LoadedImageProtocol = @import("protocols/loaded_image_protocol.zig").LoadedImageProtocol;1// Misc
2pub const loaded_image_device_path_protocol_guid = @import("protocols/loaded_image_protocol.zig").loaded_image_device_path_protocol_guid;2pub usingnamespace @import("protocols/loaded_image_protocol.zig");
33pub usingnamespace @import("protocols/device_path_protocol.zig");
4pub const AcpiDevicePath = @import("protocols/device_path_protocol.zig").AcpiDevicePath;4pub usingnamespace @import("protocols/rng_protocol.zig");
5pub const BiosBootSpecificationDevicePath = @import("protocols/device_path_protocol.zig").BiosBootSpecificationDevicePath;5pub usingnamespace @import("protocols/shell_parameters_protocol.zig");
6pub const DevicePath = @import("protocols/device_path_protocol.zig").DevicePath;6
7pub const DevicePathProtocol = @import("protocols/device_path_protocol.zig").DevicePathProtocol;7// Files
8pub const DevicePathType = @import("protocols/device_path_protocol.zig").DevicePathType;8pub usingnamespace @import("protocols/simple_file_system_protocol.zig");
9pub const EndDevicePath = @import("protocols/device_path_protocol.zig").EndDevicePath;9pub usingnamespace @import("protocols/file_protocol.zig");
10pub const HardwareDevicePath = @import("protocols/device_path_protocol.zig").HardwareDevicePath;10
11pub const MediaDevicePath = @import("protocols/device_path_protocol.zig").MediaDevicePath;11// Text
12pub const MessagingDevicePath = @import("protocols/device_path_protocol.zig").MessagingDevicePath;12pub usingnamespace @import("protocols/simple_text_input_protocol.zig");
1313pub usingnamespace @import("protocols/simple_text_input_ex_protocol.zig");
14pub const SimpleFileSystemProtocol = @import("protocols/simple_file_system_protocol.zig").SimpleFileSystemProtocol;14pub usingnamespace @import("protocols/simple_text_output_protocol.zig");
15pub const FileProtocol = @import("protocols/file_protocol.zig").FileProtocol;15
16pub const FileInfo = @import("protocols/file_protocol.zig").FileInfo;16// Pointer
17pub const FileSystemInfo = @import("protocols/file_protocol.zig").FileSystemInfo;17pub usingnamespace @import("protocols/simple_pointer_protocol.zig");
1818pub usingnamespace @import("protocols/absolute_pointer_protocol.zig");
19pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;19
20pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;20pub usingnamespace @import("protocols/graphics_output_protocol.zig");
21pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;21
22pub const SimpleTextInputProtocol = @import("protocols/simple_text_input_protocol.zig").SimpleTextInputProtocol;22// edid
23pub const SimpleTextInputExProtocol = @import("protocols/simple_text_input_ex_protocol.zig").SimpleTextInputExProtocol;23pub usingnamespace @import("protocols/edid_discovered_protocol.zig");
2424pub usingnamespace @import("protocols/edid_active_protocol.zig");
25pub const SimpleTextOutputMode = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputMode;25pub usingnamespace @import("protocols/edid_override_protocol.zig");
26pub const SimpleTextOutputProtocol = @import("protocols/simple_text_output_protocol.zig").SimpleTextOutputProtocol;26
2727// Network
28pub const SimplePointerMode = @import("protocols/simple_pointer_protocol.zig").SimplePointerMode;28pub usingnamespace @import("protocols/simple_network_protocol.zig");
29pub const SimplePointerProtocol = @import("protocols/simple_pointer_protocol.zig").SimplePointerProtocol;29pub usingnamespace @import("protocols/managed_network_service_binding_protocol.zig");
30pub const SimplePointerState = @import("protocols/simple_pointer_protocol.zig").SimplePointerState;30pub usingnamespace @import("protocols/managed_network_protocol.zig");
3131
32pub const AbsolutePointerMode = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerMode;32// ip6
33pub const AbsolutePointerProtocol = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerProtocol;33pub usingnamespace @import("protocols/ip6_service_binding_protocol.zig");
34pub const AbsolutePointerState = @import("protocols/absolute_pointer_protocol.zig").AbsolutePointerState;34pub usingnamespace @import("protocols/ip6_protocol.zig");
3535pub usingnamespace @import("protocols/ip6_config_protocol.zig");
36pub const GraphicsOutputBltPixel = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltPixel;36
37pub const GraphicsOutputBltOperation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputBltOperation;37// udp6
38pub const GraphicsOutputModeInformation = @import("protocols/graphics_output_protocol.zig").GraphicsOutputModeInformation;38pub usingnamespace @import("protocols/udp6_service_binding_protocol.zig");
39pub const GraphicsOutputProtocol = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocol;39pub usingnamespace @import("protocols/udp6_protocol.zig");
40pub const GraphicsOutputProtocolMode = @import("protocols/graphics_output_protocol.zig").GraphicsOutputProtocolMode;40
41pub const GraphicsPixelFormat = @import("protocols/graphics_output_protocol.zig").GraphicsPixelFormat;41// hii
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
91pub const hii = @import("protocols/hii.zig");42pub const hii = @import("protocols/hii.zig");
92pub const HIIDatabaseProtocol = @import("protocols/hii_database_protocol.zig").HIIDatabaseProtocol;43pub usingnamespace @import("protocols/hii_database_protocol.zig");
93pub const HIIPopupProtocol = @import("protocols/hii_popup_protocol.zig").HIIPopupProtocol;44pub usingnamespace @import("protocols/hii_popup_protocol.zig");
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;
lib/std/os/uefi/protocols/absolute_pointer_protocol.zig+2-6
...@@ -40,9 +40,7 @@ pub const AbsolutePointerMode = extern struct {...@@ -40,9 +40,7 @@ pub const AbsolutePointerMode = extern struct {
40 attributes: packed struct {40 attributes: packed struct {
41 supports_alt_active: bool,41 supports_alt_active: bool,
42 supports_pressure_as_z: bool,42 supports_pressure_as_z: bool,
43 _pad1: u6,43 _pad: u30 = 0,
44 _pad2: u8,
45 _pad3: u16,
46 },44 },
47};45};
4846
...@@ -53,8 +51,6 @@ pub const AbsolutePointerState = extern struct {...@@ -53,8 +51,6 @@ pub const AbsolutePointerState = extern struct {
53 active_buttons: packed struct {51 active_buttons: packed struct {
54 touch_active: bool,52 touch_active: bool,
55 alt_active: bool,53 alt_active: bool,
56 _pad1: u6,54 _pad: u30 = 0,
57 _pad2: u8,
58 _pad3: u16,
59 },55 },
60};56};
lib/std/os/uefi/protocols/device_path_protocol.zig+349-91
...@@ -72,63 +72,39 @@ pub const DevicePathProtocol = packed struct {...@@ -72,63 +72,39 @@ pub const DevicePathProtocol = packed struct {
72 }72 }
7373
74 pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath {74 pub fn getDevicePath(self: *const DevicePathProtocol) ?DevicePath {
75 return switch (self.type) {75 inline for (@typeInfo(DevicePath).Union.fields) |ufield| {
76 .Hardware => blk: {76 const enum_value = std.meta.stringToEnum(DevicePathType, ufield.name);
77 const hardware: ?HardwareDevicePath = switch (@intToEnum(HardwareDevicePath.Subtype, self.subtype)) {77
78 .Pci => .{ .Pci = @ptrCast(*const HardwareDevicePath.PciDevicePath, self) },78 // Got the associated union type for self.type, now
79 .PcCard => .{ .PcCard = @ptrCast(*const HardwareDevicePath.PcCardDevicePath, self) },79 // we need to initialize it and its subtype
80 .MemoryMapped => .{ .MemoryMapped = @ptrCast(*const HardwareDevicePath.MemoryMappedDevicePath, self) },80 if (self.type == enum_value) {
81 .Vendor => .{ .Vendor = @ptrCast(*const HardwareDevicePath.VendorDevicePath, self) },81 var subtype = self.initSubtype(ufield.field_type);
82 .Controller => .{ .Controller = @ptrCast(*const HardwareDevicePath.ControllerDevicePath, self) },82
83 .Bmc => .{ .Bmc = @ptrCast(*const HardwareDevicePath.BmcDevicePath, self) },83 if (subtype) |sb| {
84 _ => null,84 // e.g. return .{ .Hardware = .{ .Pci = @ptrCast(...) } }
85 };85 return @unionInit(DevicePath, ufield.name, sb);
86 break :blk if (hardware) |h| .{ .Hardware = h } else null;86 }
87 },87 }
88 .Acpi => blk: {88 }
89 const acpi: ?AcpiDevicePath = switch (@intToEnum(AcpiDevicePath.Subtype, self.subtype)) {89
90 else => null, // TODO90 return null;
91 };91 }
92 break :blk if (acpi) |a| .{ .Acpi = a } else null;92
93 },93 pub fn initSubtype(self: *const DevicePathProtocol, comptime TUnion: type) ?TUnion {
94 .Messaging => blk: {94 const type_info = @typeInfo(TUnion).Union;
95 const messaging: ?MessagingDevicePath = switch (@intToEnum(MessagingDevicePath.Subtype, self.subtype)) {95 const TTag = type_info.tag_type.?;
96 else => null, // TODO96
97 };97 inline for (type_info.fields) |subtype| {
98 break :blk if (messaging) |m| .{ .Messaging = m } else null;98 // The tag names match the union names, so just grab that off the enum
99 },99 const tag_val: u8 = @enumToInt(@field(TTag, subtype.name));
100 .Media => blk: {100
101 const media: ?MediaDevicePath = switch (@intToEnum(MediaDevicePath.Subtype, self.subtype)) {101 if (self.subtype == tag_val) {
102 .HardDrive => .{ .HardDrive = @ptrCast(*const MediaDevicePath.HardDriveDevicePath, self) },102 // e.g. expr = .{ .Pci = @ptrCast(...) }
103 .Cdrom => .{ .Cdrom = @ptrCast(*const MediaDevicePath.CdromDevicePath, self) },103 return @unionInit(TUnion, subtype.name, @ptrCast(subtype.field_type, self));
104 .Vendor => .{ .Vendor = @ptrCast(*const MediaDevicePath.VendorDevicePath, self) },104 }
105 .FilePath => .{ .FilePath = @ptrCast(*const MediaDevicePath.FilePathDevicePath, self) },105 }
106 .MediaProtocol => .{ .MediaProtocol = @ptrCast(*const MediaDevicePath.MediaProtocolDevicePath, self) },106
107 .PiwgFirmwareFile => .{ .PiwgFirmwareFile = @ptrCast(*const MediaDevicePath.PiwgFirmwareFileDevicePath, self) },107 return null;
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 };
132 }108 }
133};109};
134110
...@@ -173,79 +149,113 @@ pub const HardwareDevicePath = union(Subtype) {...@@ -173,79 +149,113 @@ pub const HardwareDevicePath = union(Subtype) {
173 type: DevicePathType,149 type: DevicePathType,
174 subtype: Subtype,150 subtype: Subtype,
175 length: u16,151 length: u16,
176 // TODO152 function: u8,
153 device: u8,
177 };154 };
178155
179 pub const PcCardDevicePath = packed struct {156 pub const PcCardDevicePath = packed struct {
180 type: DevicePathType,157 type: DevicePathType,
181 subtype: Subtype,158 subtype: Subtype,
182 length: u16,159 length: u16,
183 // TODO160 function_number: u8,
184 };161 };
185162
186 pub const MemoryMappedDevicePath = packed struct {163 pub const MemoryMappedDevicePath = packed struct {
187 type: DevicePathType,164 type: DevicePathType,
188 subtype: Subtype,165 subtype: Subtype,
189 length: u16,166 length: u16,
190 // TODO167 memory_type: u32,
168 start_address: u64,
169 end_address: u64,
191 };170 };
192171
193 pub const VendorDevicePath = packed struct {172 pub const VendorDevicePath = packed struct {
194 type: DevicePathType,173 type: DevicePathType,
195 subtype: Subtype,174 subtype: Subtype,
196 length: u16,175 length: u16,
197 // TODO176 vendor_guid: Guid,
198 };177 };
199178
200 pub const ControllerDevicePath = packed struct {179 pub const ControllerDevicePath = packed struct {
201 type: DevicePathType,180 type: DevicePathType,
202 subtype: Subtype,181 subtype: Subtype,
203 length: u16,182 length: u16,
204 // TODO183 controller_number: u32,
205 };184 };
206185
207 pub const BmcDevicePath = packed struct {186 pub const BmcDevicePath = packed struct {
208 type: DevicePathType,187 type: DevicePathType,
209 subtype: Subtype,188 subtype: Subtype,
210 length: u16,189 length: u16,
211 // TODO190 interface_type: u8,
191 base_address: usize,
212 };192 };
213};193};
214194
215pub const AcpiDevicePath = union(Subtype) {195pub const AcpiDevicePath = union(Subtype) {
216 Acpi: void, // TODO196 Acpi: *const BaseAcpiDevicePath,
217 ExpandedAcpi: void, // TODO197 ExpandedAcpi: *const ExpandedAcpiDevicePath,
218 Adr: void, // TODO198 Adr: *const AdrDevicePath,
219 Nvdimm: void, // TODO
220199
221 pub const Subtype = enum(u8) {200 pub const Subtype = enum(u8) {
222 Acpi = 1,201 Acpi = 1,
223 ExpandedAcpi = 2,202 ExpandedAcpi = 2,
224 Adr = 3,203 Adr = 3,
225 Nvdimm = 4,
226 _,204 _,
227 };205 };
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 };
228};238};
229239
230pub const MessagingDevicePath = union(Subtype) {240pub const MessagingDevicePath = union(Subtype) {
231 Atapi: void, // TODO241 Atapi: *const AtapiDevicePath,
232 Scsi: void, // TODO242 Scsi: *const ScsiDevicePath,
233 FibreChannel: void, // TODO243 FibreChannel: *const FibreChannelDevicePath,
234 FibreChannelEx: void, // TODO244 FibreChannelEx: *const FibreChannelExDevicePath,
235 @"1394": void, // TODO245 @"1394": *const F1394DevicePath,
236 Usb: void, // TODO246 Usb: *const UsbDevicePath,
237 Sata: void, // TODO247 Sata: *const SataDevicePath,
238 UsbWwid: void, // TODO248 UsbWwid: *const UsbWwidDevicePath,
239 Lun: void, // TODO249 Lun: *const DeviceLogicalUnitDevicePath,
240 UsbClass: void, // TODO250 UsbClass: *const UsbClassDevicePath,
241 I2o: void, // TODO251 I2o: *const I2oDevicePath,
242 MacAddress: void, // TODO252 MacAddress: *const MacAddressDevicePath,
243 Ipv4: void, // TODO253 Ipv4: *const Ipv4DevicePath,
244 Ipv6: void, // TODO254 Ipv6: *const Ipv6DevicePath,
245 Vlan: void, // TODO255 Vlan: *const VlanDevicePath,
246 InfiniBand: void, // TODO256 InfiniBand: *const InfiniBandDevicePath,
247 Uart: void, // TODO257 Uart: *const UartDevicePath,
248 Vendor: void, // TODO258 Vendor: *const VendorDefinedDevicePath,
249259
250 pub const Subtype = enum(u8) {260 pub const Subtype = enum(u8) {
251 Atapi = 1,261 Atapi = 1,
...@@ -268,6 +278,232 @@ pub const MessagingDevicePath = union(Subtype) {...@@ -268,6 +278,232 @@ pub const MessagingDevicePath = union(Subtype) {
268 Vendor = 10,278 Vendor = 10,
269 _,279 _,
270 };280 };
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 };
271};507};
272508
273pub const MediaDevicePath = union(Subtype) {509pub const MediaDevicePath = union(Subtype) {
...@@ -295,24 +531,44 @@ pub const MediaDevicePath = union(Subtype) {...@@ -295,24 +531,44 @@ pub const MediaDevicePath = union(Subtype) {
295 };531 };
296532
297 pub const HardDriveDevicePath = packed struct {533 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
298 type: DevicePathType,546 type: DevicePathType,
299 subtype: Subtype,547 subtype: Subtype,
300 length: u16,548 length: u16,
301 // TODO549 partition_number: u32,
550 partition_start: u64,
551 partition_size: u64,
552 partition_signature: [16]u8,
553 partition_format: Format,
554 signature_type: SignatureType,
302 };555 };
303556
304 pub const CdromDevicePath = packed struct {557 pub const CdromDevicePath = packed struct {
305 type: DevicePathType,558 type: DevicePathType,
306 subtype: Subtype,559 subtype: Subtype,
307 length: u16,560 length: u16,
308 // TODO561 boot_entry: u32,
562 partition_start: u64,
563 partition_size: u64,
309 };564 };
310565
311 pub const VendorDevicePath = packed struct {566 pub const VendorDevicePath = packed struct {
312 type: DevicePathType,567 type: DevicePathType,
313 subtype: Subtype,568 subtype: Subtype,
314 length: u16,569 length: u16,
315 // TODO570 guid: Guid,
571 // vendor-defined variable data
316 };572 };
317573
318 pub const FilePathDevicePath = packed struct {574 pub const FilePathDevicePath = packed struct {
...@@ -329,19 +585,21 @@ pub const MediaDevicePath = union(Subtype) {...@@ -329,19 +585,21 @@ pub const MediaDevicePath = union(Subtype) {
329 type: DevicePathType,585 type: DevicePathType,
330 subtype: Subtype,586 subtype: Subtype,
331 length: u16,587 length: u16,
332 // TODO588 guid: Guid,
333 };589 };
334590
335 pub const PiwgFirmwareFileDevicePath = packed struct {591 pub const PiwgFirmwareFileDevicePath = packed struct {
336 type: DevicePathType,592 type: DevicePathType,
337 subtype: Subtype,593 subtype: Subtype,
338 length: u16,594 length: u16,
595 fv_filename: Guid,
339 };596 };
340597
341 pub const PiwgFirmwareVolumeDevicePath = packed struct {598 pub const PiwgFirmwareVolumeDevicePath = packed struct {
342 type: DevicePathType,599 type: DevicePathType,
343 subtype: Subtype,600 subtype: Subtype,
344 length: u16,601 length: u16,
602 fv_name: Guid,
345 };603 };
346604
347 pub const RelativeOffsetRangeDevicePath = packed struct {605 pub const RelativeOffsetRangeDevicePath = packed struct {
...@@ -359,7 +617,7 @@ pub const MediaDevicePath = union(Subtype) {...@@ -359,7 +617,7 @@ pub const MediaDevicePath = union(Subtype) {
359 length: u16,617 length: u16,
360 start: u64,618 start: u64,
361 end: u64,619 end: u64,
362 disk_type: uefi.Guid,620 disk_type: Guid,
363 instance: u16,621 instance: u16,
364 };622 };
365};623};
lib/std/os/uefi/protocols/edid_override_protocol.zig+3-6
...@@ -8,9 +8,8 @@ pub const EdidOverrideProtocol = extern struct {...@@ -8,9 +8,8 @@ pub const EdidOverrideProtocol = extern struct {
8 _get_edid: fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) callconv(.C) Status,8 _get_edid: fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) callconv(.C) Status,
99
10 /// Returns policy information and potentially a replacement EDID for the specified video output device.10 /// Returns policy information and potentially a replacement EDID for the specified video output device.
11 /// attributes must be align(4)
12 pub fn getEdid(self: *const EdidOverrideProtocol, handle: Handle, attributes: *EdidOverrideProtocolAttributes, edid_size: *usize, edid: *?[*]u8) Status {11 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);
14 }13 }
1514
16 pub const guid align(8) = Guid{15 pub const guid align(8) = Guid{
...@@ -24,9 +23,7 @@ pub const EdidOverrideProtocol = extern struct {...@@ -24,9 +23,7 @@ pub const EdidOverrideProtocol = extern struct {
24};23};
2524
26pub const EdidOverrideProtocolAttributes = packed struct {25pub const EdidOverrideProtocolAttributes = packed struct {
27 dont_override: bool,26 dont_override: bool align(4),
28 enable_hot_plug: bool,27 enable_hot_plug: bool,
29 _pad1: u6,28 _pad: u30 = 0,
30 _pad2: u8,
31 _pad3: u16,
32};29};
lib/std/os/uefi/protocols/hii.zig+2-2
...@@ -48,7 +48,7 @@ pub const NarrowGlyph = extern struct {...@@ -48,7 +48,7 @@ pub const NarrowGlyph = extern struct {
48 attributes: packed struct {48 attributes: packed struct {
49 non_spacing: bool,49 non_spacing: bool,
50 wide: bool,50 wide: bool,
51 _pad: u6,51 _pad: u6 = 0,
52 },52 },
53 glyph_col_1: [19]u8,53 glyph_col_1: [19]u8,
54};54};
...@@ -62,7 +62,7 @@ pub const WideGlyph = extern struct {...@@ -62,7 +62,7 @@ pub const WideGlyph = extern struct {
62 },62 },
63 glyph_col_1: [19]u8,63 glyph_col_1: [19]u8,
64 glyph_col_2: [19]u8,64 glyph_col_2: [19]u8,
65 _pad: [3]u8,65 _pad: [3]u8 = [_]u8{0} ** 3,
66};66};
6767
68pub const HIIStringPackage = extern struct {68pub const HIIStringPackage = extern struct {
lib/std/os/uefi/protocols/simple_network_protocol.zig+2-6
...@@ -126,9 +126,7 @@ pub const SimpleNetworkReceiveFilter = packed struct {...@@ -126,9 +126,7 @@ pub const SimpleNetworkReceiveFilter = packed struct {
126 receive_broadcast: bool,126 receive_broadcast: bool,
127 receive_promiscuous: bool,127 receive_promiscuous: bool,
128 receive_promiscuous_multicast: bool,128 receive_promiscuous_multicast: bool,
129 _pad1: u3 = undefined,129 _pad: u27 = 0,
130 _pad2: u8 = undefined,
131 _pad3: u16 = undefined,
132};130};
133131
134pub const SimpleNetworkState = enum(u32) {132pub const SimpleNetworkState = enum(u32) {
...@@ -171,7 +169,5 @@ pub const SimpleNetworkInterruptStatus = packed struct {...@@ -171,7 +169,5 @@ pub const SimpleNetworkInterruptStatus = packed struct {
171 transmit_interrupt: bool,169 transmit_interrupt: bool,
172 command_interrupt: bool,170 command_interrupt: bool,
173 software_interrupt: bool,171 software_interrupt: bool,
174 _pad1: u4,172 _pad: u28 = 0,
175 _pad2: u8,
176 _pad3: u16,
177};173};
lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig+2-2
...@@ -64,14 +64,14 @@ pub const KeyState = extern struct {...@@ -64,14 +64,14 @@ pub const KeyState = extern struct {
64 left_logo_pressed: bool,64 left_logo_pressed: bool,
65 menu_key_pressed: bool,65 menu_key_pressed: bool,
66 sys_req_pressed: bool,66 sys_req_pressed: bool,
67 _pad1: u21,67 _pad: u21 = 0,
68 shift_state_valid: bool,68 shift_state_valid: bool,
69 },69 },
70 key_toggle_state: packed struct {70 key_toggle_state: packed struct {
71 scroll_lock_active: bool,71 scroll_lock_active: bool,
72 num_lock_active: bool,72 num_lock_active: bool,
73 caps_lock_active: bool,73 caps_lock_active: bool,
74 _pad1: u3,74 _pad: u3 = 0,
75 key_state_exposed: bool,75 key_state_exposed: bool,
76 toggle_state_valid: bool,76 toggle_state_valid: bool,
77 },77 },
lib/std/os/uefi/status.zig+62
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1const testing = @import("std").testing;
2
1const high_bit = 1 << @typeInfo(usize).Int.bits - 1;3const high_bit = 1 << @typeInfo(usize).Int.bits - 1;
24
3pub const Status = enum(usize) {5pub const Status = enum(usize) {
...@@ -139,4 +141,64 @@ pub const Status = enum(usize) {...@@ -139,4 +141,64 @@ pub const Status = enum(usize) {
139 WarnResetRequired = 7,141 WarnResetRequired = 7,
140142
141 _,143 _,
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 }
142};196};
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 @@...@@ -1,14 +1,5 @@
1pub const AllocateType = @import("tables/boot_services.zig").AllocateType;1pub usingnamespace @import("tables/boot_services.zig");
2pub const BootServices = @import("tables/boot_services.zig").BootServices;2pub usingnamespace @import("tables/runtime_services.zig");
3pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;3pub usingnamespace @import("tables/configuration_table.zig");
4pub const global_variable align(8) = @import("tables/runtime_services.zig").global_variable;4pub usingnamespace @import("tables/system_table.zig");
5pub const LocateSearchType = @import("tables/boot_services.zig").LocateSearchType;5pub usingnamespace @import("tables/table_header.zig");
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;
lib/std/os/uefi/tables/boot_services.zig+89-46
...@@ -21,120 +21,159 @@ pub const BootServices = extern struct {...@@ -21,120 +21,159 @@ pub const BootServices = extern struct {
21 hdr: TableHeader,21 hdr: TableHeader,
2222
23 /// Raises a task's priority level and returns its previous level.23 /// 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
26 /// Restores a task's priority level to its previous value.26 /// 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
29 /// Allocates memory pages from the system.29 /// 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
32 /// Frees memory pages.32 /// 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
35 /// Returns the current memory map.35 /// 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
38 /// Allocates pool memory.38 /// 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
41 /// Returns pool memory to the system.41 /// 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
44 /// Creates an event.44 /// 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
47 /// Sets the type of timer and the trigger time for a timer event.47 /// 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
50 /// Stops execution until an event is signaled.50 /// 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
53 /// Signals an event.53 /// Signals an event.
54 signalEvent: fn (Event) callconv(.C) Status,54 signalEvent: fn (event: Event) callconv(.C) Status,
5555
56 /// Closes an event.56 /// Closes an event.
57 closeEvent: fn (Event) callconv(.C) Status,57 closeEvent: fn (event: Event) callconv(.C) Status,
5858
59 /// Checks whether an event is in the signaled state.59 /// 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, // TODO62 /// Installs a protocol interface on a device handle. If the handle does not exist, it is created
63 reinstallProtocolInterface: Status, // TODO63 /// and added to the list of handles in the system. installMultipleProtocolInterfaces()
64 uninstallProtocolInterface: Status, // TODO64 /// 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
66 /// Queries a handle to determine if it supports a specified protocol.74 /// 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
69 reserved: *anyopaque,77 reserved: *anyopaque,
7078
71 registerProtocolNotify: Status, // TODO79 /// 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
73 /// Returns an array of handles that support a specified protocol.82 /// 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
76 /// Locates the handle to a device on the device path that supports the specified protocol85 /// 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,86 locateDevicePath: fn (protocols: *align(8) const Guid, device_path: **const DevicePathProtocol, device: *?Handle) callconv(.C) Status,
78 installConfigurationTable: Status, // TODO87
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
80 /// Loads an EFI image into memory.91 /// 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
83 /// Transfers control to a loaded image's entry point.94 /// 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
86 /// Terminates a loaded EFI image and returns control to boot services.97 /// 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
89 /// Unloads an image.100 /// Unloads an image.
90 unloadImage: fn (Handle) callconv(.C) Status,101 unloadImage: fn (image_handle: Handle) callconv(.C) Status,
91102
92 /// Terminates all boot services.103 /// 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
95 /// Returns a monotonically increasing count for the platform.106 /// Returns a monotonically increasing count for the platform.
96 getNextMonotonicCount: fn (*u64) callconv(.C) Status,107 getNextMonotonicCount: fn (count: *u64) callconv(.C) Status,
97108
98 /// Induces a fine-grained stall.109 /// Induces a fine-grained stall.
99 stall: fn (usize) callconv(.C) Status,110 stall: fn (microseconds: usize) callconv(.C) Status,
100111
101 /// Sets the system's watchdog timer.112 /// 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, // TODO115 /// Connects one or more drives to a controller.
105 disconnectController: Status, // TODO116 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
107 /// Queries a handle to determine if it supports a specified protocol.121 /// 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
110 /// Closes a protocol on a handle that was opened using openProtocol().124 /// 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
113 /// Retrieves the list of agents that currently have a protocol interface opened.127 /// 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
116 /// Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated from pool.130 /// 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
119 /// Returns an array of handles that support the requested protocol in a buffer allocated from pool.133 /// 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
122 /// Returns the first protocol instance that matches the given protocol.136 /// 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, // TODO142 /// Removes one or more protocol interfaces into the boot services environment
126 uninstallMultipleProtocolInterfaces: Status, // TODO143 uninstallMultipleProtocolInterfaces: fn (handle: *Handle, ...) callconv(.C) Status,
127144
128 /// Computes and returns a 32-bit CRC for a data buffer.145 /// 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
131 /// Copies the contents of one buffer to another buffer148 /// 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
134 /// Fills a buffer with a specified value151 /// 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, // TODO157 /// 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
139 pub const signature: u64 = 0x56524553544f4f42;178 pub const signature: u64 = 0x56524553544f4f42;
140179
...@@ -151,6 +190,8 @@ pub const BootServices = extern struct {...@@ -151,6 +190,8 @@ pub const BootServices = extern struct {
151 pub const tpl_high_level: usize = 31;190 pub const tpl_high_level: usize = 31;
152};191};
153192
193pub const EfiEventNotify = fn (event: Event, ctx: *anyopaque) callconv(.C) void;
194
154pub const TimerDelay = enum(u32) {195pub const TimerDelay = enum(u32) {
155 TimerCancel,196 TimerCancel,
156 TimerPeriodic,197 TimerPeriodic,
...@@ -219,9 +260,7 @@ pub const OpenProtocolAttributes = packed struct {...@@ -219,9 +260,7 @@ pub const OpenProtocolAttributes = packed struct {
219 by_child_controller: bool = false,260 by_child_controller: bool = false,
220 by_driver: bool = false,261 by_driver: bool = false,
221 exclusive: bool = false,262 exclusive: bool = false,
222 _pad1: u2 = undefined,263 _pad: u26 = 0,
223 _pad2: u8 = undefined,
224 _pad3: u16 = undefined,
225};264};
226265
227pub const ProtocolInformationEntry = extern struct {266pub const ProtocolInformationEntry = extern struct {
...@@ -231,6 +270,10 @@ pub const ProtocolInformationEntry = extern struct {...@@ -231,6 +270,10 @@ pub const ProtocolInformationEntry = extern struct {
231 open_count: u32,270 open_count: u32,
232};271};
233272
273pub const EfiInterfaceType = enum(u32) {
274 EfiNativeInterface,
275};
276
234pub const AllocateType = enum(u32) {277pub const AllocateType = enum(u32) {
235 AllocateAnyPages,278 AllocateAnyPages,
236 AllocateMaxAddress,279 AllocateMaxAddress,
lib/std/os/uefi/tables/runtime_services.zig+46-14
...@@ -18,39 +18,71 @@ pub const RuntimeServices = extern struct {...@@ -18,39 +18,71 @@ pub const RuntimeServices = extern struct {
18 hdr: TableHeader,18 hdr: TableHeader,
1919
20 /// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.20 /// 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, // TODO23 /// Sets the current local time and date information
24 getWakeupTime: Status, // TODO24 setTime: fn (time: *uefi.Time) callconv(.C) Status,
25 setWakeupTime: Status, // TODO25
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
27 /// Changes the runtime addressing mode of EFI firmware from physical to virtual.32 /// 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
30 /// Determines the new virtual address that is to be used on subsequent memory accesses.35 /// 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
33 /// Returns the value of a variable.38 /// 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
36 /// Enumerates the current variable names.41 /// 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
39 /// Sets the value of a variable.44 /// 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, // TODO47 /// Return the next high 32 bits of the platform's monotonic counter
48 getNextHighMonotonicCount: fn (high_count: *u32) callconv(.C) Status,
4349
44 /// Resets the entire platform.50 /// 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, // TODO60 /// Returns if the capsule can be supported via `updateCapsule`
48 queryCapsuleCapabilities: Status, // TODO61 queryCapsuleCapabilities: fn (capsule_header_array: **CapsuleHeader, capsule_count: usize, maximum_capsule_size: *usize, resetType: ResetType) callconv(.C) Status,
49 queryVariableInfo: Status, // TODO62
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
51 pub const signature: u64 = 0x56524553544e5552;66 pub const signature: u64 = 0x56524553544e5552;
52};67};
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
54pub const ResetType = enum(u32) {86pub const ResetType = enum(u32) {
55 ResetCold,87 ResetCold,
56 ResetWarm,88 ResetWarm,