Compare commits

..

No commits in common. "a16c639eaf0eaf8c1e56b0e9ad8b7f8462f62120" and "c0e66a632c56bb5536459cba2ef481b2c50684e7" have entirely different histories.

4 changed files with 21 additions and 97 deletions

View File

@ -33,7 +33,7 @@ use libregister::RegisterR;
use libsupport_zynq::{ use libsupport_zynq::{
boot, ram, boot, ram,
}; };
use log::{info, warn}; use log::info;
const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef];
@ -180,10 +180,10 @@ pub fn main_core0() {
let eth = zynq::eth::Eth::default(HWADDR.clone()); let eth = zynq::eth::Eth::default(HWADDR.clone());
println!("Eth on"); println!("Eth on");
const RX_LEN: usize = 4096; const RX_LEN: usize = 8;
// Number of transmission buffers (minimum is two because with // Number of transmission buffers (minimum is two because with
// one, duplicate packet transmission occurs) // one, duplicate packet transmission occurs)
const TX_LEN: usize = 4096; const TX_LEN: usize = 8;
let eth = eth.start_rx(RX_LEN); let eth = eth.start_rx(RX_LEN);
let mut eth = eth.start_tx(TX_LEN); let mut eth = eth.start_tx(TX_LEN);
@ -238,42 +238,18 @@ pub fn main_core0() {
Ok(()) Ok(())
} }
// (rx, tx) let counter = alloc::rc::Rc::new(core::cell::RefCell::new(0));
let stats = alloc::rc::Rc::new(core::cell::RefCell::new((0, 0)));
let stats_tx = stats.clone();
task::spawn(async move { task::spawn(async move {
while let Ok(stream) = TcpStream::accept(TCP_PORT, 0x10_0000, 0x10_0000).await { while let Ok(stream) = TcpStream::accept(TCP_PORT, 2048, 2408).await {
let stats_tx = stats_tx.clone(); let counter = counter.clone();
task::spawn(async move { task::spawn(async move {
let tx_data = (0..=255).take(4096).collect::<alloc::vec::Vec<u8>>(); *counter.borrow_mut() += 1;
loop { println!("Serving {} connections", *counter.borrow());
// const CHUNK_SIZE: usize = 65536; handle_connection(stream)
// match stream.send((0..=255).cycle().take(CHUNK_SIZE)).await { .await
match stream.send_slice(&tx_data[..]).await { .unwrap_or_else(|e| println!("Connection: {:?}", e));
Ok(len) => stats_tx.borrow_mut().1 += tx_data.len(), //CHUNK_SIZE, *counter.borrow_mut() -= 1;
Err(e) => { println!("Now serving {} connections", *counter.borrow());
warn!("tx: {:?}", e);
break
}
}
}
});
}
});
let stats_rx = stats.clone();
task::spawn(async move {
while let Ok(stream) = TcpStream::accept(TCP_PORT+1, 0x10_0000, 0x10_0000).await {
let stats_rx = stats_rx.clone();
task::spawn(async move {
loop {
match stream.recv(|buf| Poll::Ready((buf.len(), buf.len()))).await {
Ok(len) => stats_rx.borrow_mut().0 += len,
Err(e) => {
warn!("rx: {:?}", e);
break
}
}
}
}); });
} }
}); });
@ -286,13 +262,7 @@ pub fn main_core0() {
let timestamp = timer.get_us(); let timestamp = timer.get_us();
let seconds = timestamp / 1_000_000; let seconds = timestamp / 1_000_000;
let micros = timestamp % 1_000_000; let micros = timestamp % 1_000_000;
let (rx, tx) = { info!("time: {:6}.{:06}s", seconds, micros);
let mut stats = stats.borrow_mut();
let result = *stats;
*stats = (0, 0);
result
};
info!("time: {:6}.{:06}s, rx: {}k/s, tx: {}k/s", seconds, micros, rx / 1024, tx / 1024);
} }
}); });

View File

@ -44,15 +44,6 @@ pub fn dcisw(setway: u32) {
} }
} }
/// Data cache clean by set/way
#[inline(always)]
pub fn dccisw(setway: u32) {
unsafe {
llvm_asm!("mcr p15, 0, $0, c7, c14, 2" :: "r" (setway) :: "volatile");
}
}
/// A made-up "instruction": invalidate all of the L1 D-Cache /// A made-up "instruction": invalidate all of the L1 D-Cache
#[inline(always)] #[inline(always)]
pub fn dciall() { pub fn dciall() {
@ -80,33 +71,6 @@ pub fn dciall() {
} }
} }
/// A made-up "instruction": flush and invalidate all of the L1 D-Cache
#[inline(always)]
pub fn dcciall() {
// the cache associativity could be read from a register, but will
// always be 4 in L1 data cache of a cortex a9
let ways = 4;
let bit_pos_of_way = 30; // 32 - log2(ways)
// the cache sets could be read from a register, but are always
// 256 for the cores in the zync-7000; in general, 128 or 512 are
// also possible.
let sets = 256;
let bit_pos_of_set = 5; // for a line size of 8 words = 2^5 bytes
// select L1 data cache
unsafe {
llvm_asm!("mcr p15, 2, $0, c0, c0, 0" :: "r" (0) :: "volatile");
}
// Invalidate entire D-Cache by iterating every set and every way
for set in 0..sets {
for way in 0..ways {
dccisw((set << bit_pos_of_set) | (way << bit_pos_of_way));
}
}
}
const CACHE_LINE: usize = 0x20; const CACHE_LINE: usize = 0x20;
const CACHE_LINE_MASK: usize = CACHE_LINE - 1; const CACHE_LINE_MASK: usize = CACHE_LINE - 1;

View File

@ -1,5 +1,5 @@
use bit_field::BitField; use bit_field::BitField;
use super::{regs::*, asm::*, cache::*}; use super::{regs::*, asm, cache};
use libregister::RegisterW; use libregister::RegisterW;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -368,19 +368,10 @@ impl L1Table {
let result = f(&mut section); let result = f(&mut section);
entry.set_section(section); entry.set_section(section);
// Flush L1Dcache asm::dmb();
dcciall(); cache::tlbiall();
// // TODO: L2? asm::dsb();
asm::isb();
// Invalidate TLB
tlbiall();
// Invalidate all branch predictors
bpiall();
// ensure completion of the BP and TLB invalidation
dsb();
// synchronize context on this processor
isb();
result result
} }
@ -415,9 +406,9 @@ pub fn with_mmu<F: FnMut() -> !>(l1table: &L1Table, mut f: F) -> ! {
// Synchronization barriers // Synchronization barriers
// Allows MMU to start // Allows MMU to start
dsb(); asm::dsb();
// Flushes pre-fetch buffer // Flushes pre-fetch buffer
isb(); asm::isb();
f(); f();
} }

View File

@ -25,7 +25,6 @@ impl<T> UncachedSlice<T> {
for page_start in (start..(start + size)).step_by(L1_PAGE_SIZE) { for page_start in (start..(start + size)).step_by(L1_PAGE_SIZE) {
L1Table::get() L1Table::get()
.update(page_start as *const (), |l1_section| { .update(page_start as *const (), |l1_section| {
l1_section.tex = 0b100;
l1_section.cacheable = false; l1_section.cacheable = false;
l1_section.bufferable = false; l1_section.bufferable = false;
}); });