forked from M-Labs/zynq-rs
1
0
Fork 0

define core1 stack in linker script

This commit is contained in:
Sebastien Bourdeauducq 2020-04-28 19:31:49 +08:00
parent 1c270a55e2
commit 3948021458
3 changed files with 24 additions and 38 deletions

View File

@ -46,10 +46,16 @@ SECTIONS
__bss_end = .; __bss_end = .;
} > OCM } > OCM
.stack (NOLOAD) : ALIGN(8) { .stack1 (NOLOAD) : ALIGN(8) {
__stack_end = .; __stack1_end = .;
. += 0x200;
__stack1_start = .;
} > OCM
.stack0 (NOLOAD) : ALIGN(8) {
__stack0_end = .;
. = ORIGIN(OCM) + LENGTH(OCM) - 8; . = ORIGIN(OCM) + LENGTH(OCM) - 8;
__stack_start = .; __stack0_start = .;
} > OCM } > OCM
/DISCARD/ : /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");

View File

@ -32,8 +32,6 @@ mod ps7_init;
const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
static mut STACK_CORE1: [u32; 512] = [0; 512];
#[no_mangle] #[no_mangle]
pub fn main_core0() { pub fn main_core0() {
// zynq::clocks::CpuClocks::enable_io(1_250_000_000); // zynq::clocks::CpuClocks::enable_io(1_250_000_000);
@ -143,9 +141,7 @@ pub fn main_core0() {
tx.async_send(None).await; tx.async_send(None).await;
}); });
let core1_stack = unsafe { &mut STACK_CORE1[..] }; let core1 = boot::Core1::start();
println!("{} bytes stack for core1", core1_stack.len());
let core1 = boot::Core1::start(core1_stack);
let (mut core1_req, rx) = sync_channel(10); let (mut core1_req, rx) = sync_channel(10);
*CORE1_REQ.lock() = Some(rx); *CORE1_REQ.lock() = Some(rx);
@ -160,13 +156,6 @@ pub fn main_core0() {
}); });
core1.disable(); 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()); let eth = zynq::eth::Eth::default(HWADDR.clone());
println!("Eth on"); println!("Eth on");

View File

@ -9,13 +9,13 @@ use libboard_zynq::{slcr, mpcore};
extern "C" { extern "C" {
static mut __bss_start: u32; static mut __bss_start: u32;
static mut __bss_end: 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_core0();
fn main_core1(); fn main_core1();
} }
/// `0` means: wait for initialization by core0 static mut CORE1_ENABLED: VolatileCell<bool> = VolatileCell::new(false);
static mut CORE1_STACK: VolatileCell<u32> = VolatileCell::new(0);
#[link_section = ".text.boot"] #[link_section = ".text.boot"]
#[no_mangle] #[no_mangle]
@ -25,15 +25,14 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
match MPIDR.read() & CORE_MASK { match MPIDR.read() & CORE_MASK {
0 => { 0 => {
SP.write(&mut __stack_start as *mut _ as u32); SP.write(&mut __stack0_start as *mut _ as u32);
boot_core0(); boot_core0();
} }
1 => { 1 => {
while CORE1_STACK.get() == 0 { while !CORE1_ENABLED.get() {
asm::wfe(); asm::wfe();
} }
SP.write(&mut __stack1_start as *mut _ as u32);
SP.write(CORE1_STACK.get());
boot_core1(); boot_core1();
} }
_ => unreachable!(), _ => unreachable!(),
@ -104,18 +103,12 @@ fn l1_cache_init() {
dciall(); dciall();
} }
pub struct Core1<S: AsMut<[u32]>> { pub struct Core1 {
pub stack: S,
} }
impl<S: AsMut<[u32]>> Core1<S> { impl Core1 {
/// Reset and start core1 /// Reset and start core1
/// pub fn start() -> Self {
/// 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 };
// reset and stop (safe to repeat) // reset and stop (safe to repeat)
slcr::RegisterBlock::unlocked(|slcr| { slcr::RegisterBlock::unlocked(|slcr| {
slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_rst1(true)); slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_rst1(true));
@ -123,15 +116,13 @@ impl<S: AsMut<[u32]>> Core1<S> {
slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_rst1(false)); 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 { unsafe {
CORE1_STACK.set(stack_start as *mut _ as u32); CORE1_ENABLED.set(true);
} }
// Ensure stack pointer has been written to cache // Ensure stack pointer has been written to cache
asm::dmb(); asm::dmb();
// Flush cache-line // Flush cache-line
cache::dccmvac(unsafe { &CORE1_STACK } as *const _ as usize); cache::dccmvac(unsafe { &CORE1_ENABLED } as *const _ as usize);
// wake up core1 // wake up core1
slcr::RegisterBlock::unlocked(|slcr| { slcr::RegisterBlock::unlocked(|slcr| {
@ -139,12 +130,12 @@ impl<S: AsMut<[u32]>> Core1<S> {
slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_clkstop1(false)); slcr.a9_cpu_rst_ctrl.modify(|_, w| w.a9_clkstop1(false));
}); });
core Core1 {}
} }
pub fn disable(&self) { pub fn disable(&self) {
unsafe { unsafe {
CORE1_STACK.set(0); CORE1_ENABLED.set(false);
} }
self.restart(); self.restart();
} }