satman: support analyzer packets

This commit is contained in:
mwojcik 2023-05-10 17:22:56 +08:00 committed by Sébastien Bourdeauducq
parent fdca1ab7fc
commit 0b03126038
7 changed files with 105 additions and 7 deletions

View File

@ -352,6 +352,7 @@ dependencies = [
"board_misoc",
"build_misoc",
"log",
"proto_artiq",
"riscv",
]

View File

@ -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])?;

View File

@ -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"] }

View 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(())
}

View File

@ -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);

View File

@ -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")

View File

@ -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")