From 924ae7300026b1f28a29b1dd7c24ffcb0a867876 Mon Sep 17 00:00:00 2001 From: whitequark Date: Fri, 3 Mar 2017 09:14:43 +0000 Subject: [PATCH] firmware: fix DMA trace alignment and flush caches. --- artiq/firmware/ksupport/lib.rs | 7 ++++--- artiq/firmware/runtime/rtio_dma.rs | 28 ++++++++++++++++++++++------ artiq/firmware/runtime/session.rs | 2 ++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/artiq/firmware/ksupport/lib.rs b/artiq/firmware/ksupport/lib.rs index 8b54b8111..8a4be01da 100644 --- a/artiq/firmware/ksupport/lib.rs +++ b/artiq/firmware/ksupport/lib.rs @@ -320,9 +320,10 @@ extern fn dma_playback(timestamp: i64, name: CSlice) { let succeeded = recv!(&DmaPlaybackReply(data) => unsafe { match data { Some(bytes) => { - // Here, we take advantage of the fact that DmaPlaybackReply always refers - // to an entire heap allocation, which is 4-byte-aligned. - csr::rtio_dma::base_address_write(bytes.as_ptr() as u64); + let ptr = bytes.as_ptr() as usize; + assert!(ptr % 64 == 0); + + csr::rtio_dma::base_address_write(ptr as u64); csr::rtio_dma::time_offset_write(timestamp as u64); rtio_arb_dma(); diff --git a/artiq/firmware/runtime/rtio_dma.rs b/artiq/firmware/runtime/rtio_dma.rs index 48a34bd87..a8d624462 100644 --- a/artiq/firmware/runtime/rtio_dma.rs +++ b/artiq/firmware/runtime/rtio_dma.rs @@ -4,9 +4,12 @@ use std::string::String; use std::btree_map::BTreeMap; use std::io::Write; +const ALIGNMENT: usize = 64; + #[derive(Debug)] struct Entry { - data: Vec + data: Vec, + padding: usize } #[derive(Debug)] @@ -24,7 +27,7 @@ impl Manager { } pub fn record_start(&mut self) { - self.recording.clear(); + self.recording = Vec::new(); } pub fn record_append(&mut self, timestamp: u64, channel: u32, @@ -63,12 +66,23 @@ impl Manager { let mut recorded = Vec::new(); mem::swap(&mut self.recording, &mut recorded); 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 { - data: recorded + data: recorded, + padding: padding, }); } @@ -77,6 +91,8 @@ impl Manager { } pub fn with_trace) -> 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..])) } } diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index f46ea6ed1..ad9b6577e 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -410,6 +410,8 @@ fn process_kern_message(io: &Io, mut stream: Option<&mut TcpStream>, } &kern::DmaRecordStop(name) => { session.congress.dma_manager.record_stop(name); + board::cache::flush_cpu_dcache(); + board::cache::flush_l2_cache(); kern_acknowledge() } &kern::DmaEraseRequest(name) => {