firmware: fix DMA trace alignment and flush caches.

This commit is contained in:
whitequark 2017-03-03 09:14:43 +00:00
parent 30ac42de3f
commit 924ae73000
3 changed files with 28 additions and 9 deletions

View File

@ -320,9 +320,10 @@ extern fn dma_playback(timestamp: i64, name: CSlice<u8>) {
let succeeded = recv!(&DmaPlaybackReply(data) => unsafe { let succeeded = recv!(&DmaPlaybackReply(data) => unsafe {
match data { match data {
Some(bytes) => { Some(bytes) => {
// Here, we take advantage of the fact that DmaPlaybackReply always refers let ptr = bytes.as_ptr() as usize;
// to an entire heap allocation, which is 4-byte-aligned. assert!(ptr % 64 == 0);
csr::rtio_dma::base_address_write(bytes.as_ptr() as u64);
csr::rtio_dma::base_address_write(ptr as u64);
csr::rtio_dma::time_offset_write(timestamp as u64); csr::rtio_dma::time_offset_write(timestamp as u64);
rtio_arb_dma(); rtio_arb_dma();

View File

@ -4,9 +4,12 @@ use std::string::String;
use std::btree_map::BTreeMap; use std::btree_map::BTreeMap;
use std::io::Write; use std::io::Write;
const ALIGNMENT: usize = 64;
#[derive(Debug)] #[derive(Debug)]
struct Entry { struct Entry {
data: Vec<u8> data: Vec<u8>,
padding: usize
} }
#[derive(Debug)] #[derive(Debug)]
@ -24,7 +27,7 @@ impl Manager {
} }
pub fn record_start(&mut self) { pub fn record_start(&mut self) {
self.recording.clear(); self.recording = Vec::new();
} }
pub fn record_append(&mut self, timestamp: u64, channel: u32, pub fn record_append(&mut self, timestamp: u64, channel: u32,
@ -63,12 +66,23 @@ impl Manager {
let mut recorded = Vec::new(); let mut recorded = Vec::new();
mem::swap(&mut self.recording, &mut recorded); mem::swap(&mut self.recording, &mut recorded);
recorded.push(0); recorded.push(0);
recorded.shrink_to_fit(); let data_len = recorded.len();
info!("recorded DMA data: {:?}", recorded); // Realign.
recorded.reserve(ALIGNMENT - 1);
let padding = ALIGNMENT - recorded.as_ptr() as usize % ALIGNMENT;
let padding = if padding == ALIGNMENT { 0 } else { padding };
for _ in 0..padding {
// Vec guarantees that this will not reallocate
recorded.push(0)
}
for i in 1..data_len + 1 {
recorded[data_len + padding - i] = recorded[data_len - i]
}
self.entries.insert(String::from(name), Entry { self.entries.insert(String::from(name), Entry {
data: recorded data: recorded,
padding: padding,
}); });
} }
@ -77,6 +91,8 @@ impl Manager {
} }
pub fn with_trace<F: FnOnce(Option<&[u8]>) -> R, R>(&self, name: &str, f: F) -> R { pub fn with_trace<F: FnOnce(Option<&[u8]>) -> R, R>(&self, name: &str, f: F) -> R {
f(self.entries.get(name).map(|entry| &entry.data[..])) f(self.entries
.get(name)
.map(|entry| &entry.data[entry.padding..]))
} }
} }

View File

@ -410,6 +410,8 @@ fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>,
} }
&kern::DmaRecordStop(name) => { &kern::DmaRecordStop(name) => {
session.congress.dma_manager.record_stop(name); session.congress.dma_manager.record_stop(name);
board::cache::flush_cpu_dcache();
board::cache::flush_l2_cache();
kern_acknowledge() kern_acknowledge()
} }
&kern::DmaEraseRequest(name) => { &kern::DmaEraseRequest(name) => {