Skip to main content

uefi_raw/protocol/console/
serial.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use crate::{Guid, Status, guid, newtype_enum};
4use bitflags::bitflags;
5
6bitflags! {
7    /// The control bits of a device. These are defined in the [RS-232] standard.
8    ///
9    /// [RS-232]: https://en.wikipedia.org/wiki/RS-232
10    #[repr(transparent)]
11    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
12    pub struct ControlBits: u32 {
13        /// Clear to send
14        const CLEAR_TO_SEND = 0x10;
15        /// Data set ready
16        const DATA_SET_READY = 0x20;
17        /// Indicates that a phone line is ringing
18        const RING_INDICATE = 0x40;
19        /// Indicates the connection is still connected
20        const CARRIER_DETECT = 0x80;
21        /// The input buffer is empty
22        const INPUT_BUFFER_EMPTY = 0x100;
23        /// The output buffer is empty
24        const OUTPUT_BUFFER_EMPTY = 0x200;
25
26        /// Terminal is ready for communications
27        const DATA_TERMINAL_READY = 0x1;
28        /// Request the device to send data
29        const REQUEST_TO_SEND = 0x2;
30        /// Enable hardware loop-back
31        const HARDWARE_LOOPBACK_ENABLE = 0x1000;
32        /// Enable software loop-back
33        const SOFTWARE_LOOPBACK_ENABLE = 0x2000;
34        /// Allow the hardware to handle flow control
35        const HARDWARE_FLOW_CONTROL_ENABLE = 0x4000;
36
37        /// Bitmask of the control bits that can be set.
38        ///
39        /// Up to date as of UEFI 2.7 / Serial protocol v1
40        const SETTABLE =
41            ControlBits::DATA_TERMINAL_READY.bits()
42            | ControlBits::REQUEST_TO_SEND.bits()
43            | ControlBits::HARDWARE_LOOPBACK_ENABLE.bits()
44            | ControlBits::SOFTWARE_LOOPBACK_ENABLE.bits()
45            | ControlBits::HARDWARE_FLOW_CONTROL_ENABLE.bits();
46    }
47}
48
49/// Structure representing the device's current parameters.
50///
51/// The default values for all UART-like devices is:
52/// - 115,200 baud
53/// - 1 byte receive FIFO
54/// - 1'000'000 microsecond timeout
55/// - no parity
56/// - 8 data bits
57/// - 1 stop bit
58///
59/// The software is responsible for flow control.
60#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
61#[repr(C)]
62pub struct SerialIoMode {
63    /// Bitmask of the control bits that this device supports.
64    pub control_mask: ControlBits,
65    /// If applicable, the number of microseconds to wait before assuming an
66    /// operation timed out.
67    pub timeout: u32,
68    /// Device's baud rate, or 0 if unknown.
69    pub baud_rate: u64,
70    /// Size in character's of the device's buffer.
71    pub receive_fifo_depth: u32,
72    /// Number of data bits in each character.
73    pub data_bits: u32,
74    /// If applicable, the parity that is computed or checked for each character.
75    pub parity: Parity,
76    /// If applicable, the number of stop bits per character.
77    pub stop_bits: StopBits,
78}
79
80newtype_enum! {
81    /// The revision of the [`SerialIoProtocol`].
82    #[derive(Default)]
83    pub enum SerialIoProtocolRevision: u32  => {
84        /// Initial version 1.0.
85        REVISION_1_0 = 0x00010000,
86        /// Version 1.1.
87        REVISION_1_1 = 0x00010001,
88    }
89}
90
91/// Serial I/O protocol (revision 1.0).
92#[derive(Debug)]
93#[repr(C)]
94pub struct SerialIoProtocol {
95    pub revision: SerialIoProtocolRevision,
96    pub reset: unsafe extern "efiapi" fn(*mut Self) -> Status,
97    pub set_attributes: unsafe extern "efiapi" fn(
98        *mut Self,
99        baud_rate: u64,
100        receive_fifo_depth: u32,
101        timeout: u32,
102        parity: Parity,
103        data_bits: u8,
104        stop_bits_type: StopBits,
105    ) -> Status,
106    pub set_control_bits: unsafe extern "efiapi" fn(*mut Self, ControlBits) -> Status,
107    pub get_control_bits: unsafe extern "efiapi" fn(*const Self, *mut ControlBits) -> Status,
108    pub write: unsafe extern "efiapi" fn(*mut Self, *mut usize, *const u8) -> Status,
109    pub read: unsafe extern "efiapi" fn(*mut Self, *mut usize, *mut u8) -> Status,
110    pub mode: *const SerialIoMode,
111}
112
113impl SerialIoProtocol {
114    pub const GUID: Guid = guid!("bb25cf6f-f1d4-11d2-9a0c-0090273fc1fd");
115}
116
117/// Serial I/O protocol (revision 1.1).
118#[derive(Debug)]
119#[repr(C)]
120#[allow(non_camel_case_types)]
121pub struct SerialIoProtocol_1_1 {
122    pub base_protocol: SerialIoProtocol,
123    pub device_type_guid: *const Guid,
124}
125
126impl SerialIoProtocol_1_1 {
127    pub const GUID: Guid = SerialIoProtocol::GUID;
128}
129
130newtype_enum! {
131    /// The parity of the device.
132    pub enum Parity: u32 => {
133        /// Device default
134        DEFAULT = 0,
135        /// No parity
136        NONE = 1,
137        /// Even parity
138        EVEN = 2,
139        /// Odd parity
140        ODD = 3,
141        /// Mark parity
142        MARK = 4,
143        /// Space parity
144        SPACE = 5,
145    }
146}
147
148newtype_enum! {
149    /// Number of stop bits per character.
150    pub enum StopBits: u32 => {
151        /// Device default
152        DEFAULT = 0,
153        /// 1 stop bit
154        ONE = 1,
155        /// 1.5 stop bits
156        ONE_FIVE = 2,
157        /// 2 stop bits
158        TWO = 3,
159    }
160}