diff --git a/Cargo.toml b/Cargo.toml index f6e3205950248362183acdc2257dcf28969a388c..e5b46db9f4e11cc89854516c5dccdb4e6ccc375e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,13 +20,13 @@ memoffset = "0.8.0" [features] default = ["rom-peripherals"] # BL616 and BL618 chip series. -bl616 = ["bl-soc/bl616", "bl-rom-rt-macros/bl616", "dep:base-address"] +bl616 = ["bl-soc/bl616", "bl-rom-rt-macros/bl616"] # BL808 chip. -bl808-mcu = ["bl-soc/bl808", "bl-rom-rt-macros/bl808-mcu", "dep:base-address"] -bl808-dsp = ["bl-soc/bl808", "bl-rom-rt-macros/bl808-dsp", "dep:base-address"] -bl808-lp = ["bl-soc/bl808", "bl-rom-rt-macros/bl808-lp", "dep:base-address"] +bl808-mcu = ["bl-soc/bl808", "bl-rom-rt-macros/bl808-mcu"] +bl808-dsp = ["bl-soc/bl808", "bl-rom-rt-macros/bl808-dsp"] +bl808-lp = ["bl-soc/bl808", "bl-rom-rt-macros/bl808-lp"] # BL702, BL704 and BL706 chip series. -bl702 = ["bl-soc/bl702", "bl-rom-rt-macros/bl702", "dep:base-address"] +bl702 = ["bl-soc/bl702", "bl-rom-rt-macros/bl702"] # Provide ROM peripherals on #[entry] function. rom-peripherals = ["bl-rom-rt-macros/rom-peripherals", "dep:bl-soc", "dep:base-address", "dep:embedded-time"] diff --git a/src/soc/bl808.rs b/src/soc/bl808.rs index bf56e98b4a74cf2ad778a622df2b58df18a9bfc6..6aa0cb0c5b88349063db1ec607a03a1e75217ff0 100644 --- a/src/soc/bl808.rs +++ b/src/soc/bl808.rs @@ -5,8 +5,7 @@ use crate::{HalBasicConfig, HalFlashConfig, HalPatchCfg}; #[cfg(any(feature = "bl808-mcu", feature = "bl808-dsp"))] use {crate::Stack, core::arch::asm}; -// TODO: restore #[cfg(feature = "rom-peripherals")] once nested interrupt on BL808 DSP is supported. -#[allow(unused)] +#[cfg(feature = "rom-peripherals")] use base_address::Static; #[cfg(feature = "bl808-mcu")] @@ -152,6 +151,7 @@ unsafe extern "C" fn reserved() -> ! { #[naked] unsafe extern "C" fn machine_external() -> ! { asm!( + // save context "addi sp, sp, -19*8", "sd ra, 0*8(sp)", "sd t0, 1*8(sp)", @@ -175,9 +175,18 @@ unsafe extern "C" fn machine_external() -> ! { "sd t1, 17*8(sp)", "csrr t2, mstatus", "sd t2, 18*8(sp)", - // "csrs mstatus, 8", // TODO: disallow nested interrupt by now - "mv a0, sp", + // fetch plic interrupt number + "li t3, {plic_context_d0_machine_claim_complete}", + "lw a0, 0(t3)", + // allow nested interrupt by setting mstatus.MIE + "csrs mstatus, 8", + // call trap handler + "mv a1, sp", "call {rust_all_traps}", + // complete plic interrupt + "li t3, {plic_context_d0_machine_claim_complete}", + "sw a0, 0(t3)", + // restore context "ld t0, 16*8(sp)", "csrw mcause, t0", "ld t1, 17*8(sp)", @@ -202,21 +211,18 @@ unsafe extern "C" fn machine_external() -> ! { "ld t6, 15*8(sp)", "addi sp, sp, 19*8", "mret", + plic_context_d0_machine_claim_complete = const 0xE0200004_u32, rust_all_traps = sym rust_bl808_dsp_machine_external, options(noreturn) ) } #[cfg(feature = "bl808-dsp")] -fn rust_bl808_dsp_machine_external(_tf: &mut TrapFrame) { - let plic: PLIC> = unsafe { core::mem::transmute(()) }; - if let Some(source) = plic.claim(D0Machine) { - let idx = source.get() as usize; - if idx >= 16 && idx < 16 + 67 { - unsafe { (D0_INTERRUPT_HANDLERS[idx - 16])() }; - } - plic.complete(D0Machine, PlicSource(source)); +fn rust_bl808_dsp_machine_external(source: u32, _tf: &mut TrapFrame) -> u32 { + if source >= 16 && source < 16 + 67 { + unsafe { (D0_INTERRUPT_HANDLERS[source as usize - 16])() }; } + source } #[cfg(feature = "bl808-dsp")] @@ -380,6 +386,86 @@ impl plic::InterruptSource for PlicSource { } } +/// DSP core PLIC interrupt source. +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[repr(u32)] +pub enum DspInterrupt { + BmxDspBusErr = 16, + DspReserved1 = 17, + DspReserved2 = 18, + DspReserved3 = 19, + Uart3 = 20, + I2c2 = 21, + I2c3 = 22, + Spi1 = 23, + DspReserved4 = 24, + DspReserved5 = 25, + SeofInt0 = 26, + SeofInt1 = 27, + SeofInt2 = 28, + Dvp2BusInt0 = 29, + Dvp2BusInt1 = 30, + Dvp2BusInt2 = 31, + Dvp2BusInt3 = 32, + H264Bs = 33, + H264Frame = 34, + H264SeqDone = 35, + Mjpeg = 36, + H264SBs = 37, + H264SFrame = 38, + H264SSeqDone = 39, + Dma2Int0 = 40, + Dma2Int1 = 41, + Dma2Int2 = 42, + Dma2Int3 = 43, + Dma2Int4 = 44, + Dma2Int5 = 45, + Dma2Int6 = 46, + Dma2Int7 = 47, + DspReserved6 = 48, + DspReserved7 = 49, + DspReserved8 = 50, + DspReserved9 = 51, + DspReserved10 = 52, + MipiCsi = 53, + IpcD0 = 54, + DspReserved11 = 55, + Mjdec = 56, + Dvp2BusInt4 = 57, + Dvp2BusInt5 = 58, + Dvp2BusInt6 = 59, + Dvp2BusInt7 = 60, + Dma2DInt0 = 61, + Dma2DInt1 = 62, + Display = 63, + Pwm = 64, + SeofInt3 = 65, + DspReserved12 = 66, + DspReserved13 = 67, + Osd = 68, + Dbi = 69, + DspReserved14 = 70, + OsdaBusDrain = 71, + OsdbBusDrain = 72, + OsdPb = 73, + DspReserved15 = 74, + MipiDsi = 75, + DspReserved16 = 76, + Timer0 = 77, + Timer1 = 78, + Wdt = 79, + Audio = 80, + WlAll = 81, + Pds = 82, +} + +impl plic::InterruptSource for DspInterrupt { + #[inline] + fn id(self) -> core::num::NonZeroU32 { + core::num::NonZeroU32::new(self as u32).unwrap() + } +} + /// Trap stack frame. #[repr(C)] pub struct TrapFrame { @@ -706,12 +792,15 @@ pub struct Peripherals { } /// Platform-local Interrupt Controller. +#[cfg(feature = "rom-peripherals")] pub struct PLIC { base: A, } +#[cfg(feature = "rom-peripherals")] unsafe impl Send for PLIC {} +#[cfg(feature = "rom-peripherals")] impl core::ops::Deref for PLIC { type Target = plic::Plic;