opentitanlib/io/
middleware.rs

1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5use std::rc::Rc;
6use std::task::{Context, Poll};
7
8use anyhow::Result;
9
10use crate::io::console::{ConsoleDevice, CoverageConsole};
11use crate::io::uart::Uart;
12
13/// Base trait for middlewares that wrap an inner object.
14pub trait Middleware {
15    type Inner: ?Sized;
16    fn inner(&self) -> &Self::Inner;
17}
18
19/// Interface for middlewares that wrap a console device.
20pub trait ConsoleMiddleware: Middleware
21where
22    Self::Inner: ConsoleDevice,
23{
24    fn poll_read_impl(&self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>> {
25        self.inner().poll_read(cx, buf)
26    }
27
28    fn write_impl(&self, buf: &[u8]) -> Result<()> {
29        self.inner().write(buf)
30    }
31
32    fn as_coverage_console_impl(&self) -> Option<&dyn CoverageConsole> {
33        self.inner().as_coverage_console()
34    }
35}
36
37impl<T: ConsoleMiddleware> ConsoleDevice for T
38where
39    T::Inner: ConsoleDevice,
40{
41    fn poll_read(&self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>> {
42        self.poll_read_impl(cx, buf)
43    }
44
45    fn write(&self, buf: &[u8]) -> Result<()> {
46        self.write_impl(buf)
47    }
48
49    fn as_coverage_console(&self) -> Option<&dyn CoverageConsole> {
50        self.as_coverage_console_impl()
51    }
52}
53
54impl<T: ConsoleMiddleware> CoverageConsole for T
55where
56    T::Inner: CoverageConsole + ConsoleDevice,
57{
58    fn coverage_blocks_processed(&self) -> usize {
59        self.inner().coverage_blocks_processed()
60    }
61}
62
63/// Interface for middlewares that forward UART methods.
64pub trait UartMiddleware: Middleware
65where
66    Self::Inner: Uart,
67{
68    fn get_baudrate_impl(&self) -> Result<u32> {
69        self.inner().get_baudrate()
70    }
71
72    fn set_baudrate_impl(&self, baudrate: u32) -> Result<()> {
73        self.inner().set_baudrate(baudrate)
74    }
75
76    fn get_flow_control_impl(&self) -> Result<crate::io::uart::FlowControl> {
77        self.inner().get_flow_control()
78    }
79
80    fn set_flow_control_impl(&self, flow_control: bool) -> Result<()> {
81        self.inner().set_flow_control(flow_control)
82    }
83
84    fn get_device_path_impl(&self) -> Result<String> {
85        self.inner().get_device_path()
86    }
87
88    fn clear_rx_buffer_impl(&self) -> Result<()> {
89        self.inner().clear_rx_buffer()
90    }
91
92    fn set_parity_impl(&self, parity: crate::io::uart::Parity) -> Result<()> {
93        self.inner().set_parity(parity)
94    }
95
96    fn get_parity_impl(&self) -> Result<crate::io::uart::Parity> {
97        self.inner().get_parity()
98    }
99
100    fn set_break_impl(&self, enable: bool) -> Result<()> {
101        self.inner().set_break(enable)
102    }
103
104    fn borrow_fd_impl(&self) -> Result<std::os::fd::BorrowedFd<'_>> {
105        self.inner().borrow_fd()
106    }
107}
108
109impl<T: UartMiddleware> Uart for T
110where
111    T: ConsoleDevice,
112    T::Inner: Uart,
113{
114    fn get_baudrate(&self) -> Result<u32> {
115        self.get_baudrate_impl()
116    }
117
118    fn set_baudrate(&self, baudrate: u32) -> Result<()> {
119        self.set_baudrate_impl(baudrate)
120    }
121
122    fn get_flow_control(&self) -> Result<crate::io::uart::FlowControl> {
123        self.get_flow_control_impl()
124    }
125
126    fn set_flow_control(&self, flow_control: bool) -> Result<()> {
127        self.set_flow_control_impl(flow_control)
128    }
129
130    fn get_device_path(&self) -> Result<String> {
131        self.get_device_path_impl()
132    }
133
134    fn clear_rx_buffer(&self) -> Result<()> {
135        self.clear_rx_buffer_impl()
136    }
137
138    fn set_parity(&self, parity: crate::io::uart::Parity) -> Result<()> {
139        self.set_parity_impl(parity)
140    }
141
142    fn get_parity(&self) -> Result<crate::io::uart::Parity> {
143        self.get_parity_impl()
144    }
145
146    fn set_break(&self, enable: bool) -> Result<()> {
147        self.set_break_impl(enable)
148    }
149
150    fn borrow_fd(&self) -> Result<std::os::fd::BorrowedFd<'_>> {
151        self.borrow_fd_impl()
152    }
153}
154
155impl<T: ?Sized> Middleware for &T {
156    type Inner = T;
157    fn inner(&self) -> &T {
158        self
159    }
160}
161impl<T: ConsoleDevice + ?Sized> ConsoleMiddleware for &T {}
162impl<T: crate::io::uart::Uart + ?Sized> UartMiddleware for &T {}
163
164impl<T: ?Sized> Middleware for Rc<T> {
165    type Inner = T;
166    fn inner(&self) -> &T {
167        self
168    }
169}
170impl<T: ConsoleDevice + ?Sized> ConsoleMiddleware for Rc<T> {}
171impl<T: crate::io::uart::Uart + ?Sized> UartMiddleware for Rc<T> {}
172
173impl<T: ?Sized> Middleware for Box<T> {
174    type Inner = T;
175    fn inner(&self) -> &T {
176        self
177    }
178}
179impl<T: ConsoleDevice + ?Sized> ConsoleMiddleware for Box<T> {}
180impl<T: crate::io::uart::Uart + ?Sized> UartMiddleware for Box<T> {}