forked from M-Labs/artiq
firmware: fix DMA trace alignment and flush caches.
This commit is contained in:
parent
30ac42de3f
commit
924ae73000
|
@ -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();
|
||||||
|
|
|
@ -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..]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
Loading…
Reference in New Issue