Compare commits
No commits in common. "b6596d930deb4c1155ab9558ab721f8319325bdb" and "50481b3a805e6b1600bb6e2ec3ce6c64bd5731fa" have entirely different histories.
b6596d930d
...
50481b3a80
48
src/boot.rs
48
src/boot.rs
|
@ -1,7 +1,6 @@
|
||||||
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;
|
||||||
|
@ -9,8 +8,6 @@ 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]
|
||||||
|
@ -22,19 +19,10 @@ 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();
|
||||||
}
|
}
|
||||||
1 => {
|
_ => loop {
|
||||||
// Wait for a first `sev` so that `CORE1_STACK` is cleared
|
// if not core0, infinitely wait for events
|
||||||
// by `zero_bss()` on core 0.
|
|
||||||
asm::wfe();
|
asm::wfe();
|
||||||
|
},
|
||||||
while CORE1_STACK == 0 {
|
|
||||||
asm::wfe();
|
|
||||||
}
|
|
||||||
|
|
||||||
SP.write(CORE1_STACK);
|
|
||||||
boot_core1();
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,46 +30,16 @@ 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();
|
|
||||||
ACTLR.enable_smp();
|
|
||||||
// TODO: Barriers reqd when core1 is not yet starting?
|
|
||||||
asm::dmb();
|
|
||||||
asm::dsb();
|
|
||||||
|
|
||||||
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, || {
|
|
||||||
ACTLR.enable_smp();
|
|
||||||
// TODO: Barriers reqd when core1 is not yet starting?
|
|
||||||
asm::dmb();
|
|
||||||
asm::dsb();
|
|
||||||
|
|
||||||
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::*;
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,6 @@ 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() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{register_bit, register_bits};
|
use crate::{register_bit, register_bits};
|
||||||
use crate::regs::{RegisterR, RegisterW, RegisterRW};
|
use crate::regs::{RegisterR, RegisterW};
|
||||||
|
|
||||||
macro_rules! def_reg_r {
|
macro_rules! def_reg_r {
|
||||||
($name:tt, $type: ty, $asm_instr:tt) => {
|
($name:tt, $type: ty, $asm_instr:tt) => {
|
||||||
|
@ -115,36 +115,6 @@ register_bit!(sctlr,
|
||||||
/// Thumb Exception Enable
|
/// Thumb Exception Enable
|
||||||
te, 30);
|
te, 30);
|
||||||
|
|
||||||
/// Auxiliary Control Register
|
|
||||||
pub struct ACTLR;
|
|
||||||
wrap_reg!(actlr);
|
|
||||||
def_reg_r!(ACTLR, actlr::Read, "mrc p15, 0, $0, c1, c0, 1");
|
|
||||||
def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, $0, c1, c0, 1");
|
|
||||||
// SMP bit
|
|
||||||
register_bit!(actlr, parity_on, 9);
|
|
||||||
register_bit!(actlr, alloc_one_way, 8);
|
|
||||||
register_bit!(actlr, excl, 7);
|
|
||||||
register_bit!(actlr, smp, 6);
|
|
||||||
register_bit!(actlr, write_full_line_of_zeros, 3);
|
|
||||||
register_bit!(actlr, l1_prefetch_enable, 2);
|
|
||||||
// Cache/TLB maintenance broadcast
|
|
||||||
register_bit!(actlr, fw, 0);
|
|
||||||
|
|
||||||
impl RegisterRW for ACTLR {
|
|
||||||
fn modify<F: FnOnce(Self::R, Self::W) -> Self::W>(&mut self, f: F) {
|
|
||||||
let r = self.read();
|
|
||||||
let w = actlr::Write { inner: r.inner };
|
|
||||||
let w = f(r, w);
|
|
||||||
self.write(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ACTLR {
|
|
||||||
pub fn enable_smp(&mut self) {
|
|
||||||
self.modify(|_, w| w.smp(true).fw(true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Domain Access Control Register
|
/// Domain Access Control Register
|
||||||
pub struct DACR;
|
pub struct DACR;
|
||||||
def_reg_r!(DACR, u32, "mrc p15, 0, $0, c3, c0, 0");
|
def_reg_r!(DACR, u32, "mrc p15, 0, $0, c3, c0, 0");
|
||||||
|
|
|
@ -5,4 +5,3 @@ pub mod eth;
|
||||||
pub mod axi_hp;
|
pub mod axi_hp;
|
||||||
pub mod axi_gp;
|
pub mod axi_gp;
|
||||||
pub mod ddr;
|
pub mod ddr;
|
||||||
pub mod mpcore;
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
///! Register definitions for Application Processing Unit (mpcore)
|
|
||||||
|
|
||||||
use volatile_register::{RO, RW};
|
|
||||||
use crate::{register, register_at, register_bit, register_bits,
|
|
||||||
regs::RegisterW, regs::RegisterRW};
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct RegisterBlock {
|
|
||||||
pub scu_control: ScuControl,
|
|
||||||
pub scu_config: RO<u32>,
|
|
||||||
pub scu_cpu_power: RW<u32>,
|
|
||||||
pub scu_invalidate: ScuInvalidate,
|
|
||||||
reserved0: [u32; 12],
|
|
||||||
pub filter_start: RW<u32>,
|
|
||||||
pub filter_end: RW<u32>,
|
|
||||||
reserved1: [u32; 2],
|
|
||||||
pub scu_access_control: RW<u32>,
|
|
||||||
pub scu_non_secure_access_control: RW<u32>,
|
|
||||||
// there is plenty more (unimplemented)
|
|
||||||
}
|
|
||||||
register_at!(RegisterBlock, 0xF8F00000, new);
|
|
||||||
|
|
||||||
register!(scu_control, ScuControl, RW, u32);
|
|
||||||
register_bit!(scu_control, ic_standby_enable, 6);
|
|
||||||
register_bit!(scu_control, scu_standby_enable, 5);
|
|
||||||
register_bit!(scu_control, force_to_port0_enable, 4);
|
|
||||||
register_bit!(scu_control, scu_speculative_linefill_enable, 3);
|
|
||||||
register_bit!(scu_control, scu_rams_parity_enable, 2);
|
|
||||||
register_bit!(scu_control, address_filtering_enable, 1);
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue