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 = .;
} > 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");

View File

@ -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");

View File

@ -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<u32> = VolatileCell::new(0);
static mut CORE1_ENABLED: VolatileCell<bool> = 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<S: AsMut<[u32]>> {
pub stack: S,
pub struct Core1 {
}
impl<S: AsMut<[u32]>> Core1<S> {
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<S: AsMut<[u32]>> Core1<S> {
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<S: AsMut<[u32]>> Core1<S> {
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();
}