uefi_raw/protocol/console/
serial.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use crate::{guid, Guid, Status};
use bitflags::bitflags;

bitflags! {
    /// The control bits of a device. These are defined in the [RS-232] standard.
    ///
    /// [RS-232]: https://en.wikipedia.org/wiki/RS-232
    #[repr(transparent)]
    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
    pub struct ControlBits: u32 {
        /// Clear to send
        const CLEAR_TO_SEND = 0x10;
        /// Data set ready
        const DATA_SET_READY = 0x20;
        /// Indicates that a phone line is ringing
        const RING_INDICATE = 0x40;
        /// Indicates the connection is still connected
        const CARRIER_DETECT = 0x80;
        /// The input buffer is empty
        const INPUT_BUFFER_EMPTY = 0x100;
        /// The output buffer is empty
        const OUTPUT_BUFFER_EMPTY = 0x200;

        /// Terminal is ready for communications
        const DATA_TERMINAL_READY = 0x1;
        /// Request the device to send data
        const REQUEST_TO_SEND = 0x2;
        /// Enable hardware loop-back
        const HARDWARE_LOOPBACK_ENABLE = 0x1000;
        /// Enable software loop-back
        const SOFTWARE_LOOPBACK_ENABLE = 0x2000;
        /// Allow the hardware to handle flow control
        const HARDWARE_FLOW_CONTROL_ENABLE = 0x4000;

        /// Bitmask of the control bits that can be set.
        ///
        /// Up to date as of UEFI 2.7 / Serial protocol v1
        const SETTABLE =
            ControlBits::DATA_TERMINAL_READY.bits()
            | ControlBits::REQUEST_TO_SEND.bits()
            | ControlBits::HARDWARE_LOOPBACK_ENABLE.bits()
            | ControlBits::SOFTWARE_LOOPBACK_ENABLE.bits()
            | ControlBits::HARDWARE_FLOW_CONTROL_ENABLE.bits();
    }
}

/// Structure representing the device's current parameters.
///
/// The default values for all UART-like devices is:
/// - 115,200 baud
/// - 1 byte receive FIFO
/// - 1'000'000 microsecond timeout
/// - no parity
/// - 8 data bits
/// - 1 stop bit
///
/// The software is responsible for flow control.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
#[repr(C)]
pub struct SerialIoMode {
    /// Bitmask of the control bits that this device supports.
    pub control_mask: ControlBits,
    /// If applicable, the number of microseconds to wait before assuming an
    /// operation timed out.
    pub timeout: u32,
    /// Device's baud rate, or 0 if unknown.
    pub baud_rate: u64,
    /// Size in character's of the device's buffer.
    pub receive_fifo_depth: u32,
    /// Number of data bits in each character.
    pub data_bits: u32,
    /// If applicable, the parity that is computed or checked for each character.
    pub parity: Parity,
    /// If applicable, the number of stop bits per character.
    pub stop_bits: StopBits,
}

#[derive(Debug)]
#[repr(C)]
pub struct SerialIoProtocol {
    pub revision: u32,
    pub reset: unsafe extern "efiapi" fn(*mut Self) -> Status,
    pub set_attributes: unsafe extern "efiapi" fn(
        *const Self,
        baud_rate: u64,
        receive_fifo_depth: u32,
        timeout: u32,
        parity: Parity,
        data_bits: u8,
        stop_bits_type: StopBits,
    ) -> Status,
    pub set_control_bits: unsafe extern "efiapi" fn(*mut Self, ControlBits) -> Status,
    pub get_control_bits: unsafe extern "efiapi" fn(*const Self, *mut ControlBits) -> Status,
    pub write: unsafe extern "efiapi" fn(*mut Self, *mut usize, *const u8) -> Status,
    pub read: unsafe extern "efiapi" fn(*mut Self, *mut usize, *mut u8) -> Status,
    pub mode: *const SerialIoMode,
}

impl SerialIoProtocol {
    pub const GUID: Guid = guid!("bb25cf6f-f1d4-11d2-9a0c-0090273fc1fd");
    pub const REVISION: u32 = 0x00010000;
    pub const REVISION1P1: u32 = 0x00010001;
}

newtype_enum! {
    /// The parity of the device.
    pub enum Parity: u32 => {
        /// Device default
        DEFAULT = 0,
        /// No parity
        NONE = 1,
        /// Even parity
        EVEN = 2,
        /// Odd parity
        ODD = 3,
        /// Mark parity
        MARK = 4,
        /// Space parity
        SPACE = 5,
    }
}

newtype_enum! {
    /// Number of stop bits per character.
    pub enum StopBits: u32 => {
        /// Device default
        DEFAULT = 0,
        /// 1 stop bit
        ONE = 1,
        /// 1.5 stop bits
        ONE_FIVE = 2,
        /// 2 stop bits
        TWO = 3,
    }
}