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

boot: prepare core1 bootup

This commit is contained in:
Astro 2019-11-15 23:54:26 +01:00
parent 4a1d0fc0c3
commit 49901d1b8a
3 changed files with 75 additions and 6 deletions

View File

@ -1,6 +1,7 @@
use r0::zero_bss; use r0::zero_bss;
use crate::regs::{RegisterR, RegisterW}; use crate::regs::{RegisterR, RegisterW};
use crate::cortex_a9::{asm, regs::*, mmu}; use crate::cortex_a9::{asm, regs::*, mmu};
use crate::zynq::mpcore;
extern "C" { extern "C" {
static mut __bss_start: u32; static mut __bss_start: u32;
@ -8,6 +9,8 @@ extern "C" {
static mut __stack_start: u32; static mut __stack_start: u32;
} }
static mut CORE1_STACK: u32 = 0;
#[link_section = ".text.boot"] #[link_section = ".text.boot"]
#[no_mangle] #[no_mangle]
#[naked] #[naked]
@ -19,10 +22,19 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
SP.write(&mut __stack_start as *mut _ as u32); SP.write(&mut __stack_start as *mut _ as u32);
boot_core0(); boot_core0();
} }
_ => loop { 1 => {
// if not core0, infinitely wait for events // Wait for a first `sev` so that `CORE1_STACK` is cleared
// by `zero_bss()` on core 0.
asm::wfe(); asm::wfe();
},
while CORE1_STACK == 0 {
asm::wfe();
}
SP.write(CORE1_STACK);
boot_core1();
}
_ => unreachable!(),
} }
} }
@ -30,16 +42,37 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
#[inline(never)] #[inline(never)]
unsafe fn boot_core0() -> ! { unsafe fn boot_core0() -> ! {
l1_cache_init(); l1_cache_init();
let mpcore = mpcore::RegisterBlock::new();
mpcore.scu_invalidate.invalidate_all_cores();
zero_bss(&mut __bss_start, &mut __bss_end); zero_bss(&mut __bss_start, &mut __bss_end);
let mmu_table = mmu::L1Table::get() let mmu_table = mmu::L1Table::get()
.setup_flat_layout(); .setup_flat_layout();
mmu::with_mmu(mmu_table, || { mmu::with_mmu(mmu_table, || {
mpcore.scu_control.start();
crate::main(); crate::main();
panic!("return from main"); panic!("return from main");
}); });
} }
#[naked]
#[inline(never)]
unsafe fn boot_core1() -> ! {
l1_cache_init();
let mpcore = mpcore::RegisterBlock::new();
mpcore.scu_invalidate.invalidate_core1();
let mmu_table = mmu::L1Table::get();
mmu::with_mmu(mmu_table, || {
crate::main_core1();
panic!("return from main_core1");
});
}
fn l1_cache_init() { fn l1_cache_init() {
use crate::cortex_a9::cache::*; use crate::cortex_a9::cache::*;

View File

@ -10,6 +10,12 @@ pub fn wfe() {
unsafe { asm!("wfe" :::: "volatile") } unsafe { asm!("wfe" :::: "volatile") }
} }
/// Send Event
#[inline]
pub fn sev() {
unsafe { asm!("sev" :::: "volatile") }
}
/// Data Memory Barrier /// Data Memory Barrier
#[inline] #[inline]
pub fn dmb() { pub fn dmb() {

View File

@ -1,14 +1,15 @@
///! Register definitions for Application Processing Unit (mpcore) ///! Register definitions for Application Processing Unit (mpcore)
use volatile_register::{RO, RW, WO}; use volatile_register::{RO, RW};
use crate::{register, register_at, register_bit}; use crate::{register, register_at, register_bit, register_bits,
regs::RegisterW, regs::RegisterRW};
#[repr(C)] #[repr(C)]
pub struct RegisterBlock { pub struct RegisterBlock {
pub scu_control: ScuControl, pub scu_control: ScuControl,
pub scu_config: RO<u32>, pub scu_config: RO<u32>,
pub scu_cpu_power: RW<u32>, pub scu_cpu_power: RW<u32>,
pub scu_invalidate: WO<u32>, pub scu_invalidate: ScuInvalidate,
reserved0: [u32; 12], reserved0: [u32; 12],
pub filter_start: RW<u32>, pub filter_start: RW<u32>,
pub filter_end: RW<u32>, pub filter_end: RW<u32>,
@ -27,3 +28,32 @@ register_bit!(scu_control, scu_speculative_linefill_enable, 3);
register_bit!(scu_control, scu_rams_parity_enable, 2); register_bit!(scu_control, scu_rams_parity_enable, 2);
register_bit!(scu_control, address_filtering_enable, 1); register_bit!(scu_control, address_filtering_enable, 1);
register_bit!(scu_control, enable, 0); register_bit!(scu_control, enable, 0);
impl ScuControl {
pub fn start(&mut self) {
self.modify(|_, w| w.enable(true));
}
}
register!(scu_invalidate, ScuInvalidate, WO, u32);
register_bits!(scu_invalidate, cpu0_ways, u8, 0, 3);
register_bits!(scu_invalidate, cpu1_ways, u8, 4, 7);
register_bits!(scu_invalidate, cpu2_ways, u8, 8, 11);
register_bits!(scu_invalidate, cpu3_ways, u8, 12, 15);
impl ScuInvalidate {
pub fn invalidate_all_cores(&mut self) {
self.write(ScuInvalidate::zeroed()
.cpu0_ways(0xf)
.cpu1_ways(0xf)
.cpu2_ways(0xf)
.cpu3_ways(0xf)
);
}
pub fn invalidate_core1(&mut self) {
self.write(ScuInvalidate::zeroed()
.cpu1_ways(0xf)
);
}
}