Move timer and uart driver to sw/matcha/hal along with the other hardware-specific code. Remove some hacky stuff for dprintf(). Change-Id: I6d1eebde29583b357cbda6e2b04b031c9ea3d3c9
diff --git a/chips/opentitan/Cargo.toml b/chips/opentitan/Cargo.toml deleted file mode 100644 index b7a0004..0000000 --- a/chips/opentitan/Cargo.toml +++ /dev/null
@@ -1,10 +0,0 @@ -[package] -name = "opentitan" -version = "0.1.0" -authors = ["Tock Project Developers <tock-dev@googlegroups.com>"] -edition = "2018" - -[dependencies] -rv32i = { path = "../../../tock/arch/rv32i" } -kernel = { path = "../../../tock/kernel" } -tock-rt0 = { path = "../../../tock/libraries/tock-rt0" }
diff --git a/chips/opentitan/src/lib.rs b/chips/opentitan/src/lib.rs deleted file mode 100644 index 9622367..0000000 --- a/chips/opentitan/src/lib.rs +++ /dev/null
@@ -1,8 +0,0 @@ -//! Implementations for generic OpenTitan peripherals. - -#![feature(const_fn)] -#![no_std] -#![crate_name = "opentitan"] -#![crate_type = "rlib"] - -pub mod uart;
diff --git a/config/src/lib.rs b/config/src/lib.rs index 83a4ecf..9c4972b 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs
@@ -3,6 +3,10 @@ #![no_std] +pub const CHIP_NAME: &str = "sim_verilator"; +pub const CHIP_CPU_FREQ: u32 = 500_000; +pub const CHIP_PERIPH_FREQ: u32 = 125_000; + // TODO(aappleby): Shared capsule/command numbers can't go in matcha_capsule // right now due to some sort of toolchain mismatch that we need to figure out // later. @@ -24,14 +28,15 @@ pub const CMD_ELFLOADER_BOOT_SEL4: usize = 10; pub const CMD_DPRINTF_PRINT: usize = 0; -pub const IRQ_UART0_TX_WATERMARK: u32 = 1; // kTopMatchaPlicIrqIdUart0TxWatermark @ top_matcha.h -pub const IRQ_UART0_RX_PARITY_ERR: u32 = 8; // kTopMatchaPlicIrqIdUart0RxParityErr @ top_matcha.h +pub const IRQ_UART0_TX_WATERMARK: u32 = 1; // kTopMatchaPlicIrqIdUart0TxWatermark @ top_matcha.h +pub const IRQ_UART0_RX_PARITY_ERR: u32 = 8; // kTopMatchaPlicIrqIdUart0RxParityErr @ top_matcha.h -pub const PLIC_BASE: u32 = 0x48000000; // TOP_MATCHA_RV_PLIC_BASE_ADDR +pub const PLIC_BASE: u32 = 0x48000000; // TOP_MATCHA_RV_PLIC_BASE_ADDR pub const MAILBOX_BASE: u32 = 0x40800000; // TOP_MATCHA_MAILBOX_SEC_BASE_ADDR -pub const MAILBOX_WTIRQ: u32 = 181; // kTopMatchaPlicIrqIdMailboxSecWtirq -pub const MAILBOX_RTIRQ: u32 = 182; // kTopMatchaPlicIrqIdMailboxSecRtirq -pub const MAILBOX_EIRQ: u32 = 183; // kTopMatchaPlicIrqIdMailboxSecEirq +pub const MAILBOX_WTIRQ: u32 = 181; // kTopMatchaPlicIrqIdMailboxSecWtirq +pub const MAILBOX_RTIRQ: u32 = 182; // kTopMatchaPlicIrqIdMailboxSecRtirq +pub const MAILBOX_EIRQ: u32 = 183; // kTopMatchaPlicIrqIdMailboxSecEirq -pub const UART0_BASE_ADDRESS: u32 = 0x40000000; +pub const UART0_BASE_ADDRESS: u32 = 0x40000000; // TOP_MATCHA_UART0_BASE_ADDR +pub const UART0_BAUDRATE: u32 = 9600;
diff --git a/hal/src/dprintf_hal.rs b/hal/src/dprintf_hal.rs index 848a76f..a2e33f3 100644 --- a/hal/src/dprintf_hal.rs +++ b/hal/src/dprintf_hal.rs
@@ -1,26 +1,12 @@ //! Unsafe synchronous dump-string-to-uart impl and macro for debugging. -use core2::io::{Cursor, Write}; use core::fmt; +use core2::io::{Cursor, Write}; -// TODO(jtgans|aappleby): b/239714445. Use the actual UART registers defined in -// opentitan/uart.rs instead of hardcoding them here. Or better: get rid of this -// gross hack and replace with something less gross. :P -pub const TX_BUSY: *const u32 = 0x4000_0014 as *const u32; -pub const TX_PORT: *mut u32 = 0x4000_001c as *mut u32; - +// Convenience wrapper since capsules can't use unsafe{} pub fn send_sync(buf: &[u8], len: usize) { unsafe { - for i in 0..len { - // TODO(jtgans|aappleby): b/239714445. This is a gross hack to - // ensure we don't buffer dprintf output for diagnosing early boot - // of the system. - // - // NOTE: if the UART registers change, we're going to have to fix - // this here as well! - while (TX_BUSY.read_volatile() & 1) != 0 {} - TX_PORT.write_volatile(buf[i] as u32); - } + crate::uart_hal::UART0.transmit_sync(&buf[..len]); } }
diff --git a/hal/src/lib.rs b/hal/src/lib.rs index 6a929e7..4cd367b 100644 --- a/hal/src/lib.rs +++ b/hal/src/lib.rs
@@ -3,11 +3,14 @@ #![no_std] #![feature(asm)] +#![feature(const_fn)] pub mod dprintf_hal; pub mod mailbox_hal; -pub mod plic_hal; pub mod plic_constants; +pub mod plic_hal; +pub mod timer_hal; +pub mod uart_hal; // Software interrupt enable bits in MIE pub const USIE_BIT: u32 = 1 << 0;
diff --git a/platform/src/timer.rs b/hal/src/timer_hal.rs similarity index 97% rename from platform/src/timer.rs rename to hal/src/timer_hal.rs index b7dd21f..f1c212f 100644 --- a/platform/src/timer.rs +++ b/hal/src/timer_hal.rs
@@ -7,7 +7,7 @@ use kernel::hil::time::{Ticks, Ticks64, Time}; use kernel::ReturnCode; -const PRESCALE: u16 = ((crate::chip::CHIP_CPU_FREQ / 10_000) - 1) as u16; // 10Khz +const PRESCALE: u16 = ((matcha_config::CHIP_CPU_FREQ / 10_000) - 1) as u16; // 10Khz /// 10KHz `Frequency` #[derive(Debug)]
diff --git a/chips/opentitan/src/uart.rs b/hal/src/uart_hal.rs similarity index 87% rename from chips/opentitan/src/uart.rs rename to hal/src/uart_hal.rs index 0c21cad..a93d098 100644 --- a/chips/opentitan/src/uart.rs +++ b/hal/src/uart_hal.rs
@@ -1,4 +1,4 @@ -//! UART driver. +//! UART driver, supports the OpenTitan UART hardware. use core::cell::Cell; @@ -12,39 +12,41 @@ use kernel::hil::uart; use kernel::ReturnCode; -// BIG FAT NOTE: if the UART registers change, we're going to have to fix the -// dprintf hack in dprintf_hal.rs as well, since it bypasses these register -// definitions. If you fix this, please fix b/239714445 as well. +pub const UART0_REGISTERS: StaticRef<UartRegisters> = + unsafe { StaticRef::new(matcha_config::UART0_BASE_ADDRESS as *const UartRegisters) }; + +pub static mut UART0: Uart = Uart::new(UART0_REGISTERS, matcha_config::CHIP_PERIPH_FREQ); + register_structs! { pub UartRegisters { - (0x000 => intr_state: ReadWrite<u32, intr::Register>), - (0x004 => intr_enable: ReadWrite<u32, intr::Register>), - (0x008 => intr_test: ReadWrite<u32, intr::Register>), - (0x00c => alert_test: ReadWrite<u32, intr::Register>), + (0x000 => pub intr_state: ReadWrite<u32, intr::Register>), + (0x004 => pub intr_enable: ReadWrite<u32, intr::Register>), + (0x008 => pub intr_test: ReadWrite<u32, intr::Register>), + (0x00c => pub alert_test: ReadWrite<u32, intr::Register>), /// UART control register - (0x010 => ctrl: ReadWrite<u32, ctrl::Register>), + (0x010 => pub ctrl: ReadWrite<u32, ctrl::Register>), /// UART live status register - (0x014 => status: ReadOnly<u32, status::Register>), + (0x014 => pub status: ReadOnly<u32, status::Register>), /// UART read data) - (0x018 => rdata: ReadOnly<u32, rdata::Register>), + (0x018 => pub rdata: ReadOnly<u32, rdata::Register>), /// UART write data - (0x01c => wdata: WriteOnly<u32, wdata::Register>), + (0x01c => pub wdata: WriteOnly<u32, wdata::Register>), /// UART FIFO control register") - (0x020 => fifo_ctrl: ReadWrite<u32, fifo_ctrl::Register>), + (0x020 => pub fifo_ctrl: ReadWrite<u32, fifo_ctrl::Register>), /// UART FIFO status register - (0x024 => fifo_status: ReadWrite<u32, fifo_status::Register>), + (0x024 => pub fifo_status: ReadWrite<u32, fifo_status::Register>), /// TX pin override control. Gives direct SW control over TX pin state - (0x028 => ovrd: ReadWrite<u32, ovrd::Register>), + (0x028 => pub ovrd: ReadWrite<u32, ovrd::Register>), /// UART oversampled values - (0x02c => val: ReadWrite<u32, val::Register>), + (0x02c => pub val: ReadWrite<u32, val::Register>), /// UART RX timeout control - (0x030 => timeout_ctrl: ReadWrite<u32, timeout_ctrl::Register>), + (0x030 => pub timeout_ctrl: ReadWrite<u32, timeout_ctrl::Register>), (0x034 => @END), } } register_bitfields![u32, - intr [ + pub intr [ tx_watermark OFFSET(0) NUMBITS(1) [], rx_watermark OFFSET(1) NUMBITS(1) [], tx_empty OFFSET(2) NUMBITS(1) [], @@ -54,7 +56,7 @@ rx_timeout OFFSET(6) NUMBITS(1) [], rx_parity_err OFFSET(7) NUMBITS(1) [] ], - ctrl [ + pub ctrl [ tx OFFSET(0) NUMBITS(1) [], rx OFFSET(1) NUMBITS(1) [], nf OFFSET(2) NUMBITS(1) [], @@ -65,7 +67,7 @@ rxblvl OFFSET(8) NUMBITS(2) [], nco OFFSET(16) NUMBITS(16) [] ], - status [ + pub status [ txfull OFFSET(0) NUMBITS(1) [], rxfull OFFSET(1) NUMBITS(1) [], txempty OFFSET(2) NUMBITS(1) [], @@ -73,30 +75,30 @@ rxidle OFFSET(4) NUMBITS(1) [], rxempty OFFSET(5) NUMBITS(1) [] ], - rdata [ + pub rdata [ data OFFSET(0) NUMBITS(8) [] ], - wdata [ + pub wdata [ data OFFSET(0) NUMBITS(8) [] ], - fifo_ctrl [ + pub fifo_ctrl [ rxrst OFFSET(0) NUMBITS(1) [], txrst OFFSET(1) NUMBITS(1) [], rxilvl OFFSET(2) NUMBITS(2) [], txilvl OFFSET(5) NUMBITS(2) [] ], - fifo_status [ + pub fifo_status [ txlvl OFFSET(0) NUMBITS(5) [], rxlvl OFFSET(16) NUMBITS(5) [] ], - ovrd [ + pub ovrd [ txen OFFSET(0) NUMBITS(1) [], txval OFFSET(1) NUMBITS(1) [] ], - val [ + pub val [ rx OFFSET(0) NUMBITS(16) [] ], - timeout_ctrl [ + pub timeout_ctrl [ val OFFSET(0) NUMBITS(23) [], en OFFSET(31) NUMBITS(1) [] ]
diff --git a/platform/Cargo.toml b/platform/Cargo.toml index a0ee2e4..e3c1b04 100644 --- a/platform/Cargo.toml +++ b/platform/Cargo.toml
@@ -11,7 +11,6 @@ capsules = { path = "../../tock/capsules" } kernel = { path = "../../tock/kernel" } lowrisc = { path = "../../tock/chips/lowrisc" } -opentitan = { path = "../chips/opentitan" } blob_fs = { path = "../blob_fs" } matcha_capsules = { path = "../capsules" }
diff --git a/platform/src/chip.rs b/platform/src/chip.rs index 96d1b4a..86a216d 100644 --- a/platform/src/chip.rs +++ b/platform/src/chip.rs
@@ -9,24 +9,19 @@ use rv32i::syscall::SysCall; use rv32i::PMPConfigMacro; -use crate::timer; -use crate::uart; -use matcha_hal::plic_hal; use matcha_config::*; -use matcha_hal::mailbox_hal::MailboxISR; +use matcha_hal::mailbox_hal; +use matcha_hal::plic_hal; +use matcha_hal::timer_hal; +use matcha_hal::uart_hal; PMPConfigMacro!(4); -pub const CHIP_NAME: &str = "sim_verilator"; -pub const CHIP_CPU_FREQ: u32 = 500_000; -pub const CHIP_PERIPH_FREQ: u32 = 125_000; -pub const CHIP_UART_BPS: u32 = 9600; - pub struct Matcha<A: 'static + Alarm<'static>> { userspace_kernel_boundary: SysCall, pmp: PMP, scheduler_timer: kernel::VirtualSchedulerTimer<A>, - mailbox_isr: Cell<Option<&'static dyn MailboxISR>>, + mailbox_isr: Cell<Option<&'static dyn mailbox_hal::MailboxISR>>, } impl<A: 'static + Alarm<'static>> Matcha<A> { @@ -39,7 +34,7 @@ } } - pub fn set_mailbox_isr(&self, mailbox_isr : &'static dyn MailboxISR) { + pub fn set_mailbox_isr(&self, mailbox_isr: &'static dyn mailbox_hal::MailboxISR) { self.mailbox_isr.set(Some(mailbox_isr)); } @@ -52,10 +47,18 @@ unsafe fn handle_plic_interrupts(&self) { while let Some(interrupt) = plic_hal::next_pending() { match interrupt { - IRQ_UART0_TX_WATERMARK..=IRQ_UART0_RX_PARITY_ERR => uart::UART0.handle_interrupt(), - MAILBOX_WTIRQ => {self.mailbox_isr.get().map(|mb| mb.on_wtirq());}, - MAILBOX_RTIRQ => {self.mailbox_isr.get().map(|mb| mb.on_rtirq());}, - MAILBOX_EIRQ => {self.mailbox_isr.get().map(|mb| mb.on_eirq());}, + IRQ_UART0_TX_WATERMARK..=IRQ_UART0_RX_PARITY_ERR => { + uart_hal::UART0.handle_interrupt() + } + MAILBOX_WTIRQ => { + self.mailbox_isr.get().map(|mb| mb.on_wtirq()); + } + MAILBOX_RTIRQ => { + self.mailbox_isr.get().map(|mb| mb.on_rtirq()); + } + MAILBOX_EIRQ => { + self.mailbox_isr.get().map(|mb| mb.on_eirq()); + } _ => debug!("Pidx {}", interrupt), } plic_hal::complete(interrupt); @@ -91,7 +94,7 @@ if mip.is_set(mip::mtimer) { unsafe { - timer::TIMER.service_interrupt(); + timer_hal::TIMER.service_interrupt(); } } if mip.is_set(mip::mext) { @@ -133,7 +136,7 @@ unsafe fn print_state(&self, writer: &mut dyn Write) { let _ = writer.write_fmt(format_args!( "\r\n---| Matcha configuration for {} |---", - crate::chip::CHIP_NAME + matcha_config::CHIP_NAME )); rv32i::print_riscv_state(writer); }
diff --git a/platform/src/main.rs b/platform/src/main.rs index 00935f9..b10ee77 100644 --- a/platform/src/main.rs +++ b/platform/src/main.rs
@@ -18,15 +18,15 @@ use kernel::{create_capability, debug, static_init}; use matcha_capsules::dprintf_capsule::DprintfCapsule; use matcha_capsules::elfloader_capsule::ElfLoaderCapsule; -use matcha_capsules::storage_capsule::StorageCapsule; use matcha_capsules::mailbox_capsule::MailboxCapsule; +use matcha_capsules::storage_capsule::StorageCapsule; use matcha_config::*; use matcha_hal::dprintf; +use matcha_hal::timer_hal; +use matcha_hal::uart_hal; use rv32i::csr; pub mod chip; -pub mod timer; -pub mod uart; /// Panic handler. #[cfg(not(test))] @@ -66,7 +66,7 @@ console_capsule: &'static capsules::console::Console<'static>, alarm_capsule: &'static capsules::alarm::AlarmDriver< 'static, - VirtualMuxAlarm<'static, crate::timer::RvTimer<'static>>, + VirtualMuxAlarm<'static, timer_hal::RvTimer<'static>>, >, dprintf_capsule: &'static DprintfCapsule, storage_capsule: &'static StorageCapsule, @@ -128,34 +128,31 @@ // Create a shared UART channel for the console and for kernel debug. let uart_mux = components::console::UartMuxComponent::new( - &crate::uart::UART0, - crate::uart::UART0_BAUDRATE, + &uart_hal::UART0, + matcha_config::UART0_BAUDRATE, dynamic_deferred_caller, ) .finalize(()); - let alarm = &crate::timer::TIMER; + let alarm = &timer_hal::TIMER; alarm.setup(); // Create a shared virtualization mux layer on top of a single hardware // alarm. - let mux_alarm = static_init!( - MuxAlarm<'static, crate::timer::RvTimer>, - MuxAlarm::new(alarm) - ); - hil::time::Alarm::set_alarm_client(&crate::timer::TIMER, mux_alarm); + let mux_alarm = static_init!(MuxAlarm<'static, timer_hal::RvTimer>, MuxAlarm::new(alarm)); + hil::time::Alarm::set_alarm_client(&timer_hal::TIMER, mux_alarm); // Alarm let virtual_alarm_user = static_init!( - VirtualMuxAlarm<'static, crate::timer::RvTimer>, + VirtualMuxAlarm<'static, timer_hal::RvTimer>, VirtualMuxAlarm::new(mux_alarm) ); let scheduler_timer_virtual_alarm = static_init!( - VirtualMuxAlarm<'static, crate::timer::RvTimer>, + VirtualMuxAlarm<'static, timer_hal::RvTimer>, VirtualMuxAlarm::new(mux_alarm) ); let alarm_capsule = static_init!( - capsules::alarm::AlarmDriver<'static, VirtualMuxAlarm<'static, crate::timer::RvTimer>>, + capsules::alarm::AlarmDriver<'static, VirtualMuxAlarm<'static, timer_hal::RvTimer>>, capsules::alarm::AlarmDriver::new( virtual_alarm_user, board_kernel.create_grant(&memory_allocation_cap) @@ -164,7 +161,7 @@ hil::time::Alarm::set_alarm_client(virtual_alarm_user, alarm_capsule); let chip = static_init!( - crate::chip::Matcha<VirtualMuxAlarm<'static, crate::timer::RvTimer>>, + crate::chip::Matcha<VirtualMuxAlarm<'static, timer_hal::RvTimer>>, crate::chip::Matcha::new(scheduler_timer_virtual_alarm) ); scheduler_timer_virtual_alarm.set_alarm_client(chip.scheduler_timer()); @@ -202,7 +199,7 @@ // Construct a mailbox that points to the platform-specific base address and // PLIC lines - let mailbox_hal : &'static mut matcha_hal::mailbox_hal::MailboxImpl = static_init!( + let mailbox_hal: &'static mut matcha_hal::mailbox_hal::MailboxImpl = static_init!( matcha_hal::mailbox_hal::MailboxImpl, matcha_hal::mailbox_hal::MailboxImpl::new( MAILBOX_BASE,
diff --git a/platform/src/uart.rs b/platform/src/uart.rs deleted file mode 100644 index 5ebe18c..0000000 --- a/platform/src/uart.rs +++ /dev/null
@@ -1,10 +0,0 @@ -use kernel::common::StaticRef; -use opentitan::uart::{Uart, UartRegisters}; -use matcha_config::*; - -pub const UART0_BAUDRATE: u32 = crate::chip::CHIP_UART_BPS; - -pub static mut UART0: Uart = Uart::new(UART0_BASE, crate::chip::CHIP_PERIPH_FREQ); - -const UART0_BASE: StaticRef<UartRegisters> = - unsafe { StaticRef::new(UART0_BASE_ADDRESS as *const UartRegisters) };