forked from M-Labs/zynq-rs
mmu: set L2-bufferable for DDR
This commit is contained in:
parent
5c0953d869
commit
77c3998dbd
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
Loading…
Reference in New Issue