diff --git a/target/ast10x0/BUILD.bazel b/target/ast10x0/BUILD.bazel index 0255c5b..4e93bf1 100644 --- a/target/ast10x0/BUILD.bazel +++ b/target/ast10x0/BUILD.bazel @@ -81,6 +81,7 @@ rust_library( tags = ["kernel"], target_compatible_with = TARGET_COMPATIBLE_WITH, deps = [ + "@ast1060_pac", "@pigweed//pw_kernel/arch/arm_cortex_m:arch_arm_cortex_m", "@pigweed//pw_kernel/kernel", "@pigweed//pw_status/rust:pw_status", diff --git a/target/ast10x0/entry.rs b/target/ast10x0/entry.rs index dff6438..f9fd412 100644 --- a/target/ast10x0/entry.rs +++ b/target/ast10x0/entry.rs @@ -10,11 +10,14 @@ use arch_arm_cortex_m::Arch; #[cfg(feature = "jtag-halt")] use core::ptr::{self, addr_of}; -/// Pre-kernel hardware initialization -/// Runs before RAM is initialized, before main() #[cfg(feature = "jtag-halt")] -#[cortex_m_rt::pre_init] -unsafe fn pre_kernel_init() { +/// Enable ARM JTAG pins via SCU pinmux and halt waiting for a debugger. +/// +/// # Safety +/// Caller must have exclusive early-boot ownership of SCU MMIO and must have +/// already unlocked SCU write protection (write `0x1688_A8A8` to `SCU000`); +/// otherwise the `SCU41C` pinmux write is silently dropped. +unsafe fn jtag_init() { // Enable JTAG pins via SCU pinmux - must happen very early // Scu::steal() is safe here: it's a zero-sized type with no RAM allocation let scu = unsafe { ast1060_pac::Scu::steal() }; @@ -43,6 +46,48 @@ unsafe fn pre_kernel_init() { } } } +/// Configure and enable the AST10x0 instruction/data cache. +/// +/// Sequence: disable cache, program the cacheable area, invalidate, re-enable. +/// +/// # Safety +/// Caller must have exclusive early-boot ownership of SCU MMIO and must have +/// already unlocked SCU write protection. +unsafe fn init_cache() { + // SAFETY: see function-level safety contract. + let scu = unsafe { &*ast1060_pac::Scu::ptr() }; + + // Disable cache. + scu.scua58().write(|w| unsafe { w.bits(0) }); + + // Configure cache area. + scu.scua50().write(|w| unsafe { w.bits(0x000f_ffff) }); + + // Invalidate cache. + scu.scua54().write(|w| unsafe { w.bits(0x8660_0000) }); + + // Re-enable cache. + scu.scua58().write(|w| unsafe { w.bits(1) }); +} + +// Pre-kernel hardware initialization +/// Runs before RAM is initialized, before main() +#[cortex_m_rt::pre_init] +unsafe fn pre_init() { + // SAFETY: pre-init has exclusive early-boot ownership of SCU MMIO. + let scu = unsafe { &*ast1060_pac::Scu::ptr() }; + + // Unlock SCU write-protected registers. + scu.scu000().write(|w| unsafe { w.bits(0x1688_A8A8) }); + + #[cfg(feature = "jtag-halt")] + jtag_init(); + + // SAFETY: SCU is unlocked above; pre-init has exclusive ownership. + unsafe { init_cache() }; +} + + #[unsafe(no_mangle)] #[allow(non_snake_case)]