Commit 2fa7f6e502

Yusuf Bham <ybham6@gmail.com>
2022-04-16 22:38:27
std.os.uefi: Add `BlockIoProtocol`
1 parent 859ae15
Changed files (2)
lib
lib/std/os/uefi/protocols/block_io_protocol.zig
@@ -0,0 +1,80 @@
+const std = @import("std");
+const uefi = std.os.uefi;
+const Status = uefi.Status;
+
+const EfiBlockMedia = extern struct {
+    /// The current media ID. If the media changes, this value is changed.
+    media_id: u32,
+
+    /// `true` if the media is removable; otherwise, `false`.
+    removable_media: bool,
+    /// `true` if there is a media currently present in the device
+    media_present: bool,
+    /// `true` if the `BlockIoProtocol` was produced to abstract
+    /// partition structures on the disk. `false` if the `BlockIoProtocol` was
+    /// produced to abstract the logical blocks on a hardware device.
+    logical_partition: bool,
+    /// `true` if the media is marked read-only otherwise, `false`. This field
+    /// shows the read-only status as of the most recent `WriteBlocks()`
+    read_only: bool,
+    /// `true` if the WriteBlocks() function caches write data.
+    write_caching: bool,
+
+    /// The intrinsic block size of the device. If the media changes, then this
+    // field is updated. Returns the number of bytes per logical block.
+    block_size: u32,
+    /// Supplies the alignment requirement for any buffer used in a data
+    /// transfer. IoAlign values of 0 and 1 mean that the buffer can be
+    /// placed anywhere in memory. Otherwise, IoAlign must be a power of
+    /// 2, and the requirement is that the start address of a buffer must be
+    /// evenly divisible by IoAlign with no remainder.
+    io_align: u32,
+    /// The last LBA on the device. If the media changes, then this field is updated.
+    last_block: u64,
+
+    // Revision 2
+    lowest_aligned_lba: u64,
+    logical_blocks_per_physical_block: u32,
+    optimal_transfer_length_granularity: u32,
+};
+
+const BlockIoProtocol = extern struct {
+    const Self = @This();
+
+    revision: u64,
+    media: *EfiBlockMedia,
+
+    _reset: fn (*BlockIoProtocol, extended_verification: bool) callconv(.C) Status,
+    _read_blocks: fn (*BlockIoProtocol, media_id: u32, lba: u64, buffer_size: usize, buf: [*]u8) callconv(.C) Status,
+    _write_blocks: fn (*BlockIoProtocol, media_id: u32, lba: u64, buffer_size: usize, buf: [*]u8) callconv(.C) Status,
+    _flush_blocks: fn (*BlockIoProtocol) callconv(.C) Status,
+
+    /// Resets the block device hardware.
+    pub fn reset(self: *Self, extended_verification: bool) Status {
+        return self._reset(self, extended_verification);
+    }
+
+    /// 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);
+    }
+
+    /// 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);
+    }
+
+    /// Flushes all modified data to a physical block device.
+    pub fn flushBlocks(self: *Self) Status {
+        return self._flush_blocks(self);
+    }
+
+    pub const guid align(8) = uefi.Guid{
+        .time_low = 0x964e5b21,
+        .time_mid = 0x6459,
+        .time_high_and_version = 0x11d2,
+        .clock_seq_high_and_reserved = 0x8e,
+        .clock_seq_low = 0x39,
+        .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
+    };
+};
lib/std/os/uefi/protocols.zig
@@ -4,9 +4,10 @@ pub usingnamespace @import("protocols/device_path_protocol.zig");
 pub usingnamespace @import("protocols/rng_protocol.zig");
 pub usingnamespace @import("protocols/shell_parameters_protocol.zig");
 
-// Files
+// Files / IO
 pub usingnamespace @import("protocols/simple_file_system_protocol.zig");
 pub usingnamespace @import("protocols/file_protocol.zig");
+pub usingnamespace @import("protocols/block_io_protocol.zig");
 
 // Text
 pub usingnamespace @import("protocols/simple_text_input_protocol.zig");