diff --git a/experiments/link.x b/experiments/link.x index 179ca53..6bda2a5 100644 --- a/experiments/link.x +++ b/experiments/link.x @@ -46,10 +46,16 @@ SECTIONS __bss_end = .; } > OCM - .stack (NOLOAD) : ALIGN(8) { - __stack_end = .; + .stack1 (NOLOAD) : ALIGN(8) { + __stack1_end = .; + . += 0x200; + __stack1_start = .; + } > OCM + + .stack0 (NOLOAD) : ALIGN(8) { + __stack0_end = .; . = ORIGIN(OCM) + LENGTH(OCM) - 8; - __stack_start = .; + __stack0_start = .; } > OCM /DISCARD/ : @@ -61,4 +67,4 @@ SECTIONS } } -ASSERT(SIZEOF(.stack) >= 0x8000, "less than 32 KB left for stack"); +ASSERT(SIZEOF(.stack0) >= 0x8000, "less than 32 KB left for stack"); diff --git a/experiments/src/main.rs b/experiments/src/main.rs index 67adb77..843ee7c 100644 --- a/experiments/src/main.rs +++ b/experiments/src/main.rs @@ -32,8 +32,6 @@ mod ps7_init; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; -static mut STACK_CORE1: [u32; 512] = [0; 512]; - #[no_mangle] pub fn main_core0() { // zynq::clocks::CpuClocks::enable_io(1_250_000_000); @@ -143,9 +141,7 @@ pub fn main_core0() { tx.async_send(None).await; }); - let core1_stack = unsafe { &mut STACK_CORE1[..] }; - println!("{} bytes stack for core1", core1_stack.len()); - let core1 = boot::Core1::start(core1_stack); + let core1 = boot::Core1::start(); let (mut core1_req, rx) = sync_channel(10); *CORE1_REQ.lock() = Some(rx); @@ -160,13 +156,6 @@ pub fn main_core0() { }); core1.disable(); - libcortex_a9::asm::dsb(); - print!("Core1 stack [{:08X}..{:08X}]:", &core1.stack[0] as *const _ as u32, &core1.stack[core1.stack.len() - 1] as *const _ as u32); - for w in core1.stack { - print!(" {:08X}", w); - } - println!("."); - let eth = zynq::eth::Eth::default(HWADDR.clone()); println!("Eth on"); diff --git a/libsupport_zynq/src/boot.rs b/libsupport_zynq/src/boot.rs index 0d12269..507ad66 100644 --- a/libsupport_zynq/src/boot.rs +++ b/libsupport_zynq/src/boot.rs @@ -9,13 +9,13 @@ use libboard_zynq::{slcr, mpcore}; extern "C" { static mut __bss_start: u32; static mut __bss_end: u32; - static mut __stack_start: u32; + static mut __stack0_start: u32; + static mut __stack1_start: u32; fn main_core0(); fn main_core1(); } -/// `0` means: wait for initialization by core0 -static mut CORE1_STACK: VolatileCell = VolatileCell::new(0); +static mut CORE1_ENABLED: VolatileCell = VolatileCell::new(false); #[link_section = ".text.boot"] #[no_mangle] @@ -25,15 +25,14 @@ pub unsafe extern "C" fn _boot_cores() -> ! { match MPIDR.read() & CORE_MASK { 0 => { - SP.write(&mut __stack_start as *mut _ as u32); + SP.write(&mut __stack0_start as *mut _ as u32); boot_core0(); } 1 => { - while CORE1_STACK.get() == 0 { + while !CORE1_ENABLED.get() { asm::wfe(); } - - SP.write(CORE1_STACK.get()); + SP.write(&mut __stack1_start as *mut _ as u32); boot_core1(); } _ => unreachable!(), @@ -104,18 +103,12 @@ fn l1_cache_init() { dciall(); } -pub struct Core1> { - pub stack: S, +pub struct Core1 { } -impl> Core1 { +impl Core1 { /// Reset and start core1 - /// - /// The stack must be in OCM because core1 still has to - /// initialize its MMU before it can access DDR. - pub fn start(stack: S) -> Self { - let mut core = Core1 { stack }; - + pub fn start() -> Self { // reset and stop (safe to repeat) slcr::RegisterBlock::unlocked(|slcr| { slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_rst1(true)); @@ -123,15 +116,13 @@ impl> Core1 { slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_rst1(false)); }); - let stack = core.stack.as_mut(); - let stack_start = &mut stack[stack.len() - 1]; unsafe { - CORE1_STACK.set(stack_start as *mut _ as u32); + CORE1_ENABLED.set(true); } // Ensure stack pointer has been written to cache asm::dmb(); // Flush cache-line - cache::dccmvac(unsafe { &CORE1_STACK } as *const _ as usize); + cache::dccmvac(unsafe { &CORE1_ENABLED } as *const _ as usize); // wake up core1 slcr::RegisterBlock::unlocked(|slcr| { @@ -139,12 +130,12 @@ impl> Core1 { slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_clkstop1(false)); }); - core + Core1 {} } pub fn disable(&self) { unsafe { - CORE1_STACK.set(0); + CORE1_ENABLED.set(false); } self.restart(); }