define core1 stack in linker script
This commit is contained in:
parent
1c270a55e2
commit
3948021458
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue