mmu: set L2-bufferable for DDR

This commit is contained in:
Astro 2020-06-22 02:32:38 +02:00
parent 5c0953d869
commit 77c3998dbd
7 changed files with 30 additions and 4 deletions

View File

@ -33,7 +33,7 @@ use libregister::RegisterR;
use libsupport_zynq::{ use libsupport_zynq::{
boot, ram, boot, ram,
}; };
use log::info; use log::{info, warn};
mod ps7_init; mod ps7_init;
@ -84,7 +84,9 @@ pub fn main_core0() {
); );
info!("Setup L2Cache"); info!("Setup L2Cache");
setup_l2cache(); setup_l2cache();
info!("L2Cache done");
if false {
let sd = libboard_zynq::sdio::SDIO::sdio0(true); let sd = libboard_zynq::sdio::SDIO::sdio0(true);
// only test SD card if it is inserted // only test SD card if it is inserted
if sd.is_card_inserted() { if sd.is_card_inserted() {
@ -117,6 +119,7 @@ pub fn main_core0() {
println!(""); println!("");
} }
let mut flash = flash.stop(); let mut flash = flash.stop();
}
let timer = libboard_zynq::timer::GlobalTimer::start(); let timer = libboard_zynq::timer::GlobalTimer::start();
@ -125,6 +128,7 @@ pub fn main_core0() {
ddr.memtest(); ddr.memtest();
ram::init_alloc_ddr(&mut ddr); ram::init_alloc_ddr(&mut ddr);
if false {
#[cfg(dev)] #[cfg(dev)]
for i in 0..=1 { for i in 0..=1 {
let mut flash_io = flash.manual_mode(i); let mut flash_io = flash.manual_mode(i);
@ -178,6 +182,7 @@ pub fn main_core0() {
} }
}); });
core1.disable(); core1.disable();
}
let eth = zynq::eth::Eth::default(HWADDR.clone()); let eth = zynq::eth::Eth::default(HWADDR.clone());
println!("Eth on"); println!("Eth on");

View File

@ -21,5 +21,6 @@ libcortex_a9 = { path = "../libcortex_a9" }
[dependencies.smoltcp] [dependencies.smoltcp]
version = "0.6" version = "0.6"
# features = ["ethernet", "proto-ipv4", "socket-tcp", "log"]
features = ["ethernet", "proto-ipv4", "socket-tcp"] features = ["ethernet", "proto-ipv4", "socket-tcp"]
default-features = false default-features = false

View File

@ -2,6 +2,8 @@ use core::ops::Deref;
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
use libcortex_a9::{asm::*, cache::*, UncachedSlice}; use libcortex_a9::{asm::*, cache::*, UncachedSlice};
use libregister::*; use libregister::*;
use log::debug;
use crate::l2cache;
use super::Buffer; use super::Buffer;
#[derive(Debug)] #[derive(Debug)]
@ -83,6 +85,7 @@ impl DescList {
); );
// Flush buffer from cache, to be filled by the peripheral // Flush buffer from cache, to be filled by the peripheral
// before next read // before next read
l2cache().clean_invalidate_slice(&buffer[..]);
dcci_slice(&buffer[..]); dcci_slice(&buffer[..]);
} }
@ -105,6 +108,8 @@ impl DescList {
let word1 = entry.word1.read(); let word1 = entry.word1.read();
let len = word1.frame_length_lsbs().into(); let len = word1.frame_length_lsbs().into();
let buffer = &mut self.buffers[self.next][0..len]; let buffer = &mut self.buffers[self.next][0..len];
// l2cache().invalidate_slice(&mut buffer[..]);
// dcci_slice(&buffer[..]);
self.next += 1; self.next += 1;
if self.next >= list_len { if self.next >= list_len {
@ -113,8 +118,10 @@ impl DescList {
let pkt = PktRef { entry, buffer }; let pkt = PktRef { entry, buffer };
if word1.start_of_frame() && word1.end_of_frame() { if word1.start_of_frame() && word1.end_of_frame() {
// debug!("pkt {}: {:08X}..{:08X}", len, &pkt.buffer[0] as *const _ as usize, &pkt.buffer[pkt.len()-1] as *const _ as usize);
Ok(Some(pkt)) Ok(Some(pkt))
} else { } else {
debug!("pkt trunc");
Err(Error::Truncated) Err(Error::Truncated)
} }
} else { } else {
@ -133,6 +140,7 @@ impl<'a> Drop for PktRef<'a> {
fn drop(&mut self) { fn drop(&mut self) {
// Flush buffer from cache, to be filled by the peripheral // Flush buffer from cache, to be filled by the peripheral
// before next read // before next read
l2cache().invalidate_slice(self.buffer);
dcci_slice(self.buffer); dcci_slice(self.buffer);
self.entry.word0.modify(|_, w| w.used(false)); self.entry.word0.modify(|_, w| w.used(false));

View File

@ -2,7 +2,8 @@ use core::ops::{Deref, DerefMut};
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
use libcortex_a9::{cache::dcc_slice, UncachedSlice}; use libcortex_a9::{cache::dcc_slice, UncachedSlice};
use libregister::*; use libregister::*;
use log::warn; use log::{debug, warn};
use crate::l2cache;
use super::{Buffer, regs}; use super::{Buffer, regs};
/// Descriptor entry /// Descriptor entry
@ -91,8 +92,10 @@ impl DescList {
} }
pub fn send<'s: 'p, 'p>(&'s mut self, regs: &'s mut regs::RegisterBlock, length: usize) -> Option<PktRef<'p>> { pub fn send<'s: 'p, 'p>(&'s mut self, regs: &'s mut regs::RegisterBlock, length: usize) -> Option<PktRef<'p>> {
// debug!("send {}", length);
let list_len = self.list.len(); let list_len = self.list.len();
let entry = &mut self.list[self.next]; let entry = &mut self.list[self.next];
// dmb();
if entry.word1.read().used() { if entry.word1.read().used() {
let buffer = &mut self.buffers[self.next][0..length]; let buffer = &mut self.buffers[self.next][0..length];
entry.word1.write(DescWord1::zeroed() entry.word1.write(DescWord1::zeroed()
@ -128,8 +131,12 @@ impl<'a> Drop for PktRef<'a> {
fn drop(&mut self) { fn drop(&mut self) {
// Write back all dirty cachelines of this buffer // Write back all dirty cachelines of this buffer
dcc_slice(self.buffer); dcc_slice(self.buffer);
l2cache().clean_slice(self.buffer);
self.entry.word1.modify(|_, w| w.used(false)); self.entry.word1.modify(|_, w| w.used(false));
// dcci(self.entry);
// l2cache().clean_invalidate(self.entry);
// dsb();
if ! self.regs.tx_status.read().tx_go() { if ! self.regs.tx_status.read().tx_go() {
// Start TX if not already running // Start TX if not already running
self.regs.net_ctrl.modify(|_, w| w.start_tx(true)); self.regs.net_ctrl.modify(|_, w| w.start_tx(true));

View File

@ -34,8 +34,10 @@ pub fn setup_l2cache() {
assert_eq!(&slcr.unnamed1 as *const _ as u32, 0xF8000A1C); assert_eq!(&slcr.unnamed1 as *const _ as u32, 0xF8000A1C);
unsafe { slcr.unnamed1.write(0x020202); } unsafe { slcr.unnamed1.write(0x020202); }
}); });
let mut l2 = l2cache(); let mut l2 = l2cache();
use log::info;
info!("l2 aux={:08X}", l2.regs.aux_control.read());
// TODO: set prefetch // TODO: set prefetch
// Configure ZYNQ-specific latency // Configure ZYNQ-specific latency

View File

@ -158,7 +158,7 @@ impl L1Table {
global: true, global: true,
shareable: true, shareable: true,
access: AccessPermissions::FullAccess, access: AccessPermissions::FullAccess,
tex: 0b101, tex: 0b111,
domain: 0b1111, domain: 0b1111,
exec: true, exec: true,
cacheable: true, cacheable: true,

View File

@ -1,3 +1,5 @@
use libregister::RegisterR;
use libcortex_a9::regs::DFSR;
use libboard_zynq::{println, slcr, stdio}; use libboard_zynq::{println, slcr, stdio};
#[no_mangle] #[no_mangle]
@ -15,6 +17,7 @@ pub unsafe extern "C" fn DataAbort() {
stdio::drop_uart(); stdio::drop_uart();
println!("DataAbort"); println!("DataAbort");
println!("DFSR: {:03X}", DFSR.read());
slcr::RegisterBlock::unlocked(|slcr| slcr.soft_reset()); slcr::RegisterBlock::unlocked(|slcr| slcr.soft_reset());
loop {} loop {}