tg_rcore_tutorial_driver/
input.rs1use core::any::Any;
4use spin::Mutex;
5use virtio_drivers::{Hal, MmioTransport, VirtIOInput};
6
7use crate::{buffer::RingBuffer, clock, devices::Device};
8
9#[repr(C)]
10#[derive(Debug, Clone, Copy)]
11pub struct InputEvent {
12 pub timestamp: u64,
13 pub event_type: u16,
14 pub code: u16,
15 pub value: u32,
16}
17
18struct VirtIOInputInner<H: Hal> {
19 virtio_input: VirtIOInput<H, MmioTransport>,
20 events: RingBuffer<InputEvent, 128>, }
22
23pub struct VirtIOInputWrapper<H: Hal> {
24 inner: Mutex<VirtIOInputInner<H>>,
25}
26
27pub trait InputDevice: Device + Send + Sync + Any {
28 fn read_event(&self) -> Option<InputEvent>;
29 fn is_empty(&self) -> bool;
30}
31
32impl<H: Hal> VirtIOInputWrapper<H> {
33 pub fn new(transport: MmioTransport, buffer_overflow_strategy: crate::buffer::OverflowStrategy) -> Result<Self, virtio_drivers::Error> {
34 let inner = VirtIOInputInner {
35 virtio_input: VirtIOInput::new(transport)?,
36 events: RingBuffer::new(buffer_overflow_strategy),
37 };
38 Ok(Self {
39 inner: Mutex::new(inner),
40 })
41 }
42}
43
44unsafe impl<H: Hal> Send for VirtIOInputWrapper<H> {}
45unsafe impl<H: Hal> Sync for VirtIOInputWrapper<H> {}
46
47impl<H: Hal + 'static> InputDevice for VirtIOInputWrapper<H> {
48 fn is_empty(&self) -> bool {
49 self.inner.lock().events.is_empty()
50 }
51
52 fn read_event(&self) -> Option<InputEvent> {
53 self.inner.lock().events.pop()
54 }
55}
56
57impl<H: Hal + 'static> Device for VirtIOInputWrapper<H> {
58 fn handle_irq(&self) {
59 let mut inner = self.inner.lock();
61
62 inner.virtio_input.ack_interrupt();
63 while let Some(event) = inner.virtio_input.pop_pending_event() {
64 let result = InputEvent {
65 timestamp: clock::get_time_us() as u64,
66 event_type: event.event_type,
67 code: event.code,
68 value: event.value
69 };
70 let _ = inner.events.push(result);
71 }
72 }
73}