x86_q35/
vga_uart_driver.rs1use crate::vga::Vga;
18use core::{cell::Cell, cmp};
19use kernel::deferred_call::{DeferredCall, DeferredCallClient};
20use kernel::hil::uart::{Configure, Parameters, Receive, ReceiveClient, Transmit, TransmitClient};
21use kernel::utilities::cells::TakeCell;
22use kernel::ErrorCode;
23use tock_cells::optional_cell::OptionalCell;
24
25pub struct VgaText<'a> {
27 vga_buffer: Vga,
28 tx_client: OptionalCell<&'a dyn TransmitClient>,
29 rx_client: OptionalCell<&'a dyn ReceiveClient>,
30 deferred_call: DeferredCall,
31 pending_buf: TakeCell<'static, [u8]>,
32 pending_len: Cell<usize>,
33}
34
35impl VgaText<'_> {
36 pub fn new() -> Self {
37 Self {
38 vga_buffer: Vga::new(),
39 tx_client: OptionalCell::empty(),
40 rx_client: OptionalCell::empty(),
41 deferred_call: DeferredCall::new(),
42 pending_buf: TakeCell::empty(),
43 pending_len: Cell::new(0),
44 }
45 }
46
47 fn fire_tx_callback(&self, buf: &'static mut [u8], len: usize) {
48 self.tx_client.map(|client| {
49 client.transmitted_buffer(buf, len, Ok(()));
50 });
51 }
52}
53
54impl DeferredCallClient for VgaText<'_> {
56 fn handle_deferred_call(&self) {
57 if let Some(buf) = self.pending_buf.take() {
58 let len = self.pending_len.get();
59 self.fire_tx_callback(buf, len);
60 }
61 }
62
63 fn register(&'static self) {
64 self.deferred_call.register(self);
65 }
66}
67
68impl<'a> Transmit<'a> for VgaText<'a> {
70 fn set_transmit_client(&self, client: &'a dyn TransmitClient) {
71 self.tx_client.set(client);
72 }
73
74 fn transmit_buffer(
75 &self,
76 buffer: &'static mut [u8],
77 len: usize,
78 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
79 let write_len = cmp::min(len, buffer.len());
80 for &byte in &buffer[..write_len] {
81 self.vga_buffer.write_byte(byte);
82 }
83 self.pending_buf.replace(buffer);
84 self.pending_len.set(len);
85 self.deferred_call.set();
86 Ok(())
87 }
88
89 fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
90 Err(ErrorCode::NOSUPPORT)
91 }
92
93 fn transmit_abort(&self) -> Result<(), ErrorCode> {
94 Err(ErrorCode::NOSUPPORT)
95 }
96}
97
98impl<'a> Receive<'a> for VgaText<'a> {
100 fn set_receive_client(&self, client: &'a dyn ReceiveClient) {
101 self.rx_client.set(client);
102 }
103
104 fn receive_buffer(
105 &self,
106 buffer: &'static mut [u8],
107 _len: usize,
108 ) -> Result<(), (ErrorCode, &'static mut [u8])> {
109 Err((ErrorCode::NOSUPPORT, buffer))
110 }
111
112 fn receive_word(&self) -> Result<(), ErrorCode> {
113 Err(ErrorCode::NOSUPPORT)
114 }
115
116 fn receive_abort(&self) -> Result<(), ErrorCode> {
117 Err(ErrorCode::NOSUPPORT)
118 }
119}
120
121impl Configure for VgaText<'_> {
123 fn configure(&self, _params: Parameters) -> Result<(), ErrorCode> {
124 Ok(())
125 }
126}