veer_el2/
io.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright (c) 2024 Antmicro <www.antmicro.com>
4
5use core::cell::Cell;
6use core::ptr::write_volatile;
7use kernel::deferred_call::{DeferredCall, DeferredCallClient};
8use kernel::hil;
9use kernel::utilities::cells::{OptionalCell, TakeCell};
10use kernel::ErrorCode;
11
12pub struct SemihostUart<'a> {
13    deferred_call: DeferredCall,
14    tx_client: OptionalCell<&'a dyn hil::uart::TransmitClient>,
15    tx_buffer: TakeCell<'static, [u8]>,
16    tx_len: Cell<usize>,
17}
18
19impl<'a> SemihostUart<'a> {
20    pub fn new() -> SemihostUart<'a> {
21        SemihostUart {
22            deferred_call: DeferredCall::new(),
23            tx_client: OptionalCell::empty(),
24            tx_buffer: TakeCell::empty(),
25            tx_len: Cell::new(0),
26        }
27    }
28}
29
30impl Default for SemihostUart<'_> {
31    fn default() -> Self {
32        Self::new()
33    }
34}
35
36impl hil::uart::Configure for SemihostUart<'_> {
37    fn configure(&self, _params: hil::uart::Parameters) -> Result<(), ErrorCode> {
38        Ok(())
39    }
40}
41
42impl<'a> hil::uart::Transmit<'a> for SemihostUart<'a> {
43    fn set_transmit_client(&self, client: &'a dyn hil::uart::TransmitClient) {
44        self.tx_client.set(client);
45    }
46
47    fn transmit_buffer(
48        &self,
49        tx_buffer: &'static mut [u8],
50        tx_len: usize,
51    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
52        if tx_len == 0 || tx_len > tx_buffer.len() {
53            Err((ErrorCode::SIZE, tx_buffer))
54        } else if self.tx_buffer.is_some() {
55            Err((ErrorCode::BUSY, tx_buffer))
56        } else {
57            for b in &tx_buffer[..tx_len] {
58                unsafe {
59                    // Print to this address for simulation output
60                    write_volatile(0xd0580000 as *mut u32, (*b) as u32);
61                }
62            }
63            self.tx_len.set(tx_len);
64            self.tx_buffer.replace(tx_buffer);
65            // The whole buffer was transmited immediately
66            self.deferred_call.set();
67            Ok(())
68        }
69    }
70
71    fn transmit_word(&self, _word: u32) -> Result<(), ErrorCode> {
72        Err(ErrorCode::FAIL)
73    }
74
75    fn transmit_abort(&self) -> Result<(), ErrorCode> {
76        Err(ErrorCode::FAIL)
77    }
78}
79
80impl<'a> hil::uart::Receive<'a> for SemihostUart<'a> {
81    fn set_receive_client(&self, _client: &'a dyn hil::uart::ReceiveClient) {}
82    fn receive_buffer(
83        &self,
84        rx_buffer: &'static mut [u8],
85        _rx_len: usize,
86    ) -> Result<(), (ErrorCode, &'static mut [u8])> {
87        Err((ErrorCode::FAIL, rx_buffer))
88    }
89    fn receive_word(&self) -> Result<(), ErrorCode> {
90        Err(ErrorCode::FAIL)
91    }
92    fn receive_abort(&self) -> Result<(), ErrorCode> {
93        Err(ErrorCode::FAIL)
94    }
95}
96
97impl DeferredCallClient for SemihostUart<'_> {
98    fn register(&'static self) {
99        self.deferred_call.register(self);
100    }
101
102    fn handle_deferred_call(&self) {
103        self.tx_client.map(|client| {
104            self.tx_buffer.take().map(|tx_buf| {
105                client.transmitted_buffer(tx_buf, self.tx_len.get(), Ok(()));
106            });
107        });
108    }
109}