From fa86e09fb39c8007c7b63e70ed7db1afc7022476 Mon Sep 17 00:00:00 2001 From: Carmen Date: Tue, 1 Apr 2025 03:47:51 -0700 Subject: [PATCH] std.os.uefi.protocol: ziggify function signatures (#23214) --- lib/std/debug.zig | 6 +- lib/std/os/uefi.zig | 66 +-- lib/std/os/uefi/protocol.zig | 23 +- lib/std/os/uefi/protocol/absolute_pointer.zig | 24 +- lib/std/os/uefi/protocol/block_io.zig | 64 ++- lib/std/os/uefi/protocol/device_path.zig | 20 +- lib/std/os/uefi/protocol/edid.zig | 34 +- lib/std/os/uefi/protocol/file.zig | 387 ++++++++++++++---- lib/std/os/uefi/protocol/graphics_output.zig | 69 +++- lib/std/os/uefi/protocol/hii_database.zig | 83 +++- lib/std/os/uefi/protocol/hii_popup.zig | 22 +- lib/std/os/uefi/protocol/ip6.zig | 291 +++++++++++-- lib/std/os/uefi/protocol/ip6_config.zig | 143 ++++++- .../os/uefi/protocol/ip6_service_binding.zig | 28 -- lib/std/os/uefi/protocol/loaded_image.zig | 13 +- lib/std/os/uefi/protocol/managed_network.zig | 174 ++++++-- lib/std/os/uefi/protocol/rng.zig | 35 +- lib/std/os/uefi/protocol/serial_io.zig | 101 ++++- lib/std/os/uefi/protocol/service_binding.zig | 60 +++ .../os/uefi/protocol/simple_file_system.zig | 30 +- lib/std/os/uefi/protocol/simple_network.zig | 350 ++++++++++++++-- lib/std/os/uefi/protocol/simple_pointer.zig | 27 +- .../os/uefi/protocol/simple_text_input.zig | 31 +- .../os/uefi/protocol/simple_text_input_ex.zig | 76 +++- .../os/uefi/protocol/simple_text_output.zig | 194 ++++++--- lib/std/os/uefi/protocol/udp6.zig | 167 +++++++- .../os/uefi/protocol/udp6_service_binding.zig | 28 -- 27 files changed, 2076 insertions(+), 470 deletions(-) delete mode 100644 lib/std/os/uefi/protocol/ip6_service_binding.zig create mode 100644 lib/std/os/uefi/protocol/service_binding.zig delete mode 100644 lib/std/os/uefi/protocol/udp6_service_binding.zig diff --git a/lib/std/debug.zig b/lib/std/debug.zig index f746b4162d..664999caa0 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -629,9 +629,9 @@ pub fn defaultPanic( // isn't visible on actual hardware if directly booted into inline for ([_]?*uefi.protocol.SimpleTextOutput{ uefi.system_table.std_err, uefi.system_table.con_out }) |o| { if (o) |out| { - _ = out.setAttribute(uefi.protocol.SimpleTextOutput.red); - _ = out.outputString(exit_msg); - _ = out.setAttribute(uefi.protocol.SimpleTextOutput.white); + out.setAttribute(.{ .foreground = .red }) catch {}; + _ = out.outputString(exit_msg) catch {}; + out.setAttribute(.{ .foreground = .white }) catch {}; } } diff --git a/lib/std/os/uefi.zig b/lib/std/os/uefi.zig index 9674e704dc..1402766669 100644 --- a/lib/std/os/uefi.zig +++ b/lib/std/os/uefi.zig @@ -43,6 +43,11 @@ pub const Ipv6Address = extern struct { address: [16]u8, }; +pub const IpAddress = extern union { + v4: Ipv4Address, + v6: Ipv6Address, +}; + /// GUIDs are align(8) unless otherwise specified. pub const Guid = extern struct { time_low: u32, @@ -190,60 +195,15 @@ test "GUID formatting" { try std.testing.expect(std.mem.eql(u8, str, "32cb3c89-8080-427c-ba13-5049873bc287")); } -pub const FileInfo = extern struct { - size: u64, - file_size: u64, - physical_size: u64, - create_time: Time, - last_access_time: Time, - modification_time: Time, - attribute: u64, - - pub fn getFileName(self: *const FileInfo) [*:0]const u16 { - return @ptrCast(@alignCast(@as([*]const u8, @ptrCast(self)) + @sizeOf(FileInfo))); - } - - pub const efi_file_read_only: u64 = 0x0000000000000001; - pub const efi_file_hidden: u64 = 0x0000000000000002; - pub const efi_file_system: u64 = 0x0000000000000004; - pub const efi_file_reserved: u64 = 0x0000000000000008; - pub const efi_file_directory: u64 = 0x0000000000000010; - pub const efi_file_archive: u64 = 0x0000000000000020; - pub const efi_file_valid_attr: u64 = 0x0000000000000037; - - pub const guid align(8) = Guid{ - .time_low = 0x09576e92, - .time_mid = 0x6d3f, - .time_high_and_version = 0x11d2, - .clock_seq_high_and_reserved = 0x8e, - .clock_seq_low = 0x39, - .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, - }; -}; - -pub const FileSystemInfo = extern struct { - size: u64, - read_only: bool, - volume_size: u64, - free_space: u64, - block_size: u32, - _volume_label: u16, - - pub fn getVolumeLabel(self: *const FileSystemInfo) [*:0]const u16 { - return @as([*:0]const u16, @ptrCast(&self._volume_label)); - } - - pub const guid align(8) = Guid{ - .time_low = 0x09576e93, - .time_mid = 0x6d3f, - .time_high_and_version = 0x11d2, - .clock_seq_high_and_reserved = 0x8e, - .clock_seq_low = 0x39, - .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, - }; -}; - test { _ = tables; _ = protocol; } + +pub const UnexpectedError = error{Unexpected}; + +pub fn unexpectedStatus(status: Status) UnexpectedError { + // TODO: debug printing the encountered error? maybe handle warnings? + _ = status; + return error.Unexpected; +} diff --git a/lib/std/os/uefi/protocol.zig b/lib/std/os/uefi/protocol.zig index 6f895177f9..05ab24baf1 100644 --- a/lib/std/os/uefi/protocol.zig +++ b/lib/std/os/uefi/protocol.zig @@ -1,3 +1,8 @@ +const std = @import("std"); +const uefi = std.os.uefi; + +pub const ServiceBinding = @import("protocol/service_binding.zig").ServiceBinding; + pub const LoadedImage = @import("protocol/loaded_image.zig").LoadedImage; pub const DevicePath = @import("protocol/device_path.zig").DevicePath; pub const Rng = @import("protocol/rng.zig").Rng; @@ -23,11 +28,25 @@ pub const edid = @import("protocol/edid.zig"); pub const SimpleNetwork = @import("protocol/simple_network.zig").SimpleNetwork; pub const ManagedNetwork = @import("protocol/managed_network.zig").ManagedNetwork; -pub const Ip6ServiceBinding = @import("protocol/ip6_service_binding.zig").Ip6ServiceBinding; +pub const Ip6ServiceBinding = ServiceBinding(.{ + .time_low = 0xec835dd3, + .time_mid = 0xfe0f, + .time_high_and_version = 0x617b, + .clock_seq_high_and_reserved = 0xa6, + .clock_seq_low = 0x21, + .node = [_]u8{ 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 }, +}); pub const Ip6 = @import("protocol/ip6.zig").Ip6; pub const Ip6Config = @import("protocol/ip6_config.zig").Ip6Config; -pub const Udp6ServiceBinding = @import("protocol/udp6_service_binding.zig").Udp6ServiceBinding; +pub const Udp6ServiceBinding = ServiceBinding(.{ + .time_low = 0x66ed4721, + .time_mid = 0x3c98, + .time_high_and_version = 0x4d3e, + .clock_seq_high_and_reserved = 0x81, + .clock_seq_low = 0xe3, + .node = [_]u8{ 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 }, +}); pub const Udp6 = @import("protocol/udp6.zig").Udp6; pub const HiiDatabase = @import("protocol/hii_database.zig").HiiDatabase; diff --git a/lib/std/os/uefi/protocol/absolute_pointer.zig b/lib/std/os/uefi/protocol/absolute_pointer.zig index e71f7b3cc8..175d02f4ff 100644 --- a/lib/std/os/uefi/protocol/absolute_pointer.zig +++ b/lib/std/os/uefi/protocol/absolute_pointer.zig @@ -4,22 +4,36 @@ const Event = uefi.Event; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// Protocol for touchscreens. pub const AbsolutePointer = extern struct { - _reset: *const fn (*const AbsolutePointer, bool) callconv(cc) Status, + _reset: *const fn (*AbsolutePointer, bool) callconv(cc) Status, _get_state: *const fn (*const AbsolutePointer, *State) callconv(cc) Status, wait_for_input: Event, mode: *Mode, + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const GetStateError = uefi.UnexpectedError || error{ NotReady, DeviceError }; + /// Resets the pointer device hardware. - pub fn reset(self: *const AbsolutePointer, verify: bool) Status { - return self._reset(self, verify); + pub fn reset(self: *AbsolutePointer, verify: bool) ResetError!void { + switch (self._reset(self, verify)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Retrieves the current state of a pointer device. - pub fn getState(self: *const AbsolutePointer, state: *State) Status { - return self._get_state(self, state); + pub fn getState(self: *const AbsolutePointer) GetStateError!State { + var state: State = undefined; + switch (self._get_state(self, &state)) { + .success => return state, + .not_ready => return Error.NotReady, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/block_io.zig b/lib/std/os/uefi/protocol/block_io.zig index eb204eabc5..2ba608d7fd 100644 --- a/lib/std/os/uefi/protocol/block_io.zig +++ b/lib/std/os/uefi/protocol/block_io.zig @@ -2,6 +2,7 @@ const std = @import("std"); const uefi = std.os.uefi; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; pub const BlockIo = extern struct { const Self = @This(); @@ -11,27 +12,72 @@ pub const BlockIo = extern struct { _reset: *const fn (*BlockIo, extended_verification: bool) callconv(cc) Status, _read_blocks: *const fn (*BlockIo, media_id: u32, lba: u64, buffer_size: usize, buf: [*]u8) callconv(cc) Status, - _write_blocks: *const fn (*BlockIo, media_id: u32, lba: u64, buffer_size: usize, buf: [*]u8) callconv(cc) Status, + _write_blocks: *const fn (*BlockIo, media_id: u32, lba: u64, buffer_size: usize, buf: [*]const u8) callconv(cc) Status, _flush_blocks: *const fn (*BlockIo) callconv(cc) Status, + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const ReadBlocksError = uefi.UnexpectedError || error{ + DeviceError, + NoMedia, + BadBufferSize, + InvalidParameter, + }; + pub const WriteBlocksError = uefi.UnexpectedError || error{ + WriteProtected, + NoMedia, + MediaChanged, + DeviceError, + BadBufferSize, + InvalidParameter, + }; + pub const FlushBlocksError = uefi.UnexpectedError || error{ + DeviceError, + NoMedia, + }; + /// Resets the block device hardware. - pub fn reset(self: *Self, extended_verification: bool) Status { - return self._reset(self, extended_verification); + pub fn reset(self: *Self, extended_verification: bool) ResetError!void { + switch (self._reset(self, extended_verification)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Reads the number of requested blocks from the device. - pub fn readBlocks(self: *Self, media_id: u32, lba: u64, buffer_size: usize, buf: [*]u8) Status { - return self._read_blocks(self, media_id, lba, buffer_size, buf); + pub fn readBlocks(self: *Self, media_id: u32, lba: u64, buf: []u8) ReadBlocksError!void { + switch (self._read_blocks(self, media_id, lba, buf.len, buf.ptr)) { + .success => {}, + .device_error => return Error.DeviceError, + .no_media => return Error.NoMedia, + .bad_buffer_size => return Error.BadBufferSize, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } /// Writes a specified number of blocks to the device. - pub fn writeBlocks(self: *Self, media_id: u32, lba: u64, buffer_size: usize, buf: [*]u8) Status { - return self._write_blocks(self, media_id, lba, buffer_size, buf); + pub fn writeBlocks(self: *Self, media_id: u32, lba: u64, buf: []const u8) WriteBlocksError!void { + switch (self._write_blocks(self, media_id, lba, buf.len, buf.ptr)) { + .success => {}, + .write_protected => return Error.WriteProtected, + .no_media => return Error.NoMedia, + .media_changed => return Error.MediaChanged, + .device_error => return Error.DeviceError, + .bad_buffer_size => return Error.BadBufferSize, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } /// Flushes all modified data to a physical block device. - pub fn flushBlocks(self: *Self) Status { - return self._flush_blocks(self); + pub fn flushBlocks(self: *Self) FlushBlocksError!void { + switch (self._flush_blocks(self)) { + .success => {}, + .device_error => return Error.DeviceError, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = uefi.Guid{ diff --git a/lib/std/os/uefi/protocol/device_path.zig b/lib/std/os/uefi/protocol/device_path.zig index 49e1dc13b4..7ca2b942e1 100644 --- a/lib/std/os/uefi/protocol/device_path.zig +++ b/lib/std/os/uefi/protocol/device_path.zig @@ -13,6 +13,8 @@ pub const DevicePath = extern struct { subtype: u8, length: u16 align(1), + pub const CreateFileDevicePathError = Allocator.Error; + pub const guid align(8) = Guid{ .time_low = 0x09576e91, .time_mid = 0x6d3f, @@ -23,15 +25,17 @@ pub const DevicePath = extern struct { }; /// Returns the next DevicePath node in the sequence, if any. - pub fn next(self: *DevicePath) ?*DevicePath { - if (self.type == .end and @as(uefi.DevicePath.End.Subtype, @enumFromInt(self.subtype)) == .end_entire) + pub fn next(self: *const DevicePath) ?*const DevicePath { + const bytes: [*]const u8 = @ptrCast(self); + const next_node: *const DevicePath = @ptrCast(bytes + self.length); + if (next_node.type == .end and @as(uefi.DevicePath.End.Subtype, @enumFromInt(self.subtype)) == .end_entire) return null; - return @as(*DevicePath, @ptrCast(@as([*]u8, @ptrCast(self)) + self.length)); + return next_node; } /// Calculates the total length of the device path structure in bytes, including the end of device path node. - pub fn size(self: *DevicePath) usize { + pub fn size(self: *const DevicePath) usize { var node = self; while (node.next()) |next_node| { @@ -42,7 +46,11 @@ pub const DevicePath = extern struct { } /// Creates a file device path from the existing device path and a file path. - pub fn create_file_device_path(self: *DevicePath, allocator: Allocator, path: [:0]align(1) const u16) !*DevicePath { + pub fn createFileDevicePath( + self: *const DevicePath, + allocator: Allocator, + path: []const u16, + ) CreateFileDevicePathError!*const DevicePath { const path_size = self.size(); // 2 * (path.len + 1) for the path and its null terminator, which are u16s @@ -67,7 +75,7 @@ pub const DevicePath = extern struct { ptr[path.len] = 0; - var end = @as(*uefi.DevicePath.End.EndEntireDevicePath, @ptrCast(@as(*DevicePath, @ptrCast(new)).next().?)); + var end = @as(*uefi.DevicePath.End.EndEntireDevicePath, @ptrCast(@constCast(@as(*DevicePath, @ptrCast(new)).next().?))); end.type = .end; end.subtype = .end_entire; end.length = @sizeOf(uefi.DevicePath.End.EndEntireDevicePath); diff --git a/lib/std/os/uefi/protocol/edid.zig b/lib/std/os/uefi/protocol/edid.zig index 8392dc7370..97e0601e2f 100644 --- a/lib/std/os/uefi/protocol/edid.zig +++ b/lib/std/os/uefi/protocol/edid.zig @@ -4,6 +4,7 @@ const Guid = uefi.Guid; const Handle = uefi.Handle; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// EDID information for an active video output device pub const Active = extern struct { @@ -37,17 +38,27 @@ pub const Discovered = extern struct { /// Override EDID information pub const Override = extern struct { - _get_edid: *const fn (*const Override, Handle, *Attributes, *usize, *?[*]u8) callconv(cc) Status, + _get_edid: *const fn (*const Override, *const Handle, *Attributes, *usize, *?[*]u8) callconv(cc) Status, + + pub const GetEdidError = uefi.UnexpectedError || error{ + Unsupported, + }; /// Returns policy information and potentially a replacement EDID for the specified video output device. - pub fn getEdid( - self: *const Override, - handle: Handle, - attributes: *Attributes, - edid_size: *usize, - edid: *?[*]u8, - ) Status { - return self._get_edid(self, handle, attributes, edid_size, edid); + pub fn getEdid(self: *const Override, handle: Handle) GetEdidError!Edid { + var size: usize = undefined; + var ptr: ?[*]u8 = undefined; + var attributes: Attributes = undefined; + switch (self._get_edid(self, &handle, &attributes, &size, &ptr)) { + .success => {}, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } + + return .{ + .attributes = attributes, + .edid = if (ptr) |p| p[0..size] else null, + }; } pub const guid align(8) = Guid{ @@ -59,6 +70,11 @@ pub const Override = extern struct { .node = [_]u8{ 0xf4, 0x58, 0xfe, 0x04, 0x0b, 0xd5 }, }; + pub const Edid = struct { + attributes: Attributes, + edid: ?[]u8, + }; + pub const Attributes = packed struct(u32) { dont_override: bool, enable_hot_plug: bool, diff --git a/lib/std/os/uefi/protocol/file.zig b/lib/std/os/uefi/protocol/file.zig index d69ae14ce6..f586dd9665 100644 --- a/lib/std/os/uefi/protocol/file.zig +++ b/lib/std/os/uefi/protocol/file.zig @@ -5,28 +5,89 @@ const Guid = uefi.Guid; const Time = uefi.Time; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; pub const File = extern struct { revision: u64, - _open: *const fn (*const File, **const File, [*:0]const u16, u64, u64) callconv(cc) Status, - _close: *const fn (*const File) callconv(cc) Status, - _delete: *const fn (*const File) callconv(cc) Status, - _read: *const fn (*const File, *usize, [*]u8) callconv(cc) Status, - _write: *const fn (*const File, *usize, [*]const u8) callconv(cc) Status, + _open: *const fn (*const File, **File, [*:0]const u16, u64, u64) callconv(cc) Status, + _close: *const fn (*File) callconv(cc) Status, + _delete: *const fn (*File) callconv(cc) Status, + _read: *const fn (*File, *usize, [*]u8) callconv(cc) Status, + _write: *const fn (*File, *usize, [*]const u8) callconv(cc) Status, _get_position: *const fn (*const File, *u64) callconv(cc) Status, - _set_position: *const fn (*const File, u64) callconv(cc) Status, + _set_position: *const fn (*File, u64) callconv(cc) Status, _get_info: *const fn (*const File, *align(8) const Guid, *const usize, [*]u8) callconv(cc) Status, - _set_info: *const fn (*const File, *align(8) const Guid, usize, [*]const u8) callconv(cc) Status, - _flush: *const fn (*const File) callconv(cc) Status, + _set_info: *const fn (*File, *align(8) const Guid, usize, [*]const u8) callconv(cc) Status, + _flush: *const fn (*File) callconv(cc) Status, - pub const SeekError = error{SeekError}; - pub const GetSeekPosError = error{GetSeekPosError}; - pub const ReadError = error{ReadError}; - pub const WriteError = error{WriteError}; + pub const OpenError = uefi.UnexpectedError || error{ + NotFound, + NoMedia, + MediaChanged, + DeviceError, + VolumeCorrupted, + WriteProtected, + AccessDenied, + OutOfResources, + VolumeFull, + InvalidParameter, + }; + pub const CloseError = uefi.UnexpectedError; + pub const SeekError = uefi.UnexpectedError || error{ + Unsupported, + DeviceError, + }; + pub const ReadError = uefi.UnexpectedError || error{ + NoMedia, + DeviceError, + VolumeCorrupted, + BufferTooSmall, + }; + pub const WriteError = uefi.UnexpectedError || error{ + Unsupported, + NoMedia, + DeviceError, + VolumeCorrupted, + WriteProtected, + AccessDenied, + VolumeFull, + }; + pub const GetInfoError = uefi.UnexpectedError || error{ + Unsupported, + NoMedia, + DeviceError, + VolumeCorrupted, + BufferTooSmall, + }; + pub const SetInfoError = uefi.UnexpectedError || error{ + Unsupported, + NoMedia, + DeviceError, + VolumeCorrupted, + WriteProtected, + AccessDenied, + VolumeFull, + BadBufferSize, + }; + pub const FlushError = uefi.UnexpectedError || error{ + DeviceError, + VolumeCorrupted, + WriteProtected, + AccessDenied, + VolumeFull, + }; - pub const SeekableStream = io.SeekableStream(*const File, SeekError, GetSeekPosError, seekTo, seekBy, getPos, getEndPos); - pub const Reader = io.Reader(*const File, ReadError, readFn); - pub const Writer = io.Writer(*const File, WriteError, writeFn); + pub const SeekableStream = io.SeekableStream( + *File, + SeekError, + SeekError, + setPosition, + seekBy, + getPosition, + getEndPos, + ); + pub const Reader = io.Reader(*File, ReadError, read); + pub const Writer = io.Writer(*File, WriteError, write); pub fn seekableStream(self: *File) SeekableStream { return .{ .context = self }; @@ -40,75 +101,111 @@ pub const File = extern struct { return .{ .context = self }; } - pub fn open(self: *const File, new_handle: **const File, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status { - return self._open(self, new_handle, file_name, open_mode, attributes); + pub fn open( + self: *const File, + file_name: [*:0]const u16, + mode: OpenMode, + create_attributes: Attributes, + ) OpenError!*File { + var new: *File = undefined; + switch (self._open( + self, + &new, + file_name, + @intFromEnum(mode), + @bitCast(create_attributes), + )) { + .success => return new, + .not_found => return Error.NotFound, + .no_media => return Error.NoMedia, + .media_changed => return Error.MediaChanged, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .write_protected => return Error.WriteProtected, + .access_denied => return Error.AccessDenied, + .out_of_resources => return Error.OutOfResources, + .volume_full => return Error.VolumeFull, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn close(self: *const File) Status { - return self._close(self); + pub fn close(self: *File) CloseError!void { + switch (self._close(self)) { + .success => {}, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn delete(self: *const File) Status { - return self._delete(self); + /// Delete the file. + /// + /// Returns true if the file was deleted, false if the file was not deleted, which is a warning + /// according to the UEFI specification. + pub fn delete(self: *File) uefi.UnexpectedError!bool { + switch (self._delete(self)) { + .success => return true, + .warn_delete_failure => return false, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn read(self: *const File, buffer_size: *usize, buffer: [*]u8) Status { - return self._read(self, buffer_size, buffer); - } - - fn readFn(self: *const File, buffer: []u8) ReadError!usize { + pub fn read(self: *File, buffer: []u8) ReadError!usize { var size: usize = buffer.len; - if (.success != self.read(&size, buffer.ptr)) return ReadError.ReadError; - return size; + switch (self._read(self, &size, buffer.ptr)) { + .success => return size, + .no_media => return Error.NoMedia, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .buffer_too_small => return Error.BufferTooSmall, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn write(self: *const File, buffer_size: *usize, buffer: [*]const u8) Status { - return self._write(self, buffer_size, buffer); + pub fn write(self: *File, buffer: []const u8) WriteError!usize { + var size: usize = buffer.len; + switch (self._write(self, &size, buffer.ptr)) { + .success => return size, + .unsupported => return Error.Unsupported, + .no_media => return Error.NoMedia, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .write_protected => return Error.WriteProtected, + .access_denied => return Error.AccessDenied, + .volume_full => return Error.VolumeFull, + else => |status| return uefi.unexpectedStatus(status), + } } - fn writeFn(self: *const File, bytes: []const u8) WriteError!usize { - var size: usize = bytes.len; - if (.success != self.write(&size, bytes.ptr)) return WriteError.WriteError; - return size; + pub fn getPosition(self: *const File) SeekError!u64 { + var position: u64 = undefined; + switch (self._get_position(self, &position)) { + .success => return position, + .unsupported => return Error.Unsupported, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn getPosition(self: *const File, position: *u64) Status { - return self._get_position(self, position); + fn getEndPos(self: *File) SeekError!u64 { + const start_pos = try self.getPosition(); + // ignore error + defer self.setPosition(start_pos) catch {}; + + try self.setPosition(end_of_file); + return self.getPosition(); } - fn getPos(self: *const File) GetSeekPosError!u64 { - var pos: u64 = undefined; - if (.success != self.getPosition(&pos)) return GetSeekPosError.GetSeekPosError; - return pos; + pub fn setPosition(self: *File, position: u64) SeekError!void { + switch (self._set_position(self, position)) { + .success => {}, + .unsupported => return Error.Unsupported, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } - fn getEndPos(self: *const File) GetSeekPosError!u64 { - // preserve the old file position - var pos: u64 = undefined; - var end_pos: u64 = undefined; - if (.success != self.getPosition(&pos)) return GetSeekPosError.GetSeekPosError; - // seek to end of file to get position = file size - if (.success != self.setPosition(efi_file_position_end_of_file)) return GetSeekPosError.GetSeekPosError; - // get the position - if (.success != self.getPosition(&end_pos)) return GetSeekPosError.GetSeekPosError; - // restore the old position - if (.success != self.setPosition(pos)) return GetSeekPosError.GetSeekPosError; - // return the file size = position - return end_pos; - } - - pub fn setPosition(self: *const File, position: u64) Status { - return self._set_position(self, position); - } - - fn seekTo(self: *const File, pos: u64) SeekError!void { - if (.success != self.setPosition(pos)) return SeekError.SeekError; - } - - fn seekBy(self: *const File, offset: i64) SeekError!void { - // save the old position and calculate the delta - var pos: u64 = undefined; - if (.success != self.getPosition(&pos)) return SeekError.SeekError; + fn seekBy(self: *File, offset: i64) SeekError!void { + var pos = try self.getPosition(); const seek_back = offset < 0; const amt = @abs(offset); if (seek_back) { @@ -116,32 +213,152 @@ pub const File = extern struct { } else { pos -= amt; } - if (.success != self.setPosition(pos)) return SeekError.SeekError; + try self.setPosition(pos); } - pub fn getInfo(self: *const File, information_type: *align(8) const Guid, buffer_size: *usize, buffer: [*]u8) Status { - return self._get_info(self, information_type, buffer_size, buffer); + pub fn getInfo( + self: *const File, + comptime info: std.meta.Tag(Info), + ) GetInfoError!std.meta.TagPayload(Info, info) { + const InfoType = std.meta.TagPayload(Info, info); + + var val: InfoType = undefined; + var len: usize = @sizeOf(InfoType); + switch (self._get_info(self, &InfoType.guid, &len, @ptrCast(&val))) { + .success => return val, + .unsupported => return Error.Unsupported, + .no_media => return Error.NoMedia, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .buffer_too_small => return Error.BufferTooSmall, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn setInfo(self: *const File, information_type: *align(8) const Guid, buffer_size: usize, buffer: [*]const u8) Status { - return self._set_info(self, information_type, buffer_size, buffer); + pub fn setInfo( + self: *File, + comptime info: std.meta.Tag(Info), + data: *const std.meta.TagPayload(Info, info), + ) SetInfoError!void { + const InfoType = @TypeOf(data); + switch (self._set_info(self, &InfoType.guid, @sizeOf(InfoType), @ptrCast(data))) { + .success => {}, + .unsupported => return Error.Unsupported, + .no_media => return Error.NoMedia, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .write_protected => return Error.WriteProtected, + .access_denied => return Error.AccessDenied, + .volume_full => return Error.VolumeFull, + .bad_buffer_size => return Error.BadBufferSize, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn flush(self: *const File) Status { - return self._flush(self); + pub fn flush(self: *File) FlushError!void { + switch (self._flush(self)) { + .success => {}, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .write_protected => return Error.WriteProtected, + .access_denied => return Error.AccessDenied, + .volume_full => return Error.VolumeFull, + else => |status| return uefi.unexpectedStatus(status), + } } - pub const efi_file_mode_read: u64 = 0x0000000000000001; - pub const efi_file_mode_write: u64 = 0x0000000000000002; - pub const efi_file_mode_create: u64 = 0x8000000000000000; + pub const OpenMode = enum(u64) { + read = 0x0000000000000001, + // implies read + write = 0x0000000000000002, + // implies read+write + create = 0x8000000000000000, + }; - pub const efi_file_read_only: u64 = 0x0000000000000001; - pub const efi_file_hidden: u64 = 0x0000000000000002; - pub const efi_file_system: u64 = 0x0000000000000004; - pub const efi_file_reserved: u64 = 0x0000000000000008; - pub const efi_file_directory: u64 = 0x0000000000000010; - pub const efi_file_archive: u64 = 0x0000000000000020; - pub const efi_file_valid_attr: u64 = 0x0000000000000037; + pub const Attributes = packed struct(u64) { + // 0x0000000000000001 + read_only: bool = false, + // 0x0000000000000002 + hidden: bool = false, + // 0x0000000000000004 + system: bool = false, + // 0x0000000000000008 + reserved: bool = false, + // 0x0000000000000010 + directory: bool = false, + // 0x0000000000000020 + archive: bool = false, + _pad: u58 = 0, + }; - pub const efi_file_position_end_of_file: u64 = 0xffffffffffffffff; + pub const Info = union(enum) { + file: Info.File, + file_system: FileSystem, + volume_label: VolumeLabel, + + pub const File = extern struct { + size: u64, + file_size: u64, + physical_size: u64, + create_time: Time, + last_access_time: Time, + modification_time: Time, + attribute: Attributes, + _file_name: u16, + + pub fn getFileName(self: *const Info.File) [*:0]const u16 { + return @as([*:0]const u16, @ptrCast(&self._file_name)); + } + + pub const guid align(8) = Guid{ + .time_low = 0x09576e92, + .time_mid = 0x6d3f, + .time_high_and_version = 0x11d2, + .clock_seq_high_and_reserved = 0x8e, + .clock_seq_low = 0x39, + .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, + }; + }; + + pub const FileSystem = extern struct { + size: u64, + read_only: bool, + volume_size: u64, + free_space: u64, + block_size: u32, + _volume_label: u16, + + pub fn getVolumeLabel(self: *const FileSystem) [*:0]const u16 { + return @as([*:0]const u16, @ptrCast(&self._volume_label)); + } + + pub const guid align(8) = Guid{ + .time_low = 0x09576e93, + .time_mid = 0x6d3f, + .time_high_and_version = 0x11d2, + .clock_seq_high_and_reserved = 0x8e, + .clock_seq_low = 0x39, + .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b }, + }; + }; + + pub const VolumeLabel = extern struct { + _volume_label: u16, + + pub fn getVolumeLabel(self: *const VolumeLabel) [*:0]const u16 { + return @as([*:0]const u16, @ptrCast(&self._volume_label)); + } + + pub const guid align(8) = Guid{ + .time_low = 0xdb47d7d3, + .time_mid = 0xfe81, + .time_high_and_version = 0x11d3, + .clock_seq_high_and_reserved = 0x9a, + .clock_seq_low = 0x35, + .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }, + }; + }; + }; + + const end_of_file: u64 = 0xffffffffffffffff; }; diff --git a/lib/std/os/uefi/protocol/graphics_output.zig b/lib/std/os/uefi/protocol/graphics_output.zig index dd0c248253..eba19fc0f5 100644 --- a/lib/std/os/uefi/protocol/graphics_output.zig +++ b/lib/std/os/uefi/protocol/graphics_output.zig @@ -3,26 +3,79 @@ const uefi = std.os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; pub const GraphicsOutput = extern struct { _query_mode: *const fn (*const GraphicsOutput, u32, *usize, **Mode.Info) callconv(cc) Status, - _set_mode: *const fn (*const GraphicsOutput, u32) callconv(cc) Status, - _blt: *const fn (*const GraphicsOutput, ?[*]BltPixel, BltOperation, usize, usize, usize, usize, usize, usize, usize) callconv(cc) Status, + _set_mode: *const fn (*GraphicsOutput, u32) callconv(cc) Status, + _blt: *const fn (*GraphicsOutput, ?[*]BltPixel, BltOperation, usize, usize, usize, usize, usize, usize, usize) callconv(cc) Status, mode: *Mode, + pub const QueryModeError = uefi.UnexpectedError || error{ + DeviceError, + InvalidParameter, + }; + pub const SetModeError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const BltError = uefi.UnexpectedError || error{ + InvalidParameter, + DeviceError, + }; + /// Returns information for an available graphics mode that the graphics device and the set of active video output devices supports. - pub fn queryMode(self: *const GraphicsOutput, mode: u32, size_of_info: *usize, info: **Mode.Info) Status { - return self._query_mode(self, mode, size_of_info, info); + pub fn queryMode(self: *const GraphicsOutput, mode_id: u32) QueryModeError!*Mode.Info { + var size_of_info: usize = undefined; + var info: *Mode.Info = undefined; + switch (self._query_mode(self, mode_id, &size_of_info, &info)) { + .success => return info, + .device_error => return Error.DeviceError, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } /// Set the video device into the specified mode and clears the visible portions of the output display to black. - pub fn setMode(self: *const GraphicsOutput, mode: u32) Status { - return self._set_mode(self, mode); + pub fn setMode(self: *GraphicsOutput, mode_id: u32) SetModeError!void { + switch (self._set_mode(self, mode_id)) { + .success => {}, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer. - pub fn blt(self: *const GraphicsOutput, blt_buffer: ?[*]BltPixel, blt_operation: BltOperation, source_x: usize, source_y: usize, destination_x: usize, destination_y: usize, width: usize, height: usize, delta: usize) Status { - return self._blt(self, blt_buffer, blt_operation, source_x, source_y, destination_x, destination_y, width, height, delta); + pub fn blt( + self: *GraphicsOutput, + blt_buffer: ?[*]BltPixel, + blt_operation: BltOperation, + source_x: usize, + source_y: usize, + destination_x: usize, + destination_y: usize, + width: usize, + height: usize, + delta: usize, + ) BltError!void { + switch (self._blt( + self, + blt_buffer, + blt_operation, + source_x, + source_y, + destination_x, + destination_y, + width, + height, + delta, + )) { + .success => {}, + .device_error => return Error.DeviceError, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/hii_database.zig b/lib/std/os/uefi/protocol/hii_database.zig index 8b292ba342..f974dd7907 100644 --- a/lib/std/os/uefi/protocol/hii_database.zig +++ b/lib/std/os/uefi/protocol/hii_database.zig @@ -4,14 +4,15 @@ const Guid = uefi.Guid; const Status = uefi.Status; const hii = uefi.hii; const cc = uefi.cc; +const Error = Status.Error; /// Database manager for HII-related data structures. pub const HiiDatabase = extern struct { _new_package_list: Status, // TODO - _remove_package_list: *const fn (*const HiiDatabase, hii.Handle) callconv(cc) Status, - _update_package_list: *const fn (*const HiiDatabase, hii.Handle, *const hii.PackageList) callconv(cc) Status, + _remove_package_list: *const fn (*HiiDatabase, hii.Handle) callconv(cc) Status, + _update_package_list: *const fn (*HiiDatabase, hii.Handle, *const hii.PackageList) callconv(cc) Status, _list_package_lists: *const fn (*const HiiDatabase, u8, ?*const Guid, *usize, [*]hii.Handle) callconv(cc) Status, - _export_package_lists: *const fn (*const HiiDatabase, ?hii.Handle, *usize, *hii.PackageList) callconv(cc) Status, + _export_package_lists: *const fn (*const HiiDatabase, ?hii.Handle, *usize, [*]hii.PackageList) callconv(cc) Status, _register_package_notify: Status, // TODO _unregister_package_notify: Status, // TODO _find_keyboard_layouts: Status, // TODO @@ -19,24 +20,84 @@ pub const HiiDatabase = extern struct { _set_keyboard_layout: Status, // TODO _get_package_list_handle: Status, // TODO + pub const RemovePackageListError = uefi.UnexpectedError || error{NotFound}; + pub const UpdatePackageListError = uefi.UnexpectedError || error{ + OutOfResources, + InvalidParameter, + NotFound, + }; + pub const ListPackageListsError = uefi.UnexpectedError || error{ + BufferTooSmall, + InvalidParameter, + NotFound, + }; + pub const ExportPackageListError = uefi.UnexpectedError || error{ + BufferTooSmall, + InvalidParameter, + NotFound, + }; + /// Removes a package list from the HII database. - pub fn removePackageList(self: *const HiiDatabase, handle: hii.Handle) Status { - return self._remove_package_list(self, handle); + pub fn removePackageList(self: *HiiDatabase, handle: hii.Handle) !void { + switch (self._remove_package_list(self, handle)) { + .success => {}, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } /// Update a package list in the HII database. - pub fn updatePackageList(self: *const HiiDatabase, handle: hii.Handle, buffer: *const hii.PackageList) Status { - return self._update_package_list(self, handle, buffer); + pub fn updatePackageList( + self: *HiiDatabase, + handle: hii.Handle, + buffer: *const hii.PackageList, + ) UpdatePackageListError!void { + switch (self._update_package_list(self, handle, buffer)) { + .success => {}, + .out_of_resources => return Error.OutOfResources, + .invalid_parameter => return Error.InvalidParameter, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } /// Determines the handles that are currently active in the database. - pub fn listPackageLists(self: *const HiiDatabase, package_type: u8, package_guid: ?*const Guid, buffer_length: *usize, handles: [*]hii.Handle) Status { - return self._list_package_lists(self, package_type, package_guid, buffer_length, handles); + pub fn listPackageLists( + self: *const HiiDatabase, + package_type: u8, + package_guid: ?*const Guid, + handles: []hii.Handle, + ) ListPackageListsError![]hii.Handle { + var len: usize = handles.len; + switch (self._list_package_lists( + self, + package_type, + package_guid, + &len, + handles.ptr, + )) { + .success => return handles[0..len], + .buffer_too_small => return Error.BufferTooSmall, + .invalid_parameter => return Error.InvalidParameter, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } /// Exports the contents of one or all package lists in the HII database into a buffer. - pub fn exportPackageLists(self: *const HiiDatabase, handle: ?hii.Handle, buffer_size: *usize, buffer: *hii.PackageList) Status { - return self._export_package_lists(self, handle, buffer_size, buffer); + pub fn exportPackageLists( + self: *const HiiDatabase, + handle: ?hii.Handle, + buffer: []hii.PackageList, + ) ExportPackageListError![]hii.PackageList { + var len = buffer.len; + switch (self._export_package_lists(self, handle, &len, buffer.ptr)) { + .success => return buffer[0..len], + .buffer_too_small => return Error.BufferTooSmall, + .invalid_parameter => return Error.InvalidParameter, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/hii_popup.zig b/lib/std/os/uefi/protocol/hii_popup.zig index eac5745630..19a9b4ace6 100644 --- a/lib/std/os/uefi/protocol/hii_popup.zig +++ b/lib/std/os/uefi/protocol/hii_popup.zig @@ -4,15 +4,33 @@ const Guid = uefi.Guid; const Status = uefi.Status; const hii = uefi.hii; const cc = uefi.cc; +const Error = Status.Error; /// Display a popup window pub const HiiPopup = extern struct { revision: u64, _create_popup: *const fn (*const HiiPopup, PopupStyle, PopupType, hii.Handle, u16, ?*PopupSelection) callconv(cc) Status, + pub const CreatePopupError = uefi.UnexpectedError || error{ + InvalidParameter, + OutOfResources, + }; + /// Displays a popup window. - pub fn createPopup(self: *const HiiPopup, style: PopupStyle, popup_type: PopupType, handle: hii.Handle, msg: u16, user_selection: ?*PopupSelection) Status { - return self._create_popup(self, style, popup_type, handle, msg, user_selection); + pub fn createPopup( + self: *const HiiPopup, + style: PopupStyle, + popup_type: PopupType, + handle: hii.Handle, + msg: u16, + ) CreatePopupError!PopupSelection { + var res: PopupSelection = undefined; + switch (self._create_popup(self, style, popup_type, handle, msg, &res)) { + .success => return res, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/ip6.zig b/lib/std/os/uefi/protocol/ip6.zig index ebb28b97c8..802ea3cde8 100644 --- a/lib/std/os/uefi/protocol/ip6.zig +++ b/lib/std/os/uefi/protocol/ip6.zig @@ -7,61 +7,290 @@ const MacAddress = uefi.MacAddress; const ManagedNetworkConfigData = uefi.protocol.ManagedNetwork.Config; const SimpleNetwork = uefi.protocol.SimpleNetwork; const cc = uefi.cc; +const Error = Status.Error; pub const Ip6 = extern struct { _get_mode_data: *const fn (*const Ip6, ?*Mode, ?*ManagedNetworkConfigData, ?*SimpleNetwork) callconv(cc) Status, - _configure: *const fn (*const Ip6, ?*const Config) callconv(cc) Status, - _groups: *const fn (*const Ip6, bool, ?*const Address) callconv(cc) Status, - _routes: *const fn (*const Ip6, bool, ?*const Address, u8, ?*const Address) callconv(cc) Status, - _neighbors: *const fn (*const Ip6, bool, *const Address, ?*const MacAddress, u32, bool) callconv(cc) Status, - _transmit: *const fn (*const Ip6, *CompletionToken) callconv(cc) Status, - _receive: *const fn (*const Ip6, *CompletionToken) callconv(cc) Status, - _cancel: *const fn (*const Ip6, ?*CompletionToken) callconv(cc) Status, - _poll: *const fn (*const Ip6) callconv(cc) Status, + _configure: *const fn (*Ip6, ?*const Config) callconv(cc) Status, + _groups: *const fn (*Ip6, bool, ?*const Address) callconv(cc) Status, + _routes: *const fn (*Ip6, bool, ?*const Address, u8, ?*const Address) callconv(cc) Status, + _neighbors: *const fn (*Ip6, bool, *const Address, ?*const MacAddress, u32, bool) callconv(cc) Status, + _transmit: *const fn (*Ip6, *CompletionToken) callconv(cc) Status, + _receive: *const fn (*Ip6, *CompletionToken) callconv(cc) Status, + _cancel: *const fn (*Ip6, ?*CompletionToken) callconv(cc) Status, + _poll: *const fn (*Ip6) callconv(cc) Status, + + pub const GetModeDataError = uefi.UnexpectedError || error{ + InvalidParameter, + OutOfResources, + }; + pub const ConfigureError = uefi.UnexpectedError || error{ + InvalidParameter, + OutOfResources, + NoMapping, + AlreadyStarted, + DeviceError, + Unsupported, + }; + pub const GroupsError = uefi.UnexpectedError || error{ + InvalidParameter, + NotStarted, + OutOfResources, + Unsupported, + AlreadyStarted, + NotFound, + DeviceError, + }; + pub const RoutesError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + OutOfResources, + NotFound, + AccessDenied, + }; + pub const NeighborsError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + OutOfResources, + NotFound, + AccessDenied, + }; + pub const TransmitError = uefi.UnexpectedError || error{ + NotStarted, + NoMapping, + InvalidParameter, + AccessDenied, + NotReady, + NotFound, + OutOfResources, + BufferTooSmall, + BadBufferSize, + DeviceError, + NoMedia, + }; + pub const ReceiveError = uefi.UnexpectedError || error{ + NotStarted, + NoMapping, + InvalidParameter, + OutOfResources, + DeviceError, + AccessDenied, + NotReady, + NoMedia, + }; + pub const CancelError = uefi.UnexpectedError || error{ + InvalidParameter, + NotStarted, + NotFound, + DeviceError, + }; + pub const PollError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Timeout, + }; + + pub const ModeData = struct { + ip6_mode: Mode, + mnp_config: ManagedNetworkConfigData, + snp_mode: SimpleNetwork, + }; /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver. - pub fn getModeData(self: *const Ip6, ip6_mode_data: ?*Mode, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetwork) Status { - return self._get_mode_data(self, ip6_mode_data, mnp_config_data, snp_mode_data); + pub fn getModeData(self: *const Ip6) GetModeDataError!ModeData { + var data: ModeData = undefined; + switch (self._get_mode_data(self, &data.ip6_mode, &data.mnp_config, &data.snp_mode)) { + .success => return data, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + else => |status| return uefi.unexpectedStatus(status), + } } /// Assign IPv6 address and other configuration parameter to this EFI IPv6 Protocol driver instance. - pub fn configure(self: *const Ip6, ip6_config_data: ?*const Config) Status { - return self._configure(self, ip6_config_data); + /// + /// To reset the configuration, use `disable` instead. + pub fn configure(self: *Ip6, ip6_config_data: *const Config) ConfigureError!void { + switch (self._configure(self, ip6_config_data)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .no_mapping => return Error.NoMapping, + .already_started => return Error.AlreadyStarted, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } + } + + pub fn disable(self: *Ip6) ConfigureError!void { + switch (self._configure(self, null)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .no_mapping => return Error.NoMapping, + .already_started => return Error.AlreadyStarted, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } + } + + pub fn leaveAllGroups(self: *Ip6) GroupsError!void { + switch (self._groups(self, false, null)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .not_started => return Error.NotStarted, + .out_of_resources => return Error.OutOfResources, + .unsupported => return Error.Unsupported, + .already_started => return Error.AlreadyStarted, + .not_found => return Error.NotFound, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Joins and leaves multicast groups. - pub fn groups(self: *const Ip6, join_flag: bool, group_address: ?*const Address) Status { - return self._groups(self, join_flag, group_address); + /// + /// To leave all groups, use `leaveAllGroups` instead. + pub fn groups( + self: *Ip6, + join_flag: JoinFlag, + group_address: *const Address, + ) GroupsError!void { + switch (self._groups( + self, + // set to TRUE to join the multicast group session and FALSE to leave + join_flag == .join, + group_address, + )) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .not_started => return Error.NotStarted, + .out_of_resources => return Error.OutOfResources, + .unsupported => return Error.Unsupported, + .already_started => return Error.AlreadyStarted, + .not_found => return Error.NotFound, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Adds and deletes routing table entries. - pub fn routes(self: *const Ip6, delete_route: bool, destination: ?*const Address, prefix_length: u8, gateway_address: ?*const Address) Status { - return self._routes(self, delete_route, destination, prefix_length, gateway_address); + pub fn routes( + self: *Ip6, + delete_route: DeleteFlag, + destination: ?*const Address, + prefix_length: u8, + gateway_address: ?*const Address, + ) RoutesError!void { + switch (self._routes( + self, + delete_route == .delete, + destination, + prefix_length, + gateway_address, + )) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .not_found => return Error.NotFound, + .access_denied => return Error.AccessDenied, + else => |status| return uefi.unexpectedStatus(status), + } } /// Add or delete Neighbor cache entries. - pub fn neighbors(self: *const Ip6, delete_flag: bool, target_ip6_address: *const Address, target_link_address: ?*const MacAddress, timeout: u32, override: bool) Status { - return self._neighbors(self, delete_flag, target_ip6_address, target_link_address, timeout, override); + pub fn neighbors( + self: *Ip6, + delete_flag: DeleteFlag, + target_ip6_address: *const Address, + target_link_address: ?*const MacAddress, + timeout: u32, + override: bool, + ) NeighborsError!void { + switch (self._neighbors( + self, + // set to TRUE to delete this route from the routing table. + // set to FALSE to add this route to the routing table. + delete_flag == .delete, + target_ip6_address, + target_link_address, + timeout, + override, + )) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .not_found => return Error.NotFound, + .access_denied => return Error.AccessDenied, + else => |status| return uefi.unexpectedStatus(status), + } } /// Places outgoing data packets into the transmit queue. - pub fn transmit(self: *const Ip6, token: *CompletionToken) Status { - return self._transmit(self, token); + pub fn transmit(self: *Ip6, token: *CompletionToken) TransmitError!void { + switch (self._transmit(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .no_mapping => return Error.NoMapping, + .invalid_parameter => return Error.InvalidParameter, + .access_denied => return Error.AccessDenied, + .not_ready => return Error.NotReady, + .not_found => return Error.NotFound, + .out_of_resources => return Error.OutOfResources, + .buffer_too_small => return Error.BufferTooSmall, + .bad_buffer_size => return Error.BadBufferSize, + .device_error => return Error.DeviceError, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } /// Places a receiving request into the receiving queue. - pub fn receive(self: *const Ip6, token: *CompletionToken) Status { - return self._receive(self, token); + pub fn receive(self: *Ip6, token: *CompletionToken) ReceiveError!void { + switch (self._receive(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .no_mapping => return Error.NoMapping, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .device_error => return Error.DeviceError, + .access_denied => return Error.AccessDenied, + .not_ready => return Error.NotReady, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } /// Abort an asynchronous transmits or receive request. - pub fn cancel(self: *const Ip6, token: ?*CompletionToken) Status { - return self._cancel(self, token); + pub fn cancel(self: *Ip6, token: ?*CompletionToken) CancelError!void { + switch (self._cancel(self, token)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .not_started => return Error.NotStarted, + .not_found => return Error.NotFound, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Polls for incoming data packets and processes outgoing data packets. - pub fn poll(self: *const Ip6) Status { - return self._poll(self); + /// + /// Returns true if a packet was received or processed. + pub fn poll(self: *Ip6) PollError!bool { + switch (self._poll(self)) { + .success => return true, + .not_ready => return false, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .timeout => return Error.Timeout, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ @@ -73,6 +302,16 @@ pub const Ip6 = extern struct { .node = [_]u8{ 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 }, }; + pub const DeleteFlag = enum { + delete, + add, + }; + + pub const JoinFlag = enum { + join, + leave, + }; + pub const Mode = extern struct { is_started: bool, max_packet_size: u32, diff --git a/lib/std/os/uefi/protocol/ip6_config.zig b/lib/std/os/uefi/protocol/ip6_config.zig index ddf1d02887..bb660a3b8e 100644 --- a/lib/std/os/uefi/protocol/ip6_config.zig +++ b/lib/std/os/uefi/protocol/ip6_config.zig @@ -4,6 +4,9 @@ const Guid = uefi.Guid; const Event = uefi.Event; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; +const MacAddress = uefi.MacAddress; +const Ip6 = uefi.protocol.Ip6; pub const Ip6Config = extern struct { _set_data: *const fn (*const Ip6Config, DataType, usize, *const anyopaque) callconv(cc) Status, @@ -11,20 +14,98 @@ pub const Ip6Config = extern struct { _register_data_notify: *const fn (*const Ip6Config, DataType, Event) callconv(cc) Status, _unregister_data_notify: *const fn (*const Ip6Config, DataType, Event) callconv(cc) Status, - pub fn setData(self: *const Ip6Config, data_type: DataType, data_size: usize, data: *const anyopaque) Status { - return self._set_data(self, data_type, data_size, data); + pub const SetDataError = uefi.UnexpectedError || error{ + InvalidParameter, + WriteProtected, + AccessDenied, + NotReady, + BadBufferSize, + Unsupported, + OutOfResources, + DeviceError, + }; + pub const GetDataError = uefi.UnexpectedError || error{ + InvalidParameter, + BufferTooSmall, + NotReady, + NotFound, + }; + pub const RegisterDataNotifyError = uefi.UnexpectedError || error{ + InvalidParameter, + Unsupported, + OutOfResources, + AccessDenied, + }; + pub const UnregisterDataNotifyError = uefi.UnexpectedError || error{ + InvalidParameter, + NotFound, + }; + + pub fn setData( + self: *const Ip6Config, + comptime data_type: std.meta.Tag(DataType), + payload: *const std.meta.TagPayload(DataType, data_type), + ) SetDataError!void { + const data_size = @sizeOf(@TypeOf(payload)); + switch (self._set_data(self, data_type, data_size, @ptrCast(payload))) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .write_protected => return Error.WriteProtected, + .access_denied => return Error.AccessDenied, + .not_ready => return Error.NotReady, + .bad_buffer_size => return Error.BadBufferSize, + .unsupported => return Error.Unsupported, + .out_of_resources => return Error.OutOfResources, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn getData(self: *const Ip6Config, data_type: DataType, data_size: *usize, data: ?*const anyopaque) Status { - return self._get_data(self, data_type, data_size, data); + pub fn getData( + self: *const Ip6Config, + comptime data_type: std.meta.Tag(DataType), + ) GetDataError!std.meta.TagPayload(DataType, data_type) { + const DataPayload = std.meta.TagPayload(DataType, data_type); + + var payload: DataPayload = undefined; + var payload_size: usize = @sizeOf(DataPayload); + + switch (self._get_data(self, data_type, &payload_size, @ptrCast(&payload))) { + .success => return payload, + .invalid_parameter => return Error.InvalidParameter, + .buffer_too_small => return Error.BufferTooSmall, + .not_ready => return Error.NotReady, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn registerDataNotify(self: *const Ip6Config, data_type: DataType, event: Event) Status { - return self._register_data_notify(self, data_type, event); + pub fn registerDataNotify( + self: *const Ip6Config, + data_type: DataType, + event: Event, + ) RegisterDataNotifyError!void { + switch (self._register_data_notify(self, data_type, event)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .unsupported => return Error.Unsupported, + .out_of_resources => return Error.OutOfResources, + .access_denied => return Error.AccessDenied, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn unregisterDataNotify(self: *const Ip6Config, data_type: DataType, event: Event) Status { - return self._unregister_data_notify(self, data_type, event); + pub fn unregisterDataNotify( + self: *const Ip6Config, + data_type: DataType, + event: Event, + ) UnregisterDataNotifyError!void { + switch (self._unregister_data_notify(self, data_type, event)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ @@ -36,13 +117,43 @@ pub const Ip6Config = extern struct { .node = [_]u8{ 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a }, }; - pub const DataType = enum(u32) { - interface_info, - alt_interface_id, - policy, - dup_addr_detect_transmits, - manual_address, - gateway, - dns_server, + pub const DataType = union(enum(u32)) { + interface_info: InterfaceInfo, + alt_interface_id: InterfaceId, + policy: Policy, + dup_addr_detect_transmits: DupAddrDetectTransmits, + manual_address: [*]ManualAddress, + gateway: [*]Ip6.Address, + dns_server: [*]Ip6.Address, + }; + + pub const InterfaceInfo = extern struct { + name: [32]u16, + if_type: u8, + hw_address_size: u32, + hw_address: MacAddress, + address_info_count: u32, + address_info: [*]Ip6.AddressInfo, + route_count: u32, + route_table: Ip6.RouteTable, + }; + + pub const InterfaceId = extern struct { + id: [8]u8, + }; + + pub const Policy = enum(u32) { + manual, + automatic, + }; + + pub const DupAddrDetectTransmits = extern struct { + dup_addr_detect_transmits: u32, + }; + + pub const ManualAddress = extern struct { + address: Ip6.Address, + is_anycast: bool, + prefix_length: u8, }; }; diff --git a/lib/std/os/uefi/protocol/ip6_service_binding.zig b/lib/std/os/uefi/protocol/ip6_service_binding.zig deleted file mode 100644 index 6fb035eae0..0000000000 --- a/lib/std/os/uefi/protocol/ip6_service_binding.zig +++ /dev/null @@ -1,28 +0,0 @@ -const std = @import("std"); -const uefi = std.os.uefi; -const Handle = uefi.Handle; -const Guid = uefi.Guid; -const Status = uefi.Status; -const cc = uefi.cc; - -pub const Ip6ServiceBinding = extern struct { - _create_child: *const fn (*const Ip6ServiceBinding, *?Handle) callconv(cc) Status, - _destroy_child: *const fn (*const Ip6ServiceBinding, Handle) callconv(cc) Status, - - pub fn createChild(self: *const Ip6ServiceBinding, handle: *?Handle) Status { - return self._create_child(self, handle); - } - - pub fn destroyChild(self: *const Ip6ServiceBinding, handle: Handle) Status { - return self._destroy_child(self, handle); - } - - pub const guid align(8) = Guid{ - .time_low = 0xec835dd3, - .time_mid = 0xfe0f, - .time_high_and_version = 0x617b, - .clock_seq_high_and_reserved = 0xa6, - .clock_seq_low = 0x21, - .node = [_]u8{ 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 }, - }; -}; diff --git a/lib/std/os/uefi/protocol/loaded_image.zig b/lib/std/os/uefi/protocol/loaded_image.zig index 319efd90f9..f539bac537 100644 --- a/lib/std/os/uefi/protocol/loaded_image.zig +++ b/lib/std/os/uefi/protocol/loaded_image.zig @@ -7,6 +7,7 @@ const SystemTable = uefi.tables.SystemTable; const MemoryType = uefi.tables.MemoryType; const DevicePath = uefi.protocol.DevicePath; const cc = uefi.cc; +const Error = Status.Error; pub const LoadedImage = extern struct { revision: u32, @@ -21,11 +22,17 @@ pub const LoadedImage = extern struct { image_size: u64, image_code_type: MemoryType, image_data_type: MemoryType, - _unload: *const fn (*const LoadedImage, Handle) callconv(cc) Status, + _unload: *const fn (*LoadedImage, Handle) callconv(cc) Status, + + pub const UnloadError = uefi.UnexpectedError || error{InvalidParameter}; /// Unloads an image from memory. - pub fn unload(self: *const LoadedImage, handle: Handle) Status { - return self._unload(self, handle); + pub fn unload(self: *LoadedImage, handle: Handle) UnloadError!void { + switch (self._unload(self, handle)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/managed_network.zig b/lib/std/os/uefi/protocol/managed_network.zig index 9ea5951660..f9e484be08 100644 --- a/lib/std/os/uefi/protocol/managed_network.zig +++ b/lib/std/os/uefi/protocol/managed_network.zig @@ -8,58 +8,186 @@ const Time = uefi.Time; const SimpleNetwork = uefi.protocol.SimpleNetwork; const MacAddress = uefi.MacAddress; const cc = uefi.cc; +const Error = Status.Error; pub const ManagedNetwork = extern struct { _get_mode_data: *const fn (*const ManagedNetwork, ?*Config, ?*SimpleNetwork) callconv(cc) Status, - _configure: *const fn (*const ManagedNetwork, ?*const Config) callconv(cc) Status, - _mcast_ip_to_mac: *const fn (*const ManagedNetwork, bool, *const anyopaque, *MacAddress) callconv(cc) Status, - _groups: *const fn (*const ManagedNetwork, bool, ?*const MacAddress) callconv(cc) Status, - _transmit: *const fn (*const ManagedNetwork, *const CompletionToken) callconv(cc) Status, - _receive: *const fn (*const ManagedNetwork, *const CompletionToken) callconv(cc) Status, - _cancel: *const fn (*const ManagedNetwork, ?*const CompletionToken) callconv(cc) Status, - _poll: *const fn (*const ManagedNetwork) callconv(cc) Status, + _configure: *const fn (*ManagedNetwork, ?*const Config) callconv(cc) Status, + _mcast_ip_to_mac: *const fn (*ManagedNetwork, bool, *const anyopaque, *MacAddress) callconv(cc) Status, + _groups: *const fn (*ManagedNetwork, bool, ?*const MacAddress) callconv(cc) Status, + _transmit: *const fn (*ManagedNetwork, *CompletionToken) callconv(cc) Status, + _receive: *const fn (*ManagedNetwork, *CompletionToken) callconv(cc) Status, + _cancel: *const fn (*ManagedNetwork, ?*const CompletionToken) callconv(cc) Status, + _poll: *const fn (*ManagedNetwork) callconv(cc) Status, + + pub const GetModeDataError = uefi.UnexpectedError || error{ + InvalidParameter, + Unsupported, + NotStarted, + } || Error; + pub const ConfigureError = uefi.UnexpectedError || error{ + InvalidParameter, + OutOfResources, + Unsupported, + DeviceError, + } || Error; + pub const McastIpToMacError = uefi.UnexpectedError || error{ + InvalidParameter, + NotStarted, + Unsupported, + DeviceError, + } || Error; + pub const GroupsError = uefi.UnexpectedError || error{ + InvalidParameter, + NotStarted, + AlreadyStarted, + NotFound, + DeviceError, + Unsupported, + } || Error; + pub const TransmitError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + AccessDenied, + OutOfResources, + DeviceError, + NotReady, + NoMedia, + }; + pub const ReceiveError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + OutOfResources, + DeviceError, + AccessDenied, + NotReady, + NoMedia, + }; + pub const CancelError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + NotFound, + }; + pub const PollError = uefi.UnexpectedError || error{ + NotStarted, + DeviceError, + NotReady, + Timeout, + }; + + pub const GetModeDataData = struct { + mnp_config: Config, + snp_mode: SimpleNetwork, + }; /// Returns the operational parameters for the current MNP child driver. /// May also support returning the underlying SNP driver mode data. - pub fn getModeData(self: *const ManagedNetwork, mnp_config_data: ?*Config, snp_mode_data: ?*SimpleNetwork) Status { - return self._get_mode_data(self, mnp_config_data, snp_mode_data); + pub fn getModeData(self: *const ManagedNetwork) GetModeDataError!GetModeDataData { + var data: GetModeDataData = undefined; + switch (self._get_mode_data(self, &data.mnp_config, &data.snp_mode)) { + .success => return data, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } } /// Sets or clears the operational parameters for the MNP child driver. - pub fn configure(self: *const ManagedNetwork, mnp_config_data: ?*const Config) Status { - return self._configure(self, mnp_config_data); + pub fn configure(self: *ManagedNetwork, mnp_config_data: ?*const Config) ConfigureError!void { + switch (self._configure(self, mnp_config_data)) { + .success => {}, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } } /// Translates an IP multicast address to a hardware (MAC) multicast address. /// This function may be unsupported in some MNP implementations. - pub fn mcastIpToMac(self: *const ManagedNetwork, ipv6flag: bool, ipaddress: *const anyopaque, mac_address: *MacAddress) Status { - return self._mcast_ip_to_mac(self, ipv6flag, ipaddress, mac_address); + pub fn mcastIpToMac( + self: *ManagedNetwork, + ipv6flag: bool, + ipaddress: *const uefi.IpAddress, + ) McastIpToMacError!MacAddress { + var result: MacAddress = undefined; + switch (self._mcast_ip_to_mac(self, ipv6flag, ipaddress, &result)) { + .success => return result, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } } /// Enables and disables receive filters for multicast address. /// This function may be unsupported in some MNP implementations. - pub fn groups(self: *const ManagedNetwork, join_flag: bool, mac_address: ?*const MacAddress) Status { - return self._groups(self, join_flag, mac_address); + pub fn groups( + self: *ManagedNetwork, + join_flag: bool, + mac_address: ?*const MacAddress, + ) GroupsError!void { + switch (self._groups(self, join_flag, mac_address)) { + .success => {}, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } } /// Places asynchronous outgoing data packets into the transmit queue. - pub fn transmit(self: *const ManagedNetwork, token: *const CompletionToken) Status { - return self._transmit(self, token); + pub fn transmit(self: *ManagedNetwork, token: *CompletionToken) TransmitError!void { + switch (self._transmit(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .access_denied => return Error.AccessDenied, + .out_of_resources => return Error.OutOfResources, + .device_error => return Error.DeviceError, + .not_ready => return Error.NotReady, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } /// Places an asynchronous receiving request into the receiving queue. - pub fn receive(self: *const ManagedNetwork, token: *const CompletionToken) Status { - return self._receive(self, token); + pub fn receive(self: *ManagedNetwork, token: *CompletionToken) TransmitError!void { + switch (self._receive(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .device_error => return Error.DeviceError, + .access_denied => return Error.AccessDenied, + .not_ready => return Error.NotReady, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } /// Aborts an asynchronous transmit or receive request. - pub fn cancel(self: *const ManagedNetwork, token: ?*const CompletionToken) Status { - return self._cancel(self, token); + pub fn cancel(self: *ManagedNetwork, token: ?*const CompletionToken) CancelError!void { + switch (self._cancel(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } /// Polls for incoming data packets and processes outgoing data packets. - pub fn poll(self: *const ManagedNetwork) Status { - return self._poll(self); + pub fn poll(self: *ManagedNetwork) PollError!void { + switch (self._poll(self)) { + .success => {}, + .not_started => return Error.NotStarted, + .device_error => return Error.DeviceError, + .not_ready => return Error.NotReady, + .timeout => return Error.Timeout, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/rng.zig b/lib/std/os/uefi/protocol/rng.zig index 3d914e7a9e..4cc3edee64 100644 --- a/lib/std/os/uefi/protocol/rng.zig +++ b/lib/std/os/uefi/protocol/rng.zig @@ -3,20 +3,47 @@ const uefi = std.os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// Random Number Generator protocol pub const Rng = extern struct { _get_info: *const fn (*const Rng, *usize, [*]align(8) Guid) callconv(cc) Status, _get_rng: *const fn (*const Rng, ?*align(8) const Guid, usize, [*]u8) callconv(cc) Status, + pub const GetInfoError = uefi.UnexpectedError || error{ + Unsupported, + DeviceError, + BufferTooSmall, + }; + pub const GetRNGError = uefi.UnexpectedError || error{ + Unsupported, + DeviceError, + NotReady, + InvalidParameter, + }; + /// Returns information about the random number generation implementation. - pub fn getInfo(self: *const Rng, list_size: *usize, list: [*]align(8) Guid) Status { - return self._get_info(self, list_size, list); + pub fn getInfo(self: *const Rng, list: []align(8) Guid) GetInfoError![]align(8) Guid { + var len: usize = list.len; + switch (self._get_info(self, &len, list.ptr)) { + .success => return list[0..len], + .unsupported => return Error.Unsupported, + .device_error => return Error.DeviceError, + .buffer_too_small => return Error.BufferTooSmall, + else => |status| return uefi.unexpectedStatus(status), + } } /// Produces and returns an RNG value using either the default or specified RNG algorithm. - pub fn getRNG(self: *const Rng, algo: ?*align(8) const Guid, value_length: usize, value: [*]u8) Status { - return self._get_rng(self, algo, value_length, value); + pub fn getRNG(self: *const Rng, algo: ?*align(8) const Guid, value: []u8) GetRNGError!void { + switch (self._get_rng(self, algo, value.len, value.ptr)) { + .success => {}, + .unsupported => return Error.Unsupported, + .device_error => return Error.DeviceError, + .not_ready => return Error.NotReady, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/serial_io.zig b/lib/std/os/uefi/protocol/serial_io.zig index 3df3687db5..83210d2e5f 100644 --- a/lib/std/os/uefi/protocol/serial_io.zig +++ b/lib/std/os/uefi/protocol/serial_io.zig @@ -3,46 +3,113 @@ const uefi = std.os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; pub const SerialIo = extern struct { revision: u64, - _reset: *const fn (*const SerialIo) callconv(cc) Status, - _set_attribute: *const fn (*const SerialIo, u64, u32, u32, ParityType, u8, StopBitsType) callconv(cc) Status, - _set_control: *const fn (*const SerialIo, u32) callconv(cc) Status, + _reset: *const fn (*SerialIo) callconv(cc) Status, + _set_attribute: *const fn (*SerialIo, u64, u32, u32, ParityType, u8, StopBitsType) callconv(cc) Status, + _set_control: *const fn (*SerialIo, u32) callconv(cc) Status, _get_control: *const fn (*const SerialIo, *u32) callconv(cc) Status, - _write: *const fn (*const SerialIo, *usize, *anyopaque) callconv(cc) Status, - _read: *const fn (*const SerialIo, *usize, *anyopaque) callconv(cc) Status, + _write: *const fn (*SerialIo, *usize, *const anyopaque) callconv(cc) Status, + _read: *const fn (*SerialIo, *usize, *anyopaque) callconv(cc) Status, mode: *Mode, device_type_guid: ?*Guid, + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const SetAttributeError = uefi.UnexpectedError || error{ + InvalidParameter, + DeviceError, + }; + pub const SetControlError = uefi.UnexpectedError || error{ + Unsupported, + DeviceError, + }; + pub const GetControlError = uefi.UnexpectedError || error{DeviceError}; + pub const WriteError = uefi.UnexpectedError || error{ + DeviceError, + Timeout, + }; + pub const ReadError = uefi.UnexpectedError || error{ + DeviceError, + Timeout, + }; + /// Resets the serial device. - pub fn reset(self: *const SerialIo) Status { - return self._reset(self); + pub fn reset(self: *SerialIo) ResetError!void { + switch (self._reset(self)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Sets the baud rate, receive FIFO depth, transmit/receive time out, parity, data bits, and stop bits on a serial device. - pub fn setAttribute(self: *const SerialIo, baud_rate: u64, receiver_fifo_depth: u32, timeout: u32, parity: ParityType, data_bits: u8, stop_bits: StopBitsType) Status { - return self._set_attribute(self, baud_rate, receiver_fifo_depth, timeout, parity, data_bits, stop_bits); + pub fn setAttribute( + self: *SerialIo, + baud_rate: u64, + receiver_fifo_depth: u32, + timeout: u32, + parity: ParityType, + data_bits: u8, + stop_bits: StopBitsType, + ) SetAttributeError!void { + switch (self._set_attribute( + self, + baud_rate, + receiver_fifo_depth, + timeout, + parity, + data_bits, + stop_bits, + )) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Sets the control bits on a serial device. - pub fn setControl(self: *const SerialIo, control: u32) Status { - return self._set_control(self, control); + pub fn setControl(self: *SerialIo, control: u32) SetControlError!void { + switch (self._set_control(self, control)) { + .success => {}, + .unsupported => return Error.Unsupported, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Retrieves the status of the control bits on a serial device. - pub fn getControl(self: *const SerialIo, control: *u32) Status { - return self._get_control(self, control); + pub fn getControl(self: *SerialIo) GetControlError!u32 { + var control: u32 = undefined; + switch (self._get_control(self, &control)) { + .success => return control, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Writes data to a serial device. - pub fn write(self: *const SerialIo, buffer_size: *usize, buffer: *anyopaque) Status { - return self._write(self, buffer_size, buffer); + pub fn write(self: *SerialIo, buffer: []const u8) WriteError!usize { + var len: usize = buffer.len; + switch (self._write(self, &len, buffer.ptr)) { + .success => return len, + .device_error => return Error.DeviceError, + .timeout => return Error.Timeout, + else => |status| return uefi.unexpectedStatus(status), + } } /// Reads data from a serial device. - pub fn read(self: *const SerialIo, buffer_size: *usize, buffer: *anyopaque) Status { - return self._read(self, buffer_size, buffer); + pub fn read(self: *SerialIo, buffer: []u8) ReadError!usize { + var len: usize = buffer.len; + switch (self._read(self, &len, buffer.ptr)) { + .success => return len, + .device_error => return Error.DeviceError, + .timeout => return Error.Timeout, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/service_binding.zig b/lib/std/os/uefi/protocol/service_binding.zig new file mode 100644 index 0000000000..06cc64001e --- /dev/null +++ b/lib/std/os/uefi/protocol/service_binding.zig @@ -0,0 +1,60 @@ +const std = @import("std"); +const uefi = std.uefi; +const Guid = uefi.Guid; +const Handle = uefi.Handle; +const Status = uefi.Status; +const Error = Status.Error; +const cc = uefi.cc; + +pub fn ServiceBinding(service_guid: Guid) type { + return struct { + const Self = @This(); + + _create_child: *const fn (*Self, *?Handle) callconv(cc) Status, + _destroy_child: *const fn (*Self, Handle) callconv(cc) Status, + + pub const CreateChildError = uefi.UnexpectedError || error{ + InvalidParameter, + OutOfResources, + } || Error; + pub const DestroyChildError = uefi.UnexpectedError || error{ + Unsupported, + InvalidParameter, + AccessDenied, + } || Error; + + /// To add this protocol to an existing handle, use `addToHandle` instead. + pub fn createChild(self: *Self) CreateChildError!Handle { + var handle: ?Handle = null; + switch (self._create_child(self, &handle)) { + .success => return handle orelse error.Unexpected, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } + } + + pub fn addToHandle(self: *Self, handle: Handle) CreateChildError!void { + switch (self._create_child(self, @ptrCast(@constCast(&handle)))) { + .success => {}, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } + } + + pub fn destroyChild(self: *Self, handle: Handle) DestroyChildError!void { + switch (self._destroy_child(self, handle)) { + .success => {}, + else => |status| { + try status.err(); + return uefi.unexpectedStatus(status); + }, + } + } + + pub const guid align(8) = service_guid; + }; +} diff --git a/lib/std/os/uefi/protocol/simple_file_system.zig b/lib/std/os/uefi/protocol/simple_file_system.zig index bdd0d1d909..23118e1710 100644 --- a/lib/std/os/uefi/protocol/simple_file_system.zig +++ b/lib/std/os/uefi/protocol/simple_file_system.zig @@ -1,16 +1,38 @@ const std = @import("std"); const uefi = std.os.uefi; const Guid = uefi.Guid; -const FileProtocol = uefi.protocol.File; +const File = uefi.protocol.File; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; pub const SimpleFileSystem = extern struct { revision: u64, - _open_volume: *const fn (*const SimpleFileSystem, **const FileProtocol) callconv(cc) Status, + _open_volume: *const fn (*const SimpleFileSystem, **File) callconv(cc) Status, - pub fn openVolume(self: *const SimpleFileSystem, root: **const FileProtocol) Status { - return self._open_volume(self, root); + pub const OpenVolumeError = uefi.UnexpectedError || error{ + Unsupported, + NoMedia, + DeviceError, + VolumeCorrupted, + AccessDenied, + OutOfResources, + MediaChanged, + }; + + pub fn openVolume(self: *const SimpleFileSystem) OpenVolumeError!*File { + var root: *File = undefined; + switch (self._open_volume(self, &root)) { + .success => return root, + .unsupported => return Error.Unsupported, + .no_media => return Error.NoMedia, + .device_error => return Error.DeviceError, + .volume_corrupted => return Error.VolumeCorrupted, + .access_denied => return Error.AccessDenied, + .out_of_resources => return Error.OutOfResources, + .media_changed => return Error.MediaChanged, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/simple_network.zig b/lib/std/os/uefi/protocol/simple_network.zig index e126576966..1a151865fa 100644 --- a/lib/std/os/uefi/protocol/simple_network.zig +++ b/lib/std/os/uefi/protocol/simple_network.zig @@ -4,88 +4,349 @@ const Event = uefi.Event; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; pub const SimpleNetwork = extern struct { revision: u64, - _start: *const fn (*const SimpleNetwork) callconv(cc) Status, - _stop: *const fn (*const SimpleNetwork) callconv(cc) Status, - _initialize: *const fn (*const SimpleNetwork, usize, usize) callconv(cc) Status, - _reset: *const fn (*const SimpleNetwork, bool) callconv(cc) Status, - _shutdown: *const fn (*const SimpleNetwork) callconv(cc) Status, - _receive_filters: *const fn (*const SimpleNetwork, ReceiveFilter, ReceiveFilter, bool, usize, ?[*]const MacAddress) callconv(cc) Status, - _station_address: *const fn (*const SimpleNetwork, bool, ?*const MacAddress) callconv(cc) Status, + _start: *const fn (*SimpleNetwork) callconv(cc) Status, + _stop: *const fn (*SimpleNetwork) callconv(cc) Status, + _initialize: *const fn (*SimpleNetwork, usize, usize) callconv(cc) Status, + _reset: *const fn (*SimpleNetwork, bool) callconv(cc) Status, + _shutdown: *const fn (*SimpleNetwork) callconv(cc) Status, + _receive_filters: *const fn (*SimpleNetwork, ReceiveFilter, ReceiveFilter, bool, usize, ?[*]const MacAddress) callconv(cc) Status, + _station_address: *const fn (*SimpleNetwork, bool, ?*const MacAddress) callconv(cc) Status, _statistics: *const fn (*const SimpleNetwork, bool, ?*usize, ?*Statistics) callconv(cc) Status, - _mcast_ip_to_mac: *const fn (*const SimpleNetwork, bool, *const anyopaque, *MacAddress) callconv(cc) Status, - _nvdata: *const fn (*const SimpleNetwork, bool, usize, usize, [*]u8) callconv(cc) Status, - _get_status: *const fn (*const SimpleNetwork, *InterruptStatus, ?*?[*]u8) callconv(cc) Status, - _transmit: *const fn (*const SimpleNetwork, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) callconv(cc) Status, - _receive: *const fn (*const SimpleNetwork, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) callconv(cc) Status, + _mcast_ip_to_mac: *const fn (*SimpleNetwork, bool, *const anyopaque, *MacAddress) callconv(cc) Status, + _nvdata: *const fn (*SimpleNetwork, bool, usize, usize, [*]u8) callconv(cc) Status, + _get_status: *const fn (*SimpleNetwork, ?*InterruptStatus, ?*?[*]u8) callconv(cc) Status, + _transmit: *const fn (*SimpleNetwork, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) callconv(cc) Status, + _receive: *const fn (*SimpleNetwork, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) callconv(cc) Status, wait_for_packet: Event, mode: *Mode, + pub const StartError = uefi.UnexpectedError || error{ + AlreadyStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const StopError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const InitializeError = uefi.UnexpectedError || error{ + NotStarted, + OutOfResources, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const ResetError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const ShutdownError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + }; + pub const ReceiveFiltersError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const StationAddressError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const StatisticsError = uefi.UnexpectedError || error{ + NotStarted, + BufferTooSmall, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const McastIpToMacError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const NvDataError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const GetStatusError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + DeviceError, + }; + pub const TransmitError = uefi.UnexpectedError || error{ + NotStarted, + NotReady, + BufferTooSmall, + InvalidParameter, + DeviceError, + Unsupported, + }; + pub const ReceiveError = uefi.UnexpectedError || error{ + NotStarted, + NotReady, + BufferTooSmall, + InvalidParameter, + DeviceError, + }; + /// Changes the state of a network interface from "stopped" to "started". - pub fn start(self: *const SimpleNetwork) Status { - return self._start(self); + pub fn start(self: *SimpleNetwork) StartError!void { + switch (self._start(self)) { + .success => {}, + .already_started => return Error.AlreadyStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Changes the state of a network interface from "started" to "stopped". - pub fn stop(self: *const SimpleNetwork) Status { - return self._stop(self); + pub fn stop(self: *SimpleNetwork) StopError!void { + switch (self._stop(self)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Resets a network adapter and allocates the transmit and receive buffers required by the network interface. - pub fn initialize(self: *const SimpleNetwork, extra_rx_buffer_size: usize, extra_tx_buffer_size: usize) Status { - return self._initialize(self, extra_rx_buffer_size, extra_tx_buffer_size); + pub fn initialize( + self: *SimpleNetwork, + extra_rx_buffer_size: usize, + extra_tx_buffer_size: usize, + ) InitializeError!void { + switch (self._initialize(self, extra_rx_buffer_size, extra_tx_buffer_size)) { + .success => {}, + .not_started => return Error.NotStarted, + .out_of_resources => return Error.OutOfResources, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Resets a network adapter and reinitializes it with the parameters that were provided in the previous call to initialize(). - pub fn reset(self: *const SimpleNetwork, extended_verification: bool) Status { - return self._reset(self, extended_verification); + pub fn reset(self: *SimpleNetwork, extended_verification: bool) ResetError!void { + switch (self._reset(self, extended_verification)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Resets a network adapter and leaves it in a state that is safe for another driver to initialize. - pub fn shutdown(self: *const SimpleNetwork) Status { - return self._shutdown(self); + pub fn shutdown(self: *SimpleNetwork) ShutdownError!void { + switch (self._shutdown(self)) { + .success => {}, + .not_started => return ShutdownError.NotStarted, + .invalid_parameter => return ShutdownError.InvalidParameter, + .device_error => return ShutdownError.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Manages the multicast receive filters of a network interface. - pub fn receiveFilters(self: *const SimpleNetwork, enable: ReceiveFilter, disable: ReceiveFilter, reset_mcast_filter: bool, mcast_filter_cnt: usize, mcast_filter: ?[*]const MacAddress) Status { - return self._receive_filters(self, enable, disable, reset_mcast_filter, mcast_filter_cnt, mcast_filter); + pub fn receiveFilters( + self: *SimpleNetwork, + enable: ReceiveFilter, + disable: ReceiveFilter, + reset_mcast_filter: bool, + mcast_filter: ?[]const MacAddress, + ) ReceiveFiltersError!void { + const count: usize, const ptr: ?[*]const MacAddress = + if (mcast_filter) |f| + .{ f.len, f.ptr } + else + .{ 0, null }; + + switch (self._receive_filters(self, enable, disable, reset_mcast_filter, count, ptr)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Modifies or resets the current station address, if supported. - pub fn stationAddress(self: *const SimpleNetwork, reset_flag: bool, new: ?*const MacAddress) Status { - return self._station_address(self, reset_flag, new); + pub fn stationAddress( + self: *SimpleNetwork, + reset_flag: bool, + new: ?*const MacAddress, + ) StationAddressError!void { + switch (self._station_address(self, reset_flag, new)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } + } + + pub fn resetStatistics(self: *SimpleNetwork) StatisticsError!void { + switch (self._statistics(self, true, null, null)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Resets or collects the statistics on a network interface. - pub fn statistics(self: *const SimpleNetwork, reset_flag: bool, statistics_size: ?*usize, statistics_table: ?*Statistics) Status { - return self._statistics(self, reset_flag, statistics_size, statistics_table); + pub fn statistics(self: *SimpleNetwork, reset_flag: bool) StatisticsError!Statistics { + var stats: Statistics = undefined; + var stats_size: usize = @sizeOf(Statistics); + switch (self._statistics(self, reset_flag, &stats_size, &stats)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } + + if (stats_size != @sizeOf(Statistics)) + return error.Unexpected + else + return stats; } /// Converts a multicast IP address to a multicast HW MAC address. - pub fn mcastIpToMac(self: *const SimpleNetwork, ipv6: bool, ip: *const anyopaque, mac: *MacAddress) Status { - return self._mcast_ip_to_mac(self, ipv6, ip, mac); + pub fn mcastIpToMac( + self: *SimpleNetwork, + ipv6: bool, + ip: *const anyopaque, + ) McastIpToMacError!MacAddress { + var mac: MacAddress = undefined; + switch (self._mcast_ip_to_mac(self, ipv6, ip, &mac)) { + .success => return mac, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Performs read and write operations on the NVRAM device attached to a network interface. - pub fn nvdata(self: *const SimpleNetwork, read_write: bool, offset: usize, buffer_size: usize, buffer: [*]u8) Status { - return self._nvdata(self, read_write, offset, buffer_size, buffer); + pub fn nvData( + self: *SimpleNetwork, + read_write: NvDataOperation, + offset: usize, + buffer: []u8, + ) NvDataError!void { + switch (self._nvdata( + self, + // if ReadWrite is TRUE, a read operation is performed + read_write == .read, + offset, + buffer.len, + buffer.ptr, + )) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Reads the current interrupt status and recycled transmit buffer status from a network interface. - pub fn getStatus(self: *const SimpleNetwork, interrupt_status: *InterruptStatus, tx_buf: ?*?[*]u8) Status { - return self._get_status(self, interrupt_status, tx_buf); + pub fn getStatus( + self: *SimpleNetwork, + interrupt_status: ?*InterruptStatus, + recycled_tx_buf: ?*?[*]u8, + ) GetStatusError!void { + switch (self._get_status(self, interrupt_status, recycled_tx_buf)) { + .success => {}, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Places a packet in the transmit queue of a network interface. - pub fn transmit(self: *const SimpleNetwork, header_size: usize, buffer_size: usize, buffer: [*]const u8, src_addr: ?*const MacAddress, dest_addr: ?*const MacAddress, protocol: ?*const u16) Status { - return self._transmit(self, header_size, buffer_size, buffer, src_addr, dest_addr, protocol); + pub fn transmit( + self: *SimpleNetwork, + header_size: usize, + buffer: []const u8, + src_addr: ?*const MacAddress, + dest_addr: ?*const MacAddress, + protocol: ?*const u16, + ) TransmitError!void { + switch (self._transmit( + self, + header_size, + buffer.len, + buffer.ptr, + src_addr, + dest_addr, + protocol, + )) { + .success => {}, + .not_started => return Error.NotStarted, + .not_ready => return Error.NotReady, + .buffer_too_small => return Error.BufferTooSmall, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Receives a packet from a network interface. - pub fn receive(self: *const SimpleNetwork, header_size: ?*usize, buffer_size: *usize, buffer: [*]u8, src_addr: ?*MacAddress, dest_addr: ?*MacAddress, protocol: ?*u16) Status { - return self._receive(self, header_size, buffer_size, buffer, src_addr, dest_addr, protocol); + pub fn receive(self: *SimpleNetwork, buffer: []u8) ReceiveError!Packet { + var packet: Packet = undefined; + packet.buffer = buffer; + + switch (self._receive( + self, + &packet.header_size, + &packet.buffer.len, + packet.buffer.ptr, + &packet.src_addr, + &packet.dst_addr, + &packet.protocol, + )) { + .success => return packet, + .not_started => return Error.NotStarted, + .not_ready => return Error.NotReady, + .buffer_too_small => return Error.BufferTooSmall, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ @@ -97,6 +358,11 @@ pub const SimpleNetwork = extern struct { .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d }, }; + pub const NvDataOperation = enum { + read, + write, + }; + pub const MacAddress = [32]u8; pub const Mode = extern struct { @@ -172,4 +438,12 @@ pub const SimpleNetwork = extern struct { software_interrupt: bool, _pad: u28 = 0, }; + + pub const Packet = struct { + header_size: usize, + buffer: []u8, + src_addr: MacAddress, + dst_addr: MacAddress, + protocol: u16, + }; }; diff --git a/lib/std/os/uefi/protocol/simple_pointer.zig b/lib/std/os/uefi/protocol/simple_pointer.zig index ab7d1abc58..ea160b2b18 100644 --- a/lib/std/os/uefi/protocol/simple_pointer.zig +++ b/lib/std/os/uefi/protocol/simple_pointer.zig @@ -4,22 +4,39 @@ const Event = uefi.Event; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// Protocol for mice. pub const SimplePointer = struct { - _reset: *const fn (*const SimplePointer, bool) callconv(cc) Status, + _reset: *const fn (*SimplePointer, bool) callconv(cc) Status, _get_state: *const fn (*const SimplePointer, *State) callconv(cc) Status, wait_for_input: Event, mode: *Mode, + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const GetStateError = uefi.UnexpectedError || error{ + NotReady, + DeviceError, + }; + /// Resets the pointer device hardware. - pub fn reset(self: *const SimplePointer, verify: bool) Status { - return self._reset(self, verify); + pub fn reset(self: *SimplePointer, verify: bool) ResetError!void { + switch (self._reset(self, verify)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Retrieves the current state of a pointer device. - pub fn getState(self: *const SimplePointer, state: *State) Status { - return self._get_state(self, state); + pub fn getState(self: *const SimplePointer) GetStateError!State { + var state: State = undefined; + switch (self._get_state(self, &state)) { + .success => return state, + .not_ready => return Error.NotReady, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/simple_text_input.zig b/lib/std/os/uefi/protocol/simple_text_input.zig index e6091b93b7..a39e312b68 100644 --- a/lib/std/os/uefi/protocol/simple_text_input.zig +++ b/lib/std/os/uefi/protocol/simple_text_input.zig @@ -4,21 +4,40 @@ const Event = uefi.Event; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// Character input devices, e.g. Keyboard pub const SimpleTextInput = extern struct { - _reset: *const fn (*const SimpleTextInput, bool) callconv(cc) Status, - _read_key_stroke: *const fn (*const SimpleTextInput, *Key.Input) callconv(cc) Status, + _reset: *const fn (*SimpleTextInput, bool) callconv(cc) Status, + _read_key_stroke: *const fn (*SimpleTextInput, *Key.Input) callconv(cc) Status, wait_for_key: Event, + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const ReadKeyStrokeError = uefi.UnexpectedError || error{ + NotReady, + DeviceError, + Unsupported, + }; + /// Resets the input device hardware. - pub fn reset(self: *const SimpleTextInput, verify: bool) Status { - return self._reset(self, verify); + pub fn reset(self: *SimpleTextInput, verify: bool) ResetError!void { + switch (self._reset(self, verify)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Reads the next keystroke from the input device. - pub fn readKeyStroke(self: *const SimpleTextInput, input_key: *Key.Input) Status { - return self._read_key_stroke(self, input_key); + pub fn readKeyStroke(self: *SimpleTextInput) ReadKeyStrokeError!Key.Input { + var key: Key.Input = undefined; + switch (self._read_key_stroke(self, &key)) { + .success => return key, + .not_ready => return Error.NotReady, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/simple_text_input_ex.zig b/lib/std/os/uefi/protocol/simple_text_input_ex.zig index 593321e130..9cc4a50844 100644 --- a/lib/std/os/uefi/protocol/simple_text_input_ex.zig +++ b/lib/std/os/uefi/protocol/simple_text_input_ex.zig @@ -4,39 +4,85 @@ const Event = uefi.Event; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// Character input devices, e.g. Keyboard pub const SimpleTextInputEx = extern struct { - _reset: *const fn (*const SimpleTextInputEx, bool) callconv(cc) Status, - _read_key_stroke_ex: *const fn (*const SimpleTextInputEx, *Key) callconv(cc) Status, + _reset: *const fn (*SimpleTextInputEx, bool) callconv(cc) Status, + _read_key_stroke_ex: *const fn (*SimpleTextInputEx, *Key) callconv(cc) Status, wait_for_key_ex: Event, - _set_state: *const fn (*const SimpleTextInputEx, *const u8) callconv(cc) Status, - _register_key_notify: *const fn (*const SimpleTextInputEx, *const Key, *const fn (*const Key) callconv(cc) usize, **anyopaque) callconv(cc) Status, - _unregister_key_notify: *const fn (*const SimpleTextInputEx, *const anyopaque) callconv(cc) Status, + _set_state: *const fn (*SimpleTextInputEx, *const u8) callconv(cc) Status, + _register_key_notify: *const fn (*SimpleTextInputEx, *const Key, *const fn (*const Key) callconv(cc) Status, **anyopaque) callconv(cc) Status, + _unregister_key_notify: *const fn (*SimpleTextInputEx, *const anyopaque) callconv(cc) Status, + + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const ReadKeyStrokeError = uefi.UnexpectedError || error{ + NotReady, + DeviceError, + Unsupported, + }; + pub const SetStateError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const RegisterKeyNotifyError = uefi.UnexpectedError || error{OutOfResources}; + pub const UnregisterKeyNotifyError = uefi.UnexpectedError || error{InvalidParameter}; /// Resets the input device hardware. - pub fn reset(self: *const SimpleTextInputEx, verify: bool) Status { - return self._reset(self, verify); + pub fn reset(self: *SimpleTextInputEx, verify: bool) ResetError!void { + switch (self._reset(self, verify)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Reads the next keystroke from the input device. - pub fn readKeyStrokeEx(self: *const SimpleTextInputEx, key_data: *Key) Status { - return self._read_key_stroke_ex(self, key_data); + pub fn readKeyStroke(self: *SimpleTextInputEx) ReadKeyStrokeError!Key { + var key: Key = undefined; + switch (self._read_key_stroke_ex(self, &key)) { + .success => return key, + .not_ready => return Error.NotReady, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Set certain state for the input device. - pub fn setState(self: *const SimpleTextInputEx, state: *const u8) Status { - return self._set_state(self, state); + pub fn setState(self: *SimpleTextInputEx, state: *const Key.State.Toggle) SetStateError!void { + switch (self._set_state(self, @ptrCast(state))) { + .success => {}, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Register a notification function for a particular keystroke for the input device. - pub fn registerKeyNotify(self: *const SimpleTextInputEx, key_data: *const Key, notify: *const fn (*const Key) callconv(cc) usize, handle: **anyopaque) Status { - return self._register_key_notify(self, key_data, notify, handle); + pub fn registerKeyNotify( + self: *SimpleTextInputEx, + key_data: *const Key, + notify: *const fn (*const Key) callconv(cc) Status, + ) RegisterKeyNotifyError!uefi.Handle { + var handle: uefi.Handle = undefined; + switch (self._register_key_notify(self, key_data, notify, &handle)) { + .success => return handle, + .out_of_resources => return Error.OutOfResources, + else => |status| return uefi.unexpectedStatus(status), + } } /// Remove the notification that was previously registered. - pub fn unregisterKeyNotify(self: *const SimpleTextInputEx, handle: *const anyopaque) Status { - return self._unregister_key_notify(self, handle); + pub fn unregisterKeyNotify( + self: *SimpleTextInputEx, + handle: uefi.Handle, + ) UnregisterKeyNotifyError!void { + switch (self._unregister_key_notify(self, handle)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ diff --git a/lib/std/os/uefi/protocol/simple_text_output.zig b/lib/std/os/uefi/protocol/simple_text_output.zig index 3c46be3d6a..af1ded2303 100644 --- a/lib/std/os/uefi/protocol/simple_text_output.zig +++ b/lib/std/os/uefi/protocol/simple_text_output.zig @@ -3,63 +3,142 @@ const uefi = std.os.uefi; const Guid = uefi.Guid; const Status = uefi.Status; const cc = uefi.cc; +const Error = Status.Error; /// Character output devices pub const SimpleTextOutput = extern struct { - _reset: *const fn (*const SimpleTextOutput, bool) callconv(cc) Status, - _output_string: *const fn (*const SimpleTextOutput, [*:0]const u16) callconv(cc) Status, + _reset: *const fn (*SimpleTextOutput, bool) callconv(cc) Status, + _output_string: *const fn (*SimpleTextOutput, [*:0]const u16) callconv(cc) Status, _test_string: *const fn (*const SimpleTextOutput, [*:0]const u16) callconv(cc) Status, _query_mode: *const fn (*const SimpleTextOutput, usize, *usize, *usize) callconv(cc) Status, - _set_mode: *const fn (*const SimpleTextOutput, usize) callconv(cc) Status, - _set_attribute: *const fn (*const SimpleTextOutput, usize) callconv(cc) Status, - _clear_screen: *const fn (*const SimpleTextOutput) callconv(cc) Status, - _set_cursor_position: *const fn (*const SimpleTextOutput, usize, usize) callconv(cc) Status, - _enable_cursor: *const fn (*const SimpleTextOutput, bool) callconv(cc) Status, + _set_mode: *const fn (*SimpleTextOutput, usize) callconv(cc) Status, + _set_attribute: *const fn (*SimpleTextOutput, usize) callconv(cc) Status, + _clear_screen: *const fn (*SimpleTextOutput) callconv(cc) Status, + _set_cursor_position: *const fn (*SimpleTextOutput, usize, usize) callconv(cc) Status, + _enable_cursor: *const fn (*SimpleTextOutput, bool) callconv(cc) Status, mode: *Mode, + pub const ResetError = uefi.UnexpectedError || error{DeviceError}; + pub const OutputStringError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const QueryModeError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const SetModeError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const SetAttributeError = uefi.UnexpectedError || error{DeviceError}; + pub const ClearScreenError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const SetCursorPositionError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + pub const EnableCursorError = uefi.UnexpectedError || error{ + DeviceError, + Unsupported, + }; + /// Resets the text output device hardware. - pub fn reset(self: *const SimpleTextOutput, verify: bool) Status { - return self._reset(self, verify); + pub fn reset(self: *SimpleTextOutput, verify: bool) ResetError!void { + switch (self._reset(self, verify)) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Writes a string to the output device. - pub fn outputString(self: *const SimpleTextOutput, msg: [*:0]const u16) Status { - return self._output_string(self, msg); + /// + /// Returns `true` if the string was successfully written, `false` if an unknown glyph was encountered. + pub fn outputString(self: *SimpleTextOutput, msg: [*:0]const u16) OutputStringError!bool { + switch (self._output_string(self, msg)) { + .success => return true, + .warn_unknown_glyph => return false, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Verifies that all characters in a string can be output to the target device. - pub fn testString(self: *const SimpleTextOutput, msg: [*:0]const u16) Status { - return self._test_string(self, msg); + pub fn testString(self: *const SimpleTextOutput, msg: [*:0]const u16) uefi.UnexpectedError!bool { + switch (self._test_string(self, msg)) { + .success => return true, + .unsupported => return false, + else => |status| return uefi.unexpectedStatus(status), + } } /// Returns information for an available text mode that the output device(s) supports. - pub fn queryMode(self: *const SimpleTextOutput, mode_number: usize, columns: *usize, rows: *usize) Status { - return self._query_mode(self, mode_number, columns, rows); + pub fn queryMode(self: *const SimpleTextOutput, mode_number: usize) QueryModeError!Geometry { + var geo: Geometry = undefined; + switch (self._query_mode(self, mode_number, &geo.columns, &geo.rows)) { + .success => return geo, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Sets the output device(s) to a specified mode. - pub fn setMode(self: *const SimpleTextOutput, mode_number: usize) Status { - return self._set_mode(self, mode_number); + pub fn setMode(self: *SimpleTextOutput, mode_number: usize) SetModeError!void { + switch (self._set_mode(self, mode_number)) { + .success => {}, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Sets the background and foreground colors for the outputString() and clearScreen() functions. - pub fn setAttribute(self: *const SimpleTextOutput, attribute: usize) Status { - return self._set_attribute(self, attribute); + pub fn setAttribute(self: *SimpleTextOutput, attribute: Attribute) SetAttributeError!void { + const attr_as_num: u8 = @bitCast(attribute); + switch (self._set_attribute(self, @intCast(attr_as_num))) { + .success => {}, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } /// Clears the output device(s) display to the currently selected background color. - pub fn clearScreen(self: *const SimpleTextOutput) Status { - return self._clear_screen(self); + pub fn clearScreen(self: *SimpleTextOutput) ClearScreenError!void { + switch (self._clear_screen(self)) { + .success => {}, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Sets the current coordinates of the cursor position. - pub fn setCursorPosition(self: *const SimpleTextOutput, column: usize, row: usize) Status { - return self._set_cursor_position(self, column, row); + pub fn setCursorPosition( + self: *SimpleTextOutput, + column: usize, + row: usize, + ) SetCursorPositionError!void { + switch (self._set_cursor_position(self, column, row)) { + .success => {}, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } /// Makes the cursor visible or invisible. - pub fn enableCursor(self: *const SimpleTextOutput, visible: bool) Status { - return self._enable_cursor(self, visible); + pub fn enableCursor(self: *SimpleTextOutput, visible: bool) EnableCursorError!void { + switch (self._enable_cursor(self, visible)) { + .success => {}, + .device_error => return Error.DeviceError, + .unsupported => return Error.Unsupported, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = Guid{ @@ -118,31 +197,41 @@ pub const SimpleTextOutput = extern struct { pub const geometricshape_left_triangle: u16 = 0x25c4; pub const arrow_up: u16 = 0x2591; pub const arrow_down: u16 = 0x2593; - pub const black: u8 = 0x00; - pub const blue: u8 = 0x01; - pub const green: u8 = 0x02; - pub const cyan: u8 = 0x03; - pub const red: u8 = 0x04; - pub const magenta: u8 = 0x05; - pub const brown: u8 = 0x06; - pub const lightgray: u8 = 0x07; - pub const bright: u8 = 0x08; - pub const darkgray: u8 = 0x08; - pub const lightblue: u8 = 0x09; - pub const lightgreen: u8 = 0x0a; - pub const lightcyan: u8 = 0x0b; - pub const lightred: u8 = 0x0c; - pub const lightmagenta: u8 = 0x0d; - pub const yellow: u8 = 0x0e; - pub const white: u8 = 0x0f; - pub const background_black: u8 = 0x00; - pub const background_blue: u8 = 0x10; - pub const background_green: u8 = 0x20; - pub const background_cyan: u8 = 0x30; - pub const background_red: u8 = 0x40; - pub const background_magenta: u8 = 0x50; - pub const background_brown: u8 = 0x60; - pub const background_lightgray: u8 = 0x70; + + pub const Attribute = packed struct(u8) { + foreground: ForegroundColor = .white, + background: BackgroundColor = .black, + + pub const ForegroundColor = enum(u4) { + black, + blue, + green, + cyan, + red, + magenta, + brown, + lightgray, + darkgray, + lightblue, + lightgreen, + lightcyan, + lightred, + lightmagenta, + yellow, + white, + }; + + pub const BackgroundColor = enum(u4) { + black, + blue, + green, + cyan, + red, + magenta, + brown, + lightgray, + }; + }; pub const Mode = extern struct { max_mode: u32, // specified as signed @@ -152,4 +241,9 @@ pub const SimpleTextOutput = extern struct { cursor_row: i32, cursor_visible: bool, }; + + pub const Geometry = struct { + columns: usize, + rows: usize, + }; }; diff --git a/lib/std/os/uefi/protocol/udp6.zig b/lib/std/os/uefi/protocol/udp6.zig index b1623d8330..7994fa98b0 100644 --- a/lib/std/os/uefi/protocol/udp6.zig +++ b/lib/std/os/uefi/protocol/udp6.zig @@ -8,6 +8,7 @@ const Ip6 = uefi.protocol.Ip6; const ManagedNetworkConfigData = uefi.protocol.ManagedNetwork.Config; const SimpleNetwork = uefi.protocol.SimpleNetwork; const cc = uefi.cc; +const Error = Status.Error; pub const Udp6 = extern struct { _get_mode_data: *const fn (*const Udp6, ?*Config, ?*Ip6.Mode, ?*ManagedNetworkConfigData, ?*SimpleNetwork) callconv(cc) Status, @@ -18,32 +19,158 @@ pub const Udp6 = extern struct { _cancel: *const fn (*const Udp6, ?*CompletionToken) callconv(cc) Status, _poll: *const fn (*const Udp6) callconv(cc) Status, - pub fn getModeData(self: *const Udp6, udp6_config_data: ?*Config, ip6_mode_data: ?*Ip6.Mode, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetwork) Status { - return self._get_mode_data(self, udp6_config_data, ip6_mode_data, mnp_config_data, snp_mode_data); + pub const GetModeDataError = uefi.UnexpectedError || error{ + NotStarted, + InvalidParameter, + }; + pub const ConfigureError = uefi.UnexpectedError || error{ + NoMapping, + InvalidParameter, + AlreadyStarted, + AccessDenied, + OutOfResources, + DeviceError, + }; + pub const GroupsError = uefi.UnexpectedError || error{ + NotStarted, + OutOfResources, + InvalidParameter, + AlreadyStarted, + NotFound, + DeviceError, + }; + pub const TransmitError = uefi.UnexpectedError || error{ + NotStarted, + NoMapping, + InvalidParameter, + AccessDenied, + NotReady, + OutOfResources, + NotFound, + BadBufferSize, + NoMedia, + }; + pub const ReceiveError = uefi.UnexpectedError || error{ + NotStarted, + NoMapping, + InvalidParameter, + OutOfResources, + DeviceError, + AccessDenied, + NotReady, + NoMedia, + }; + pub const CancelError = uefi.UnexpectedError || error{ + InvalidParameter, + NotStarted, + NotFound, + }; + pub const PollError = uefi.UnexpectedError || error{ + InvalidParameter, + DeviceError, + Timeout, + }; + + pub fn getModeData(self: *const Udp6) GetModeDataError!ModeData { + var data: ModeData = undefined; + switch (self._get_mode_data( + self, + &data.udp6_config_data, + &data.ip6_mode_data, + &data.mnp_config_data, + &data.snp_mode_data, + )) { + .success => return data, + .not_started => return Error.NotStarted, + .invalid_parameter => return Error.InvalidParameter, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn configure(self: *const Udp6, udp6_config_data: ?*const Config) Status { - return self._configure(self, udp6_config_data); + pub fn configure(self: *Udp6, udp6_config_data: ?*const Config) ConfigureError!void { + switch (self._configure(self, udp6_config_data)) { + .success => {}, + .no_mapping => return Error.NoMapping, + .invalid_parameter => return Error.InvalidParameter, + .already_started => return Error.AlreadyStarted, + .access_denied => return Error.AccessDenied, + .out_of_resources => return Error.OutOfResources, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn groups(self: *const Udp6, join_flag: bool, multicast_address: ?*const Ip6.Address) Status { - return self._groups(self, join_flag, multicast_address); + pub fn groups( + self: *Udp6, + join_flag: JoinFlag, + multicast_address: ?*const Ip6.Address, + ) GroupsError!void { + switch (self._groups( + self, + // set to TRUE to join a multicast group + join_flag == .join, + multicast_address, + )) { + .success => {}, + .not_started => return Error.NotStarted, + .out_of_resources => return Error.OutOfResources, + .invalid_parameter => return Error.InvalidParameter, + .already_started => return Error.AlreadyStarted, + .not_found => return Error.NotFound, + .device_error => return Error.DeviceError, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn transmit(self: *const Udp6, token: *CompletionToken) Status { - return self._transmit(self, token); + pub fn transmit(self: *Udp6, token: *CompletionToken) TransmitError!void { + switch (self._transmit(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .no_mapping => return Error.NoMapping, + .invalid_parameter => return Error.InvalidParameter, + .access_denied => return Error.AccessDenied, + .not_ready => return Error.NotReady, + .out_of_resources => return Error.OutOfResources, + .not_found => return Error.NotFound, + .bad_buffer_size => return Error.BadBufferSize, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn receive(self: *const Udp6, token: *CompletionToken) Status { - return self._receive(self, token); + pub fn receive(self: *Udp6, token: *CompletionToken) ReceiveError!void { + switch (self._receive(self, token)) { + .success => {}, + .not_started => return Error.NotStarted, + .no_mapping => return Error.NoMapping, + .invalid_parameter => return Error.InvalidParameter, + .out_of_resources => return Error.OutOfResources, + .device_error => return Error.DeviceError, + .access_denied => return Error.AccessDenied, + .not_ready => return Error.NotReady, + .no_media => return Error.NoMedia, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn cancel(self: *const Udp6, token: ?*CompletionToken) Status { - return self._cancel(self, token); + pub fn cancel(self: *Udp6, token: ?*CompletionToken) CancelError!void { + switch (self._cancel(self, token)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .not_started => return Error.NotStarted, + .not_found => return Error.NotFound, + else => |status| return uefi.unexpectedStatus(status), + } } - pub fn poll(self: *const Udp6) Status { - return self._poll(self); + pub fn poll(self: *Udp6) PollError!void { + switch (self._poll(self)) { + .success => {}, + .invalid_parameter => return Error.InvalidParameter, + .device_error => return Error.DeviceError, + .timeout => return Error.Timeout, + else => |status| return uefi.unexpectedStatus(status), + } } pub const guid align(8) = uefi.Guid{ @@ -55,6 +182,18 @@ pub const Udp6 = extern struct { .node = [_]u8{ 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 }, }; + pub const JoinFlag = enum { + join, + leave, + }; + + pub const ModeData = struct { + udp6_config_data: Config, + ip6_mode_data: Ip6.Mode, + mnp_config_data: ManagedNetworkConfigData, + snp_mode_data: SimpleNetwork, + }; + pub const Config = extern struct { accept_promiscuous: bool, accept_any_port: bool, diff --git a/lib/std/os/uefi/protocol/udp6_service_binding.zig b/lib/std/os/uefi/protocol/udp6_service_binding.zig deleted file mode 100644 index 64e91232b4..0000000000 --- a/lib/std/os/uefi/protocol/udp6_service_binding.zig +++ /dev/null @@ -1,28 +0,0 @@ -const std = @import("std"); -const uefi = std.os.uefi; -const Handle = uefi.Handle; -const Guid = uefi.Guid; -const Status = uefi.Status; -const cc = uefi.cc; - -pub const Udp6ServiceBinding = extern struct { - _create_child: *const fn (*const Udp6ServiceBinding, *?Handle) callconv(cc) Status, - _destroy_child: *const fn (*const Udp6ServiceBinding, Handle) callconv(cc) Status, - - pub fn createChild(self: *const Udp6ServiceBinding, handle: *?Handle) Status { - return self._create_child(self, handle); - } - - pub fn destroyChild(self: *const Udp6ServiceBinding, handle: Handle) Status { - return self._destroy_child(self, handle); - } - - pub const guid align(8) = Guid{ - .time_low = 0x66ed4721, - .time_mid = 0x3c98, - .time_high_and_version = 0x4d3e, - .clock_seq_high_and_reserved = 0x81, - .clock_seq_low = 0xe3, - .node = [_]u8{ 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 }, - }; -};