l2 cache init now done in user app #7
@@ -15,6 +15,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{Flex, Output, PinState, mio},
|
gpio::{Flex, Output, PinState, mio},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
@@ -43,7 +44,9 @@ const OPEN_DRAIN_PINS_MIO9_TO_MIO14: bool = false;
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
let dp = PsPeripherals::take().unwrap();
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -16,6 +16,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{Output, PinState, mio},
|
gpio::{Output, PinState, mio},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, TxAsync, Uart, UartConfig, on_interrupt_tx},
|
uart::{ClkConfigRaw, TxAsync, Uart, UartConfig, on_interrupt_tx},
|
||||||
};
|
};
|
||||||
@@ -37,7 +38,9 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) -> ! {
|
async fn main(spawner: Spawner) -> ! {
|
||||||
let dp = PsPeripherals::take().unwrap();
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -21,6 +21,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{Output, PinState, mio},
|
gpio::{Output, PinState, mio},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
@@ -43,7 +44,9 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
let dp = PsPeripherals::take().unwrap();
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -14,6 +14,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{Output, PinState, mio},
|
gpio::{Output, PinState, mio},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
@@ -33,11 +34,12 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: The export name is ignored..
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
let dp = PsPeripherals::take().unwrap();
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -12,6 +12,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{Output, PinState, mio},
|
gpio::{Output, PinState, mio},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
@@ -35,7 +36,9 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
|
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
pub fn main() -> ! {
|
pub fn main() -> ! {
|
||||||
let dp = zynq7000::PsPeripherals::take().unwrap();
|
let mut dp = zynq7000::PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -13,6 +13,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{Output, PinState, mio},
|
gpio::{Output, PinState, mio},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
@@ -36,7 +37,9 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
|
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
pub fn main() -> ! {
|
pub fn main() -> ! {
|
||||||
let dp = zynq7000::PsPeripherals::take().unwrap();
|
let mut dp = zynq7000::PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -6,7 +6,10 @@ use core::panic::PanicInfo;
|
|||||||
use cortex_ar::asm::nop;
|
use cortex_ar::asm::nop;
|
||||||
use embedded_hal::digital::StatefulOutputPin;
|
use embedded_hal::digital::StatefulOutputPin;
|
||||||
use zynq7000::PsPeripherals;
|
use zynq7000::PsPeripherals;
|
||||||
use zynq7000_hal::gpio::{Output, PinState, mio};
|
use zynq7000_hal::{
|
||||||
|
gpio::{Output, PinState, mio},
|
||||||
|
l2_cache,
|
||||||
|
};
|
||||||
use zynq7000_rt as _;
|
use zynq7000_rt as _;
|
||||||
|
|
||||||
/// One user LED is MIO7
|
/// One user LED is MIO7
|
||||||
@@ -31,6 +34,7 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
|
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
pub fn main() -> ! {
|
pub fn main() -> ! {
|
||||||
|
l2_cache::init_with_defaults(&mut unsafe { zynq7000::l2_cache::L2Cache::new_mmio_fixed() });
|
||||||
match LIB {
|
match LIB {
|
||||||
Lib::Pac => {
|
Lib::Pac => {
|
||||||
let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio_fixed() };
|
let mut gpio = unsafe { zynq7000::gpio::Gpio::new_mmio_fixed() };
|
||||||
|
@@ -48,6 +48,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -208,14 +209,17 @@ async fn tcp_task(mut tcp: TcpSocket<'static>) -> ! {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(spawner: Spawner) -> ! {
|
async fn main(spawner: Spawner) -> ! {
|
||||||
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
|
// Enable PS-PL level shifters.
|
||||||
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
|
|
||||||
// Configure the uncached memory region using the MMU.
|
// Configure the uncached memory region using the MMU.
|
||||||
mmu_l1_table_mut()
|
mmu_l1_table_mut()
|
||||||
.update(UNCACHED_ADDR, SHAREABLE_DEVICE)
|
.update(UNCACHED_ADDR, SHAREABLE_DEVICE)
|
||||||
.expect("configuring uncached memory section failed");
|
.expect("configuring uncached memory section failed");
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
|
||||||
configure_level_shifter(LevelShifterConfig::EnableAll);
|
|
||||||
let dp = PsPeripherals::take().unwrap();
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -24,7 +24,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
i2c,
|
i2c, l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart,
|
uart,
|
||||||
};
|
};
|
||||||
@@ -48,9 +48,12 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterConfig::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
let dp = PsPeripherals::take().unwrap();
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
spi::{self, SpiAsync, SpiId, SpiWithHwCs, SpiWithHwCsAsync, on_interrupt},
|
spi::{self, SpiAsync, SpiId, SpiWithHwCs, SpiWithHwCsAsync, on_interrupt},
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{self, TxAsync, on_interrupt_tx},
|
uart::{self, TxAsync, on_interrupt_tx},
|
||||||
@@ -50,9 +51,12 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(spawner: Spawner) -> ! {
|
async fn main(spawner: Spawner) -> ! {
|
||||||
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterConfig::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
let dp = PsPeripherals::take().unwrap();
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let mut clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let mut clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,9 +101,11 @@ impl UartMultiplexer {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterConfig::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
let dp = PsPeripherals::take().unwrap();
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -45,6 +45,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
time::Hertz,
|
time::Hertz,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
@@ -165,9 +166,12 @@ impl UartMultiplexer {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(spawner: Spawner) -> ! {
|
async fn main(spawner: Spawner) -> ! {
|
||||||
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterConfig::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
let dp = PsPeripherals::take().unwrap();
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -16,6 +16,7 @@ use zynq7000_hal::{
|
|||||||
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
gic::{GicConfigurator, GicInterruptHelper, Interrupt},
|
||||||
gpio::{GpioPins, Output, PinState},
|
gpio::{GpioPins, Output, PinState},
|
||||||
gtc::Gtc,
|
gtc::Gtc,
|
||||||
|
l2_cache,
|
||||||
uart::{ClkConfigRaw, Uart, UartConfig},
|
uart::{ClkConfigRaw, Uart, UartConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -36,9 +37,12 @@ pub extern "C" fn boot_core(cpu_id: u32) -> ! {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
#[unsafe(export_name = "main")]
|
#[unsafe(export_name = "main")]
|
||||||
async fn main(_spawner: Spawner) -> ! {
|
async fn main(_spawner: Spawner) -> ! {
|
||||||
|
let mut dp = PsPeripherals::take().unwrap();
|
||||||
|
l2_cache::init_with_defaults(&mut dp.l2c);
|
||||||
|
|
||||||
// Enable PS-PL level shifters.
|
// Enable PS-PL level shifters.
|
||||||
configure_level_shifter(LevelShifterConfig::EnableAll);
|
configure_level_shifter(LevelShifterConfig::EnableAll);
|
||||||
let dp = PsPeripherals::take().unwrap();
|
|
||||||
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
// Clock was already initialized by PS7 Init TCL script or FSBL, we just read it.
|
||||||
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
let clocks = Clocks::new_from_regs(PS_CLOCK_FREQUENCY).unwrap();
|
||||||
// Set up the global interrupt controller.
|
// Set up the global interrupt controller.
|
||||||
|
@@ -29,7 +29,7 @@ pub fn clean_and_invalidate_data_cache() {
|
|||||||
|
|
||||||
// Clean all ways in L2 cache.
|
// Clean all ways in L2 cache.
|
||||||
let mut l2c = unsafe { L2Cache::new_mmio_fixed() };
|
let mut l2c = unsafe { L2Cache::new_mmio_fixed() };
|
||||||
l2c.write_clean_invalidate_by_way(0xff);
|
l2c.write_clean_invalidate_by_way(0xffff);
|
||||||
while l2c.read_cache_sync().busy() {}
|
while l2c.read_cache_sync().busy() {}
|
||||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
|
81
zynq7000-hal/src/l2_cache.rs
Normal file
81
zynq7000-hal/src/l2_cache.rs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
use core::sync::atomic::compiler_fence;
|
||||||
|
|
||||||
|
use arbitrary_int::{u2, u3};
|
||||||
|
pub use zynq7000::l2_cache::LatencyConfig;
|
||||||
|
use zynq7000::l2_cache::{
|
||||||
|
Associativity, AuxControl, Control, InterruptControl, MmioL2Cache, ReplacementPolicy, WaySize,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::slcr::Slcr;
|
||||||
|
|
||||||
|
/// This is the default configuration used by Xilinx/AMD.
|
||||||
|
pub const AUX_CTRL_DEFAULT: AuxControl = AuxControl::builder()
|
||||||
|
.with_early_bresp_enable(true)
|
||||||
|
.with_isntruction_prefetch_enable(true)
|
||||||
|
.with_data_prefetch_enable(true)
|
||||||
|
.with_nonsec_interrupt_access_control(false)
|
||||||
|
.with_nonsec_lockdown_enable(false)
|
||||||
|
.with_cache_replace_policy(ReplacementPolicy::RoundRobin)
|
||||||
|
.with_force_write_alloc(u2::new(0))
|
||||||
|
.with_shared_attr_override(false)
|
||||||
|
.with_parity_enable(true)
|
||||||
|
.with_event_monitor_bus_enable(true)
|
||||||
|
.with_way_size(WaySize::_64kB)
|
||||||
|
.with_associativity(Associativity::_8Way)
|
||||||
|
.with_shared_attribute_invalidate(false)
|
||||||
|
.with_exclusive_cache_config(false)
|
||||||
|
.with_store_buff_device_limitation_enable(false)
|
||||||
|
.with_high_priority_so_dev_reads(false)
|
||||||
|
.with_full_line_zero_enable(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/// Xilinx/AMD default configuration. 2 cycles for setup, write and read.
|
||||||
|
pub const DEFAULT_TAG_RAM_LATENCY: LatencyConfig = LatencyConfig::builder()
|
||||||
|
.with_write_access_latency(u3::new(0b001))
|
||||||
|
.with_read_access_latency(u3::new(0b001))
|
||||||
|
.with_setup_latency(u3::new(0b001))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
/// Xilinx/AMD default configuration. 2 cycles for setup and write, 3 cycles for read.
|
||||||
|
pub const DEFAULT_DATA_RAM_LATENCY: LatencyConfig = LatencyConfig::builder()
|
||||||
|
.with_write_access_latency(u3::new(0b001))
|
||||||
|
.with_read_access_latency(u3::new(0b010))
|
||||||
|
.with_setup_latency(u3::new(0b001))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// SLCR L2C ram configuration.
|
||||||
|
pub const SLCR_L2C_CONFIG_MAGIC_VALUE: u32 = 0x00020202;
|
||||||
|
|
||||||
|
/// Similar to [init], but uses Xilinx/AMD defaults for the latency configurations.
|
||||||
|
pub fn init_with_defaults(l2c_mmio: &mut MmioL2Cache<'static>) {
|
||||||
|
init(l2c_mmio, DEFAULT_TAG_RAM_LATENCY, DEFAULT_DATA_RAM_LATENCY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Generic intializer function for the L2 cache.
|
||||||
|
///
|
||||||
|
/// This function is based on the initialization sequence specified in the TRM p.94 and on
|
||||||
|
/// the runtime initialization provided by Xilinx/AMD.
|
||||||
|
pub fn init(
|
||||||
|
l2c_mmio: &mut MmioL2Cache<'static>,
|
||||||
|
tag_ram_latency: LatencyConfig,
|
||||||
|
data_ram_latency: LatencyConfig,
|
||||||
|
) {
|
||||||
|
l2c_mmio.write_control(Control::new_disabled());
|
||||||
|
l2c_mmio.write_aux_control(AUX_CTRL_DEFAULT);
|
||||||
|
l2c_mmio.write_tag_ram_latency(tag_ram_latency);
|
||||||
|
l2c_mmio.write_data_ram_latency(data_ram_latency);
|
||||||
|
|
||||||
|
// Invalidate the whole cache.
|
||||||
|
l2c_mmio.write_clean_invalidate_by_way(0xffff);
|
||||||
|
while l2c_mmio.read_cache_sync().busy() {}
|
||||||
|
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
|
let pending = l2c_mmio.read_interrupt_raw_status();
|
||||||
|
l2c_mmio.write_interrupt_clear(InterruptControl::new_with_raw_value(pending.raw_value()));
|
||||||
|
unsafe {
|
||||||
|
Slcr::with(|slcr| {
|
||||||
|
slcr.write_magic_l2c_register(SLCR_L2C_CONFIG_MAGIC_VALUE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
l2c_mmio.write_control(Control::new_enabled());
|
||||||
|
}
|
@@ -19,6 +19,7 @@ pub mod gic;
|
|||||||
pub mod gpio;
|
pub mod gpio;
|
||||||
pub mod gtc;
|
pub mod gtc;
|
||||||
pub mod i2c;
|
pub mod i2c;
|
||||||
|
pub mod l2_cache;
|
||||||
pub mod log;
|
pub mod log;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
pub mod slcr;
|
pub mod slcr;
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
//! Start-up code for Zynq 7000
|
//! Start-up code for Zynq 7000
|
||||||
//!
|
//!
|
||||||
//! The bootup routine was kepts as similar to the one
|
//! The bootup routine was is based on the one
|
||||||
//! [provided by Xilinx](https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexa9/gcc/boot.S)
|
//! [provided by Xilinx](https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/arm/cortexa9/gcc/boot.S)
|
||||||
//! as possible. The boot routine includes stack, MMU, cache and .bss/.data section initialization.
|
//! but does NOT provide the L2 cache initialization.
|
||||||
|
//!
|
||||||
|
//! The boot routine includes stack, MMU and .bss/.data section initialization.
|
||||||
use cortex_a_rt as _;
|
use cortex_a_rt as _;
|
||||||
use cortex_ar::register::{Cpsr, cpsr::ProcessorMode};
|
use cortex_ar::register::{Cpsr, cpsr::ProcessorMode};
|
||||||
|
|
||||||
@@ -196,61 +198,6 @@ initialize:
|
|||||||
orr r0, r0, #(0x01 ) /* Cache/TLB maintenance broadcast */
|
orr r0, r0, #(0x01 ) /* Cache/TLB maintenance broadcast */
|
||||||
mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/
|
mcr p15, 0, r0, c1, c0, 1 /* Write ACTLR*/
|
||||||
|
|
||||||
/* Invalidate L2 Cache and enable L2 Cache*/
|
|
||||||
/* For AMP, assume running on CPU1. Don't initialize L2 Cache (up to Linux) */
|
|
||||||
ldr r0,=L2CCCrtl /* Load L2CC base address base + control register */
|
|
||||||
mov r1, #0 /* force the disable bit */
|
|
||||||
str r1, [r0] /* disable the L2 Caches */
|
|
||||||
|
|
||||||
ldr r0,=L2CCAuxCrtl /* Load L2CC base address base + Aux control register */
|
|
||||||
ldr r1,[r0] /* read the register */
|
|
||||||
ldr r2,=L2CCAuxControl /* set the default bits */
|
|
||||||
orr r1,r1,r2
|
|
||||||
str r1, [r0] /* store the Aux Control Register */
|
|
||||||
|
|
||||||
ldr r0,=L2CCTAGLatReg /* Load L2CC base address base + TAG Latency address */
|
|
||||||
ldr r1,=L2CCTAGLatency /* set the latencies for the TAG*/
|
|
||||||
str r1, [r0] /* store the TAG Latency register Register */
|
|
||||||
|
|
||||||
ldr r0,=L2CCDataLatReg /* Load L2CC base address base + Data Latency address */
|
|
||||||
ldr r1,=L2CCDataLatency /* set the latencies for the Data*/
|
|
||||||
str r1, [r0] /* store the Data Latency register Register */
|
|
||||||
|
|
||||||
ldr r0,=L2CCWay /* Load L2CC base address base + way register*/
|
|
||||||
ldr r2, =0xFFFF
|
|
||||||
str r2, [r0] /* force invalidate */
|
|
||||||
|
|
||||||
ldr r0,=L2CCSync /* need to poll 0x730, PSS_L2CC_CACHE_SYNC_OFFSET */
|
|
||||||
/* Load L2CC base address base + sync register*/
|
|
||||||
/* poll for completion */
|
|
||||||
Sync:
|
|
||||||
ldr r1, [r0]
|
|
||||||
cmp r1, #0
|
|
||||||
bne Sync
|
|
||||||
|
|
||||||
ldr r0,=L2CCIntRaw /* clear pending interrupts */
|
|
||||||
ldr r1,[r0]
|
|
||||||
ldr r0,=L2CCIntClear
|
|
||||||
str r1,[r0]
|
|
||||||
|
|
||||||
ldr r0,=SLCRUnlockReg /* Load SLCR base address base + unlock register */
|
|
||||||
ldr r1,=SLCRUnlockKey /* set unlock key */
|
|
||||||
str r1, [r0] /* Unlock SLCR */
|
|
||||||
|
|
||||||
ldr r0,=SLCRL2cRamReg /* Load SLCR base address base + l2c Ram Control register */
|
|
||||||
ldr r1,=SLCRL2cRamConfig /* set the configuration value */
|
|
||||||
str r1, [r0] /* store the L2c Ram Control Register */
|
|
||||||
|
|
||||||
ldr r0,=SLCRlockReg /* Load SLCR base address base + lock register */
|
|
||||||
ldr r1,=SLCRlockKey /* set lock key */
|
|
||||||
str r1, [r0] /* lock SLCR */
|
|
||||||
|
|
||||||
ldr r0,=L2CCCrtl /* Load L2CC base address base + control register */
|
|
||||||
ldr r1,[r0] /* read the register */
|
|
||||||
mov r2, #L2CCControl /* set the enable bit */
|
|
||||||
orr r1,r1,r2
|
|
||||||
str r1, [r0] /* enable the L2 Caches */
|
|
||||||
|
|
||||||
mov r0, r0
|
mov r0, r0
|
||||||
mrc p15, 0, r1, c1, c0, 2 /* read cp access control register (CACR) into r1 */
|
mrc p15, 0, r1, c1, c0, 2 /* read cp access control register (CACR) into r1 */
|
||||||
orr r1, r1, #(0xf << 20) /* enable full access for p10 & p11 */
|
orr r1, r1, #(0xf << 20) /* enable full access for p10 & p11 */
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
use arbitrary_int::{u4, u6};
|
use arbitrary_int::{u2, u3, u4, u6};
|
||||||
|
|
||||||
pub const L2C_BASE_ADDR: usize = 0xF8F0_2000;
|
pub const L2C_BASE_ADDR: usize = 0xF8F0_2000;
|
||||||
|
|
||||||
@@ -40,6 +40,153 @@ pub struct CacheId {
|
|||||||
rtl_release: u6,
|
rtl_release: u6,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Control(u32);
|
||||||
|
|
||||||
|
impl Control {
|
||||||
|
pub fn new_enabled() -> Self {
|
||||||
|
Self(0x1)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_disabled() -> Self {
|
||||||
|
Self(0x0)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn enabled(&mut self) -> bool {
|
||||||
|
self.0 == 0x1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||||
|
pub enum ReplacementPolicy {
|
||||||
|
PseudoRandomWithLfsr = 0,
|
||||||
|
RoundRobin = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitenum(u3, exhaustive = true)]
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub enum WaySize {
|
||||||
|
__Reserved0 = 0b000,
|
||||||
|
_16kB = 0b001,
|
||||||
|
_32kB = 0b010,
|
||||||
|
#[default]
|
||||||
|
_64kB = 0b011,
|
||||||
|
_128kB = 0b100,
|
||||||
|
_256kB = 0b101,
|
||||||
|
_512kB = 0b110,
|
||||||
|
__Reserved1 = 0b111,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitenum(u1, exhaustive = true)]
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub enum Associativity {
|
||||||
|
#[default]
|
||||||
|
_8Way = 0,
|
||||||
|
_16Way = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
|
pub struct AuxControl {
|
||||||
|
#[bit(30, rw)]
|
||||||
|
early_bresp_enable: bool,
|
||||||
|
#[bit(29, rw)]
|
||||||
|
isntruction_prefetch_enable: bool,
|
||||||
|
#[bit(28, rw)]
|
||||||
|
data_prefetch_enable: bool,
|
||||||
|
#[bit(27, rw)]
|
||||||
|
nonsec_interrupt_access_control: bool,
|
||||||
|
#[bit(26, rw)]
|
||||||
|
nonsec_lockdown_enable: bool,
|
||||||
|
#[bit(25, rw)]
|
||||||
|
cache_replace_policy: ReplacementPolicy,
|
||||||
|
#[bits(23..=24, rw)]
|
||||||
|
force_write_alloc: u2,
|
||||||
|
#[bit(22, rw)]
|
||||||
|
shared_attr_override: bool,
|
||||||
|
#[bit(21, rw)]
|
||||||
|
parity_enable: bool,
|
||||||
|
#[bit(20, rw)]
|
||||||
|
event_monitor_bus_enable: bool,
|
||||||
|
#[bits(17..=19, rw)]
|
||||||
|
way_size: WaySize,
|
||||||
|
#[bit(16, rw)]
|
||||||
|
associativity: Associativity,
|
||||||
|
#[bit(13, rw)]
|
||||||
|
shared_attribute_invalidate: bool,
|
||||||
|
#[bit(12, rw)]
|
||||||
|
exclusive_cache_config: bool,
|
||||||
|
#[bit(11, rw)]
|
||||||
|
store_buff_device_limitation_enable: bool,
|
||||||
|
#[bit(10, rw)]
|
||||||
|
high_priority_so_dev_reads: bool,
|
||||||
|
/// Disabled by default.
|
||||||
|
#[bit(0, rw)]
|
||||||
|
full_line_zero_enable: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub struct LatencyConfig {
|
||||||
|
/// Latency is the numerical value + 1 cycles.
|
||||||
|
#[bits(8..=10, rw)]
|
||||||
|
write_access_latency: u3,
|
||||||
|
/// Latency is the numerical value + 1 cycles.
|
||||||
|
#[bits(4..=6, rw)]
|
||||||
|
read_access_latency: u3,
|
||||||
|
/// Latency is the numerical value + 1 cycles.
|
||||||
|
#[bits(0..=2, rw)]
|
||||||
|
setup_latency: u3,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InterruptStatus {
|
||||||
|
#[bit(8, r)]
|
||||||
|
dec_error_l3: bool,
|
||||||
|
#[bit(7, r)]
|
||||||
|
slave_error_l3: bool,
|
||||||
|
#[bit(6, r)]
|
||||||
|
error_data_ram_read: bool,
|
||||||
|
#[bit(5, r)]
|
||||||
|
error_tag_ram_read: bool,
|
||||||
|
#[bit(4, r)]
|
||||||
|
error_data_ram_write: bool,
|
||||||
|
#[bit(3, r)]
|
||||||
|
error_tag_ram_write: bool,
|
||||||
|
#[bit(2, r)]
|
||||||
|
parity_error_data_ram_read: bool,
|
||||||
|
#[bit(1, r)]
|
||||||
|
parity_error_tag_ram_read: bool,
|
||||||
|
/// ECNTR
|
||||||
|
#[bit(0, r)]
|
||||||
|
event_counter_overflow_increment: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bitbybit::bitfield(u32, default = 0x0)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InterruptControl {
|
||||||
|
#[bit(8, w)]
|
||||||
|
dec_error_l3: bool,
|
||||||
|
#[bit(7, w)]
|
||||||
|
slave_error_l3: bool,
|
||||||
|
#[bit(6, w)]
|
||||||
|
error_data_ram_read: bool,
|
||||||
|
#[bit(5, w)]
|
||||||
|
error_tag_ram_read: bool,
|
||||||
|
#[bit(4, w)]
|
||||||
|
error_data_ram_write: bool,
|
||||||
|
#[bit(3, w)]
|
||||||
|
error_tag_ram_write: bool,
|
||||||
|
#[bit(2, w)]
|
||||||
|
parity_error_data_ram_read: bool,
|
||||||
|
#[bit(1, w)]
|
||||||
|
parity_error_tag_ram_read: bool,
|
||||||
|
/// ECNTR
|
||||||
|
#[bit(0, w)]
|
||||||
|
event_counter_overflow_increment: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(derive_mmio::Mmio)]
|
#[derive(derive_mmio::Mmio)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct L2Cache {
|
pub struct L2Cache {
|
||||||
@@ -50,10 +197,10 @@ pub struct L2Cache {
|
|||||||
|
|
||||||
_reserved: [u32; 0x3E],
|
_reserved: [u32; 0x3E],
|
||||||
|
|
||||||
control: u32,
|
control: Control,
|
||||||
aux_control: u32,
|
aux_control: AuxControl,
|
||||||
tag_ram_control: u32,
|
tag_ram_latency: LatencyConfig,
|
||||||
data_ram_control: u32,
|
data_ram_latency: LatencyConfig,
|
||||||
|
|
||||||
_reserved2: [u32; 0x3C],
|
_reserved2: [u32; 0x3C],
|
||||||
|
|
||||||
@@ -64,11 +211,11 @@ pub struct L2Cache {
|
|||||||
event_counter_0: u32,
|
event_counter_0: u32,
|
||||||
interrupt_mask: u32,
|
interrupt_mask: u32,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
interrupt_mask_status: u32,
|
interrupt_mask_status: InterruptStatus,
|
||||||
#[mmio(PureRead)]
|
#[mmio(PureRead)]
|
||||||
interrupt_raw_status: u32,
|
interrupt_raw_status: InterruptStatus,
|
||||||
#[mmio(Write)]
|
#[mmio(Write)]
|
||||||
interrupt_clear: u32,
|
interrupt_clear: InterruptControl,
|
||||||
|
|
||||||
_reserved3: [u32; 0x143],
|
_reserved3: [u32; 0x143],
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@ static PERIPHERALS_TAKEN: AtomicBool = AtomicBool::new(false);
|
|||||||
pub struct PsPeripherals {
|
pub struct PsPeripherals {
|
||||||
pub gicc: gic::MmioGicc<'static>,
|
pub gicc: gic::MmioGicc<'static>,
|
||||||
pub gicd: gic::MmioGicd<'static>,
|
pub gicd: gic::MmioGicd<'static>,
|
||||||
|
pub l2c: l2_cache::MmioL2Cache<'static>,
|
||||||
pub uart_0: uart::MmioUart<'static>,
|
pub uart_0: uart::MmioUart<'static>,
|
||||||
pub uart_1: uart::MmioUart<'static>,
|
pub uart_1: uart::MmioUart<'static>,
|
||||||
pub spi_0: spi::MmioSpi<'static>,
|
pub spi_0: spi::MmioSpi<'static>,
|
||||||
@@ -74,6 +75,7 @@ impl PsPeripherals {
|
|||||||
Self {
|
Self {
|
||||||
gicc: gic::Gicc::new_mmio_fixed(),
|
gicc: gic::Gicc::new_mmio_fixed(),
|
||||||
gicd: gic::Gicd::new_mmio_fixed(),
|
gicd: gic::Gicd::new_mmio_fixed(),
|
||||||
|
l2c: l2_cache::L2Cache::new_mmio_fixed(),
|
||||||
uart_0: uart::Uart::new_mmio_fixed_0(),
|
uart_0: uart::Uart::new_mmio_fixed_0(),
|
||||||
uart_1: uart::Uart::new_mmio_fixed_1(),
|
uart_1: uart::Uart::new_mmio_fixed_1(),
|
||||||
gtc: gtc::Gtc::new_mmio_fixed(),
|
gtc: gtc::Gtc::new_mmio_fixed(),
|
||||||
|
Reference in New Issue
Block a user