analyzer: implement firmware part

core0-buffer
Sebastien Bourdeauducq 2020-07-16 11:47:55 +08:00
parent b62fbce826
commit 2e10922715
3 changed files with 110 additions and 3 deletions

104
src/runtime/src/analyzer.rs Normal file
View File

@ -0,0 +1,104 @@
use libasync::{smoltcp::TcpStream, task};
use libboard_zynq::smoltcp::Error;
use libcortex_a9::cache;
use log::{debug, info, warn};
use crate::proto_async::*;
use crate::pl;
const BUFFER_SIZE: usize = 512 * 1024;
#[repr(align(64))]
struct Buffer {
data: [u8; BUFFER_SIZE],
}
static mut BUFFER: Buffer = Buffer {
data: [0; BUFFER_SIZE]
};
fn arm() {
debug!("arming RTIO analyzer");
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;
pl::csr::rtio_analyzer::message_encoder_overflow_reset_write(1);
pl::csr::rtio_analyzer::dma_base_address_write(base_addr as u32);
pl::csr::rtio_analyzer::dma_last_address_write(last_addr as u32);
pl::csr::rtio_analyzer::dma_reset_write(1);
pl::csr::rtio_analyzer::enable_write(1);
}
}
fn disarm() {
debug!("disarming RTIO analyzer");
unsafe {
pl::csr::rtio_analyzer::enable_write(0);
while pl::csr::rtio_analyzer::busy_read() != 0 {}
cache::dcci_slice(&BUFFER.data);
}
debug!("RTIO analyzer disarmed");
}
#[derive(Debug)]
struct Header {
sent_bytes: u32,
total_byte_count: u64,
overflow_occurred: bool,
log_channel: u8,
dds_onehot_sel: bool
}
async fn write_header(stream: &mut TcpStream, header: &Header) -> Result<(), Error> {
write_i32(stream, header.sent_bytes as i32).await?;
write_i64(stream, header.total_byte_count as i64).await?;
write_i8(stream, header.overflow_occurred as i8).await?;
write_i8(stream, header.log_channel as i8).await?;
write_i8(stream, header.dds_onehot_sel as i8).await?;
Ok(())
}
async fn handle_connection(stream: &mut TcpStream) -> Result<(), Error> {
info!("received connection");
let data = unsafe { &BUFFER.data[..] };
let overflow_occurred = unsafe { pl::csr::rtio_analyzer::message_encoder_overflow_read() != 0 };
let total_byte_count = unsafe { pl::csr::rtio_analyzer::dma_byte_count_read() as u64 };
let pointer = (total_byte_count % BUFFER_SIZE as u64) as usize;
let wraparound = total_byte_count >= BUFFER_SIZE as u64;
let header = Header {
total_byte_count: total_byte_count,
sent_bytes: if wraparound { BUFFER_SIZE as u32 } else { total_byte_count as u32 },
overflow_occurred: overflow_occurred,
log_channel: 255,
dds_onehot_sel: true // kept for backward compatibility of analyzer dumps
};
debug!("{:?}", header);
debug!("{:?}", &data[..256]);
write_header(stream, &header).await?;
if wraparound {
stream.send(data[pointer..].iter().copied()).await?;
stream.send(data[..pointer].iter().copied()).await?;
} else {
stream.send(data[..pointer].iter().copied()).await?;
}
Ok(())
}
pub fn start() {
task::spawn(async move {
loop {
arm();
let mut stream = TcpStream::accept(1382, 2048, 2048).await.unwrap();
disarm();
let _ = handle_connection(&mut stream)
.await
.map_err(|e| warn!("connection terminated: {:?}", e));
let _ = stream.flush().await;
let _ = stream.abort().await;
}
});
}

View File

@ -28,6 +28,7 @@ use crate::kernel;
use crate::rpc;
use crate::moninj;
use crate::mgmt;
use crate::analyzer;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -331,6 +332,10 @@ pub fn main(timer: GlobalTimer, cfg: &config::Config) {
Sockets::init(32);
mgmt::start();
analyzer::start();
moninj::start(timer);
let control: Rc<RefCell<kernel::Control>> = Rc::new(RefCell::new(kernel::Control::start()));
if let Ok(buffer) = cfg.read("startup") {
info!("Loading startup kernel...");
@ -357,9 +362,6 @@ pub fn main(timer: GlobalTimer, cfg: &config::Config) {
}
});
mgmt::start();
moninj::start(timer);
Sockets::run(&mut iface, || {
Instant::from_millis(timer.get_time().0 as i32)
});

View File

@ -35,6 +35,7 @@ mod eh_artiq;
mod panic;
mod logger;
mod mgmt;
mod analyzer;
fn init_gateware() {
// Set up PS->PL clocks