feat: add mach_rpi3 target

This commit is contained in:
2021-10-14 19:20:51 +03:00
parent b440a3c975
commit 6bd252f18e
9 changed files with 231 additions and 7 deletions
@@ -0,0 +1,40 @@
use crate::dev::{Device, irq::{IntController, IntSource, IrqContext}};
use error::Errno;
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub struct IrqNumber(u32);
pub(super) struct Bcm283xIntController {}
impl Device for Bcm283xIntController {
fn name(&self) -> &'static str {
"BCM283x interrupt controller"
}
unsafe fn enable(&self) -> Result<(), Errno> {
Ok(())
}
}
impl IntController for Bcm283xIntController {
type IrqNumber = IrqNumber;
fn register_handler(&self, irq: IrqNumber, handler: &'static (dyn IntSource + Sync)) -> Result<(), Errno> {
todo!()
}
fn enable_irq(&self, irq: IrqNumber) -> Result<(), Errno> {
todo!()
}
fn handle_pending_irqs<'q>(&'q self, _ic: &IrqContext<'q>) {
todo!()
}
}
impl Bcm283xIntController {
pub const unsafe fn new() -> Self {
Self {}
}
}
+46
View File
@@ -0,0 +1,46 @@
#![allow(missing_docs)]
use crate::arch::aarch64::timer::GenericTimer;
use crate::dev::{irq::IntController, serial::SerialDevice, timer::TimestampSource, Device};
use crate::mem::phys;
use error::Errno;
mod irqchip;
use irqchip::Bcm283xIntController;
pub use irqchip::IrqNumber;
mod uart;
use uart::Bcm283xMiniUart;
pub fn init_board_early() -> Result<(), Errno> {
unsafe {
MUART.enable()?;
phys::init_from_region(0x0, 0x30000000);
}
Ok(())
}
pub fn init_board() -> Result<(), Errno> {
unsafe {
INTC.enable()?;
}
Ok(())
}
pub fn console() -> &'static impl SerialDevice {
&MUART
}
/// Returns the timer used as CPU-local periodic IRQ source
#[inline]
pub fn local_timer() -> &'static impl TimestampSource {
&LOCAL_TIMER
}
pub fn intc() -> &'static impl IntController<IrqNumber = IrqNumber> {
&INTC
}
static INTC: Bcm283xIntController = unsafe { Bcm283xIntController::new() };
static MUART: Bcm283xMiniUart = unsafe { Bcm283xMiniUart::new(0x3F215040) };
static LOCAL_TIMER: GenericTimer = GenericTimer {};
+67
View File
@@ -0,0 +1,67 @@
use crate::dev::{serial::SerialDevice, Device};
use crate::mem::virt::DeviceMemoryIo;
use crate::sync::IrqSafeNullLock;
use crate::util::InitOnce;
use error::Errno;
use tock_registers::{
interfaces::{ReadWriteable, Readable, Writeable},
register_bitfields, register_structs,
registers::{ReadOnly, ReadWrite, WriteOnly},
};
register_structs! {
Regs {
(0x00 => IO: ReadWrite<u32>),
(0x04 => @END),
}
}
pub(super) struct Bcm283xMiniUart {
regs: InitOnce<IrqSafeNullLock<DeviceMemoryIo<Regs>>>,
base: usize,
}
impl Device for Bcm283xMiniUart {
fn name(&self) -> &'static str {
"BCM283x Mini-UART"
}
unsafe fn enable(&self) -> Result<(), Errno> {
self.regs.init(IrqSafeNullLock::new(DeviceMemoryIo::map(
self.name(),
self.base,
1,
)?));
Ok(())
}
}
impl SerialDevice for Bcm283xMiniUart {
fn send(&self, byte: u8) -> Result<(), Errno> {
if !self.regs.is_initialized() {
return Ok(());
}
let regs = self.regs.get().lock();
regs.IO.set(byte as u32);
Ok(())
}
fn recv(&self, _blocking: bool) -> Result<u8, Errno> {
todo!()
}
}
impl Bcm283xMiniUart {
/// Constructs an instance of MiniUART device.
///
/// # Safety
///
/// Does not perform `base` validation.
pub const unsafe fn new(base: usize) -> Self {
Self {
regs: InitOnce::new(),
base,
}
}
}
+4
View File
@@ -18,6 +18,10 @@ cfg_if! {
pub mod mach_orangepi3;
pub use mach_orangepi3 as machine;
} else if #[cfg(feature = "mach_rpi3")] {
pub mod mach_rpi3;
pub use mach_rpi3 as machine;
}
}