mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-26 03:38:25 +08:00
satman: support analyzer packets
This commit is contained in:
parent
fdca1ab7fc
commit
0b03126038
1
artiq/firmware/Cargo.lock
generated
1
artiq/firmware/Cargo.lock
generated
@ -352,6 +352,7 @@ dependencies = [
|
||||
"board_misoc",
|
||||
"build_misoc",
|
||||
"log",
|
||||
"proto_artiq",
|
||||
"riscv",
|
||||
]
|
||||
|
||||
|
@ -59,6 +59,7 @@ pub enum Packet {
|
||||
SpiBasicReply { succeeded: bool },
|
||||
|
||||
AnalyzerRequest { destination: u8 },
|
||||
AnalyzerHeader { sent_bytes: u32, total_byte_count: u64, overflow_occurred: bool },
|
||||
AnalyzerData { last: bool, length: u16, data: [u8; ANALYZER_MAX_SIZE]},
|
||||
|
||||
DmaAddTraceRequest { destination: u8, id: u32, last: bool, length: u16, trace: [u8; DMA_TRACE_MAX_SIZE] },
|
||||
@ -202,18 +203,22 @@ impl Packet {
|
||||
0xa0 => Packet::AnalyzerRequest {
|
||||
destination: reader.read_u8()?
|
||||
},
|
||||
|
||||
0xa1 => {
|
||||
0xa1 => Packet::AnalyzerHeader {
|
||||
sent_bytes: reader.read_u32()?,
|
||||
total_byte_count: reader.read_u64()?,
|
||||
overflow_occurred: reader.read_bool()?,
|
||||
},
|
||||
0xa2 => {
|
||||
let last = reader.read_bool()?;
|
||||
let length = reader.read_u16()?;
|
||||
let mut data: [u8; ANALYZER_MAX_SIZE] = [0; ANALYZER_MAX_SIZE];
|
||||
reader.read_exact(&mut trace[0..length as usize])?;
|
||||
reader.read_exact(&mut data[0..length as usize])?;
|
||||
Packet::AnalyzerData {
|
||||
last: last,
|
||||
length: length,
|
||||
data: data
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
0xb0 => {
|
||||
let destination = reader.read_u8()?;
|
||||
@ -419,8 +424,14 @@ impl Packet {
|
||||
writer.write_u8(0xa0)?;
|
||||
writer.write_u8(destination)?;
|
||||
},
|
||||
Packet::AnalyzerData { last, length, data } => {
|
||||
Packet::AnalyzerHeader { sent_bytes, total_byte_count, overflow_occurred } => {
|
||||
writer.write_u8(0xa1)?;
|
||||
writer.write_u32(sent_bytes)?;
|
||||
writer.write_u64(total_byte_count)?;
|
||||
writer.write_bool(overflow_occurred)?;
|
||||
},
|
||||
Packet::AnalyzerData { last, length, data } => {
|
||||
writer.write_u8(0xa2)?;
|
||||
writer.write_bool(last)?;
|
||||
writer.write_u16(length)?;
|
||||
writer.write_all(&data[0..length as usize])?;
|
||||
|
@ -18,3 +18,4 @@ board_misoc = { path = "../libboard_misoc", features = ["uart_console", "log"] }
|
||||
board_artiq = { path = "../libboard_artiq" }
|
||||
alloc_list = { path = "../liballoc_list" }
|
||||
riscv = { version = "0.6.0", features = ["inline-asm"] }
|
||||
proto_artiq = { path = "../libproto_artiq", features = ["log", "alloc"] }
|
||||
|
71
artiq/firmware/satman/analyzer.rs
Normal file
71
artiq/firmware/satman/analyzer.rs
Normal file
@ -0,0 +1,71 @@
|
||||
use board_misoc::{csr, cache};
|
||||
use board_artiq::drtioaux;
|
||||
use proto_artiq::drtioaux_proto::ANALYZER_MAX_SIZE;
|
||||
|
||||
const BUFFER_SIZE: usize = 512 * 1024;
|
||||
|
||||
#[repr(align(64))]
|
||||
struct Buffer {
|
||||
data: [u8; BUFFER_SIZE],
|
||||
}
|
||||
|
||||
static mut BUFFER: Buffer = Buffer {
|
||||
data: [0; BUFFER_SIZE]
|
||||
};
|
||||
|
||||
pub fn arm() {
|
||||
unsafe {
|
||||
let base_addr = &mut BUFFER.data[0] as *mut _ as usize;
|
||||
let last_addr = &mut BUFFER.data[BUFFER_SIZE - 1] as *mut _ as usize;
|
||||
csr::rtio_analyzer::message_encoder_overflow_reset_write(1);
|
||||
csr::rtio_analyzer::dma_base_address_write(base_addr as u64);
|
||||
csr::rtio_analyzer::dma_last_address_write(last_addr as u64);
|
||||
csr::rtio_analyzer::dma_reset_write(1);
|
||||
csr::rtio_analyzer::enable_write(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disarm() {
|
||||
unsafe {
|
||||
csr::rtio_analyzer::enable_write(0);
|
||||
while csr::rtio_analyzer::busy_read() != 0 {}
|
||||
cache::flush_cpu_dcache();
|
||||
cache::flush_l2_cache();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send() -> Result<(), drtioaux::Error<!>> {
|
||||
let data = unsafe { &BUFFER.data[..] };
|
||||
let overflow_occurred = unsafe { csr::rtio_analyzer::message_encoder_overflow_read() != 0 };
|
||||
let total_byte_count = unsafe { csr::rtio_analyzer::dma_byte_count_read() };
|
||||
let pointer = (total_byte_count % BUFFER_SIZE as u64) as usize;
|
||||
let wraparound = total_byte_count >= BUFFER_SIZE as u64;
|
||||
let sent_bytes = if wraparound { BUFFER_SIZE } else { total_byte_count as usize };
|
||||
|
||||
drtioaux::send(0, &drtioaux::Packet::AnalyzerHeader {
|
||||
total_byte_count: total_byte_count,
|
||||
sent_bytes: sent_bytes as u32,
|
||||
overflow_occurred: overflow_occurred,
|
||||
})?;
|
||||
|
||||
let mut i = if wraparound { pointer } else { 0 };
|
||||
while i < sent_bytes {
|
||||
let mut data_slice: [u8; ANALYZER_MAX_SIZE] = [0; ANALYZER_MAX_SIZE];
|
||||
let len: usize = if i + ANALYZER_MAX_SIZE < sent_bytes { ANALYZER_MAX_SIZE } else { sent_bytes - i } as usize;
|
||||
let last = i + len == sent_bytes;
|
||||
if i + len >= BUFFER_SIZE {
|
||||
data_slice[..len].clone_from_slice(&data[i..BUFFER_SIZE]);
|
||||
data_slice[..len].clone_from_slice(&data[..(i+len) % BUFFER_SIZE]);
|
||||
} else {
|
||||
data_slice[..len].clone_from_slice(&data[i..i+len]);
|
||||
}
|
||||
i += len;
|
||||
drtioaux::send(0, &drtioaux::Packet::AnalyzerData {
|
||||
last: last,
|
||||
length: len as u16,
|
||||
data: data_slice,
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
@ -8,6 +8,7 @@ extern crate board_misoc;
|
||||
extern crate board_artiq;
|
||||
extern crate riscv;
|
||||
extern crate alloc;
|
||||
extern crate proto_artiq;
|
||||
|
||||
use core::convert::TryFrom;
|
||||
use board_misoc::{csr, ident, clock, uart_logger, i2c, pmp};
|
||||
@ -23,6 +24,7 @@ static mut ALLOC: alloc_list::ListAlloc = alloc_list::EMPTY;
|
||||
|
||||
mod repeater;
|
||||
mod dma;
|
||||
mod analyzer;
|
||||
|
||||
fn drtiosat_reset(reset: bool) {
|
||||
unsafe {
|
||||
@ -300,6 +302,15 @@ fn process_aux_packet(_manager: &mut DmaManager, _repeaters: &mut [repeater::Rep
|
||||
&drtioaux::Packet::SpiReadReply { succeeded: false, data: 0 })
|
||||
}
|
||||
}
|
||||
|
||||
drtioaux::Packet::AnalyzerRequest { destination: _destination } => {
|
||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
||||
analyzer::disarm();
|
||||
let res = analyzer::send();
|
||||
analyzer::arm();
|
||||
res
|
||||
}
|
||||
|
||||
#[cfg(has_rtio_dma)]
|
||||
drtioaux::Packet::DmaAddTraceRequest { destination: _destination, id, last, length, trace } => {
|
||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
||||
@ -546,6 +557,9 @@ pub extern fn main() -> i32 {
|
||||
// without a manual intervention.
|
||||
let mut dma_manager = DmaManager::new();
|
||||
|
||||
// Reset the analyzer as well.
|
||||
analyzer::arm();
|
||||
|
||||
drtioaux::reset(0);
|
||||
drtiosat_reset(false);
|
||||
drtiosat_reset_phy(false);
|
||||
|
@ -577,7 +577,7 @@ class SatelliteBase(BaseSoC):
|
||||
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||
self.csr_devices.append("routing_table")
|
||||
|
||||
self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.rtio_core.cri,
|
||||
self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.local_io.cri,
|
||||
self.get_native_sdram_if(), cpu_dw=self.cpu_dw)
|
||||
self.csr_devices.append("rtio_analyzer")
|
||||
|
||||
|
@ -464,7 +464,7 @@ class _SatelliteBase(BaseSoC):
|
||||
self.csr_devices.append("cri_con")
|
||||
self.submodules.routing_table = rtio.RoutingTableAccess(self.cri_con)
|
||||
self.csr_devices.append("routing_table")
|
||||
self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.rtio_core.cri,
|
||||
self.submodules.rtio_analyzer = rtio.Analyzer(self.rtio_tsc, self.local_io.cri,
|
||||
self.get_native_sdram_if(), cpu_dw=self.cpu_dw)
|
||||
self.csr_devices.append("rtio_analyzer")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user