1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
#![feature(external_doc)] #![feature(const_fn)] #![feature(decl_macro)] #![feature(naked_functions)] #![feature(slice_ptr_len)] #![feature(asm)] #![feature(raw_ref_op)] #![feature(const_generics)] #![feature(const_option)] #![feature(const_mut_refs)] #![feature(const_fn_fn_ptr_basics)] #![feature(unsafe_block_in_unsafe_fn)] // `unsafe fn` doesn't imply `unsafe {}` #![deny(unsafe_op_in_unsafe_fn)] #![doc(include = "./lib.md")] #![doc(include = "./common.md")] #![no_std] use core::ops::Range; use r3::kernel::{ ClearInterruptLineError, EnableInterruptLineError, InterruptNum, InterruptPriority, PendInterruptLineError, QueryInterruptLineError, SetInterruptLinePriorityError, }; /// Used by macros #[doc(hidden)] pub extern crate r3; /// Used by macros #[doc(hidden)] pub extern crate r3_portkit; /// Used by macros #[doc(hidden)] pub extern crate core; /// The Platform-Level Interrupt Controller driver. #[doc(hidden)] pub mod plic { pub mod cfg; pub mod imp; pub mod plic_regs; } /// The binding for [`::riscv_rt`]. #[doc(hidden)] pub mod rt { pub mod cfg; #[cfg(target_os = "none")] pub mod imp; } /// The [`r3::kernel::PortThreading`] implementation. #[doc(hidden)] pub mod threading { pub mod cfg; #[cfg(target_os = "none")] pub mod imp; } /// The standard timer driver. #[doc(hidden)] pub mod timer { pub mod cfg; pub mod imp; } pub use self::plic::cfg::*; pub use self::rt::cfg::*; pub use self::threading::cfg::*; pub use self::timer::cfg::*; /// Defines the entry points of a port instantiation. Implemented by /// [`use_port!`]. pub trait EntryPoint { /// Proceed with the boot process. /// /// # Safety /// /// - The processor should be in M-mode and have M-mode interrupts masked. /// - This method hasn't been entered yet. /// unsafe fn start() -> !; /// The trap handler. /// /// # Safety /// /// - The processor should be in M-mode and have M-mode interrupts masked. /// - The register state of the background context should be preserved so /// that the handler can restore it later. /// unsafe fn exception_handler() -> !; } /// An abstract inferface to a port timer driver. Implemented by /// [`use_timer!`]. pub trait Timer { /// Initialize the driver. This will be called just before entering /// [`PortToKernel::boot`]. /// /// [`PortToKernel::boot`]: r3::kernel::PortToKernel::boot /// /// # Safety /// /// This is only intended to be called by the port. unsafe fn init() {} } /// An abstract interface to an interrupt controller. Implemented by /// [`use_plic!`]. /// /// # Safety /// /// These methods are only intended to be called by the port. pub trait InterruptController { /// Initialize the driver. This will be called just before entering /// [`PortToKernel::boot`]. /// /// [`PortToKernel::boot`]: r3::kernel::PortToKernel::boot unsafe fn init() {} /// The range of interrupt priority values considered [managed]. /// /// Defaults to `0..0` (empty) when unspecified. /// /// [managed]: r3#interrupt-handling-framework #[allow(clippy::reversed_empty_ranges)] // on purpose const MANAGED_INTERRUPT_PRIORITY_RANGE: Range<InterruptPriority> = 0..0; /// Handle the call to [`PortInterrupts::set_interrupt_line_priority`] for a /// platform interrupt line. /// /// The provided interrupt number must be greater than or equal to /// [`INTERRUPT_PLATFORM_START`]. /// /// [`PortInterrupts::set_interrupt_line_priority`]: r3::kernel::PortInterrupts::set_interrupt_line_priority unsafe fn set_interrupt_line_priority( _line: InterruptNum, _priority: InterruptPriority, ) -> Result<(), SetInterruptLinePriorityError> { Err(SetInterruptLinePriorityError::BadParam) } /// Handle the call to [`PortInterrupts::enable_interrupt_line`] for a /// platform interrupt line. /// /// The provided interrupt number must be greater than or equal to /// [`INTERRUPT_PLATFORM_START`]. /// /// [`PortInterrupts::enable_interrupt_line`]: r3::kernel::PortInterrupts::enable_interrupt_line unsafe fn enable_interrupt_line(_line: InterruptNum) -> Result<(), EnableInterruptLineError> { Err(EnableInterruptLineError::BadParam) } /// Handle the call to [`PortInterrupts::disable_interrupt_line`] for a /// platform interrupt line. /// /// The provided interrupt number must be greater than or equal to /// [`INTERRUPT_PLATFORM_START`]. /// /// [`PortInterrupts::disable_interrupt_line`]: r3::kernel::PortInterrupts::disable_interrupt_line unsafe fn disable_interrupt_line(_line: InterruptNum) -> Result<(), EnableInterruptLineError> { Err(EnableInterruptLineError::BadParam) } /// Handle the call to [`PortInterrupts::pend_interrupt_line`] for a /// platform interrupt line. /// /// The provided interrupt number must be greater than or equal to /// [`INTERRUPT_PLATFORM_START`]. /// /// [`PortInterrupts::pend_interrupt_line`]: r3::kernel::PortInterrupts::pend_interrupt_line unsafe fn pend_interrupt_line(_line: InterruptNum) -> Result<(), PendInterruptLineError> { Err(PendInterruptLineError::BadParam) } /// Handle the call to [`PortInterrupts::clear_interrupt_line`] for a /// platform interrupt line. /// /// The provided interrupt number must be greater than or equal to /// [`INTERRUPT_PLATFORM_START`]. /// /// [`PortInterrupts::clear_interrupt_line`]: r3::kernel::PortInterrupts::clear_interrupt_line unsafe fn clear_interrupt_line(_line: InterruptNum) -> Result<(), ClearInterruptLineError> { Err(ClearInterruptLineError::BadParam) } /// Handle the call to [`PortInterrupts::is_interrupt_line_pending`] for a /// platform interrupt line. /// /// The provided interrupt number must be greater than or equal to /// [`INTERRUPT_PLATFORM_START`]. /// /// [`PortInterrupts::is_interrupt_line_pending`]: r3::kernel::PortInterrupts::is_interrupt_line_pending unsafe fn is_interrupt_line_pending( _line: InterruptNum, ) -> Result<bool, QueryInterruptLineError> { Err(QueryInterruptLineError::BadParam) } }