diff --git a/examples/aarch64/Cargo.toml b/examples/aarch64/Cargo.toml index f8694461..2a416e39 100644 --- a/examples/aarch64/Cargo.toml +++ b/examples/aarch64/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" buddy_system_allocator = "0.10.0" flat_device_tree = "3.1.1" log = "0.4.22" +pl011-uart = "0.1.0" smccc = "0.1.1" spin = "0.9.8" virtio-drivers = { path = "../.." } diff --git a/examples/aarch64/src/main.rs b/examples/aarch64/src/main.rs index 2d7ad046..2ab89787 100644 --- a/examples/aarch64/src/main.rs +++ b/examples/aarch64/src/main.rs @@ -7,9 +7,7 @@ mod exceptions; mod hal; mod logger; #[cfg(platform = "qemu")] -mod pl011; -#[cfg(platform = "qemu")] -use pl011 as uart; +use pl011_uart as uart; #[cfg(platform = "crosvm")] mod uart8250; #[cfg(platform = "crosvm")] @@ -50,11 +48,11 @@ use virtio_drivers::{ /// Base memory-mapped address of the primary PL011 UART device. #[cfg(platform = "qemu")] -pub const UART_BASE_ADDRESS: usize = 0x900_0000; +pub const UART_BASE_ADDRESS: *mut u32 = 0x900_0000 as _; /// The base address of the first 8250 UART. #[cfg(platform = "crosvm")] -pub const UART_BASE_ADDRESS: usize = 0x3f8; +pub const UART_BASE_ADDRESS: *mut u32 = 0x3f8 as _; #[global_allocator] static HEAP_ALLOCATOR: LockedHeap<32> = LockedHeap::new(); diff --git a/examples/aarch64/src/pl011.rs b/examples/aarch64/src/pl011.rs deleted file mode 100644 index c6fc37b1..00000000 --- a/examples/aarch64/src/pl011.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Minimal driver for a PL011 UART. - -use core::fmt::{self, Write}; - -const FLAG_REGISTER_OFFSET: usize = 0x18; -const FR_BUSY: u8 = 1 << 3; -const FR_TXFF: u8 = 1 << 5; - -/// Minimal driver for a PL011 UART. -pub struct Uart { - base_address: *mut u8, -} - -impl Uart { - /// Constructs a new instance of the UART driver for a device at the given base address. - /// - /// # Safety - /// - /// The given base address must point to the 8 MMIO control registers of an appropriate UART - /// device, which must be mapped into the address space of the process as device memory and not - /// have any other aliases. - pub unsafe fn new(base_address: usize) -> Self { - Self { - base_address: base_address as *mut u8, - } - } - - /// Writes a single byte to the UART. - pub fn write_byte(&self, byte: u8) { - // Wait until there is room in the TX buffer. - while self.read_flag_register() & FR_TXFF != 0 {} - - // Safe because we know that the base address points to the control registers of a PL011 - // device which is appropriately mapped. - unsafe { - // Write to the TX buffer. - self.base_address.write_volatile(byte); - } - - // Wait until the UART is no longer busy. - while self.read_flag_register() & FR_BUSY != 0 {} - } - - fn read_flag_register(&self) -> u8 { - // Safe because we know that the base address points to the control registers of a PL011 - // device which is appropriately mapped. - unsafe { self.base_address.add(FLAG_REGISTER_OFFSET).read_volatile() } - } -} - -impl Write for Uart { - fn write_str(&mut self, s: &str) -> fmt::Result { - for c in s.as_bytes() { - self.write_byte(*c); - } - Ok(()) - } -} - -// Safe because it just contains a pointer to device memory, which can be accessed from any context. -unsafe impl Send for Uart {} diff --git a/examples/aarch64/src/uart8250.rs b/examples/aarch64/src/uart8250.rs index 0ee226b9..a283f6eb 100644 --- a/examples/aarch64/src/uart8250.rs +++ b/examples/aarch64/src/uart8250.rs @@ -18,9 +18,9 @@ impl Uart { /// The given base address must point to the 8 MMIO control registers of an appropriate UART /// device, which must be mapped into the address space of the process as device memory and not /// have any other aliases. - pub unsafe fn new(base_address: usize) -> Self { + pub unsafe fn new(base_address: *mut u32) -> Self { Self { - base_address: base_address as *mut u8, + base_address: base_address.cast(), } }