master
  1const std = @import("std");
  2const uefi = std.os.uefi;
  3const Guid = uefi.Guid;
  4const Status = uefi.Status;
  5const cc = uefi.cc;
  6const Error = Status.Error;
  7
  8pub const SerialIo = extern struct {
  9    revision: u64,
 10    _reset: *const fn (*SerialIo) callconv(cc) Status,
 11    _set_attribute: *const fn (*SerialIo, u64, u32, u32, ParityType, u8, StopBitsType) callconv(cc) Status,
 12    _set_control: *const fn (*SerialIo, u32) callconv(cc) Status,
 13    _get_control: *const fn (*const SerialIo, *u32) callconv(cc) Status,
 14    _write: *const fn (*SerialIo, *usize, *const anyopaque) callconv(cc) Status,
 15    _read: *const fn (*SerialIo, *usize, *anyopaque) callconv(cc) Status,
 16    mode: *Mode,
 17    device_type_guid: ?*Guid,
 18
 19    pub const ResetError = uefi.UnexpectedError || error{DeviceError};
 20    pub const SetAttributeError = uefi.UnexpectedError || error{
 21        InvalidParameter,
 22        DeviceError,
 23    };
 24    pub const SetControlError = uefi.UnexpectedError || error{
 25        Unsupported,
 26        DeviceError,
 27    };
 28    pub const GetControlError = uefi.UnexpectedError || error{DeviceError};
 29    pub const WriteError = uefi.UnexpectedError || error{
 30        DeviceError,
 31        Timeout,
 32    };
 33    pub const ReadError = uefi.UnexpectedError || error{
 34        DeviceError,
 35        Timeout,
 36    };
 37
 38    /// Resets the serial device.
 39    pub fn reset(self: *SerialIo) ResetError!void {
 40        switch (self._reset(self)) {
 41            .success => {},
 42            .device_error => return Error.DeviceError,
 43            else => |status| return uefi.unexpectedStatus(status),
 44        }
 45    }
 46
 47    /// Sets the baud rate, receive FIFO depth, transmit/receive time out, parity, data bits, and stop bits on a serial device.
 48    pub fn setAttribute(
 49        self: *SerialIo,
 50        baud_rate: u64,
 51        receiver_fifo_depth: u32,
 52        timeout: u32,
 53        parity: ParityType,
 54        data_bits: u8,
 55        stop_bits: StopBitsType,
 56    ) SetAttributeError!void {
 57        switch (self._set_attribute(
 58            self,
 59            baud_rate,
 60            receiver_fifo_depth,
 61            timeout,
 62            parity,
 63            data_bits,
 64            stop_bits,
 65        )) {
 66            .success => {},
 67            .invalid_parameter => return Error.InvalidParameter,
 68            .device_error => return Error.DeviceError,
 69            else => |status| return uefi.unexpectedStatus(status),
 70        }
 71    }
 72
 73    /// Sets the control bits on a serial device.
 74    pub fn setControl(self: *SerialIo, control: u32) SetControlError!void {
 75        switch (self._set_control(self, control)) {
 76            .success => {},
 77            .unsupported => return Error.Unsupported,
 78            .device_error => return Error.DeviceError,
 79            else => |status| return uefi.unexpectedStatus(status),
 80        }
 81    }
 82
 83    /// Retrieves the status of the control bits on a serial device.
 84    pub fn getControl(self: *SerialIo) GetControlError!u32 {
 85        var control: u32 = undefined;
 86        switch (self._get_control(self, &control)) {
 87            .success => return control,
 88            .device_error => return Error.DeviceError,
 89            else => |status| return uefi.unexpectedStatus(status),
 90        }
 91    }
 92
 93    /// Writes data to a serial device.
 94    pub fn write(self: *SerialIo, buffer: []const u8) WriteError!usize {
 95        var len: usize = buffer.len;
 96        switch (self._write(self, &len, buffer.ptr)) {
 97            .success => return len,
 98            .device_error => return Error.DeviceError,
 99            .timeout => return Error.Timeout,
100            else => |status| return uefi.unexpectedStatus(status),
101        }
102    }
103
104    /// Reads data from a serial device.
105    pub fn read(self: *SerialIo, buffer: []u8) ReadError!usize {
106        var len: usize = buffer.len;
107        switch (self._read(self, &len, buffer.ptr)) {
108            .success => return len,
109            .device_error => return Error.DeviceError,
110            .timeout => return Error.Timeout,
111            else => |status| return uefi.unexpectedStatus(status),
112        }
113    }
114
115    pub const guid align(8) = Guid{
116        .time_low = 0xBB25CF6F,
117        .time_mid = 0xF1D4,
118        .time_high_and_version = 0x11D2,
119        .clock_seq_high_and_reserved = 0x9a,
120        .clock_seq_low = 0x0c,
121        .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd },
122    };
123
124    pub const ParityType = enum(u32) {
125        default_parity,
126        no_parity,
127        even_parity,
128        odd_parity,
129        mark_parity,
130        space_parity,
131    };
132
133    pub const StopBitsType = enum(u32) {
134        default_stop_bits,
135        one_stop_bit,
136        one_five_stop_bits,
137        two_stop_bits,
138    };
139
140    pub const Mode = extern struct {
141        control_mask: u32,
142        timeout: u32,
143        baud_rate: u64,
144        receive_fifo_depth: u32,
145        data_bits: u32,
146        parity: u32,
147        stop_bits: u32,
148    };
149};