From cd7527b701575b8c8998fca6f895c1265c31e9f5 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 23 Nov 2016 13:49:19 +0000 Subject: [PATCH 1/5] runtime: print trace level log messages to UART during startup. There's no way to retrieve them otherwise if the startup kernel hangs. --- artiq/runtime.rs/src/logger.rs | 21 +++++++++++++++++---- artiq/runtime.rs/src/session.rs | 2 ++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/artiq/runtime.rs/src/logger.rs b/artiq/runtime.rs/src/logger.rs index 77d1d01d5..e4093e48a 100644 --- a/artiq/runtime.rs/src/logger.rs +++ b/artiq/runtime.rs/src/logger.rs @@ -1,11 +1,12 @@ use core::{mem, ptr}; -use core::cell::RefCell; +use core::cell::{Cell, RefCell}; use log::{self, Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter}; use log_buffer::LogBuffer; use clock; pub struct BufferLogger { - buffer: RefCell> + buffer: RefCell>, + trace_to_uart: Cell } unsafe impl Sync for BufferLogger {} @@ -15,7 +16,8 @@ static mut LOGGER: *const BufferLogger = ptr::null(); impl BufferLogger { pub fn new(buffer: &'static mut [u8]) -> BufferLogger { BufferLogger { - buffer: RefCell::new(LogBuffer::new(buffer)) + buffer: RefCell::new(LogBuffer::new(buffer)), + trace_to_uart: Cell::new(true) } } @@ -48,6 +50,14 @@ impl BufferLogger { pub fn extract R>(&self, f: F) -> R { f(self.buffer.borrow_mut().extract()) } + + pub fn disable_trace_to_uart(&self) { + if self.trace_to_uart.get() { + trace!("disabling tracing to UART; all further trace messages \ + are sent to core log only"); + self.trace_to_uart.set(false) + } + } } impl Log for BufferLogger { @@ -61,7 +71,10 @@ impl Log for BufferLogger { writeln!(self.buffer.borrow_mut(), "[{:12}us] {:>5}({}): {}", clock::get_us(), record.level(), record.target(), record.args()).unwrap(); - if record.level() <= LogLevel::Info { + + // Printing to UART is really slow, so avoid doing that when we have an alternative + // route to retrieve the debug messages. + if self.trace_to_uart.get() || record.level() <= LogLevel::Info { println!("[{:12}us] {:>5}({}): {}", clock::get_us(), record.level(), record.target(), record.args()); } diff --git a/artiq/runtime.rs/src/session.rs b/artiq/runtime.rs/src/session.rs index 78eba0faa..083cfa8a9 100644 --- a/artiq/runtime.rs/src/session.rs +++ b/artiq/runtime.rs/src/session.rs @@ -583,6 +583,8 @@ pub fn thread(waiter: Waiter, spawner: Spawner) { } } + BufferLogger::with_instance(|logger| logger.disable_trace_to_uart()); + let addr = SocketAddr::new(IP_ANY, 1381); let listener = TcpListener::bind(waiter, addr).expect("cannot bind socket"); listener.set_keepalive(true); From 4df7941a9797542f461ed11730ad222c88faef81 Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 23 Nov 2016 13:53:12 +0000 Subject: [PATCH 2/5] runtime: don't attempt to perform writeback if disabled in kernel. Otherwise, the startup kernel session hangs. --- artiq/runtime.rs/libksupport/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/artiq/runtime.rs/libksupport/lib.rs b/artiq/runtime.rs/libksupport/lib.rs index 027c0e3b3..08673e759 100644 --- a/artiq/runtime.rs/libksupport/lib.rs +++ b/artiq/runtime.rs/libksupport/lib.rs @@ -307,7 +307,10 @@ pub unsafe fn main() { (mem::transmute::(library.lookup("__modinit__")))(); send(&NowSave(NOW)); - attribute_writeback(library.lookup("typeinfo") as *const ()); + let typeinfo = library.lookup("typeinfo"); + if typeinfo != 0 { + attribute_writeback(typeinfo as *const ()) + } send(&RunFinished); From 347609d7651c5e7cf59e905c45b5b8973c34080d Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Sat, 19 Nov 2016 14:16:06 +0100 Subject: [PATCH 3/5] rtio: auto clear output event data and address This is to support channels where variable length event data is well-defined through zero-padding. E.g. in the case of `Spline` zero-padding of events naturally corresponds to low-order knots. Use timestamp change as trigger. This assumes that writes to the timestamp register always precede address and data writes. It does not break support for ganged writes of the same event timestamp and data/address to multiple channels or channel-addresses. --- artiq/gateware/rtio/core.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/artiq/gateware/rtio/core.py b/artiq/gateware/rtio/core.py index a248632da..4d5624684 100644 --- a/artiq/gateware/rtio/core.py +++ b/artiq/gateware/rtio/core.py @@ -334,9 +334,9 @@ class _KernelCSRs(AutoCSR): self.chan_sel = CSRStorage(chan_sel_width) if data_width: - self.o_data = CSRStorage(data_width) + self.o_data = CSRStorage(data_width, write_from_dev=True) if address_width: - self.o_address = CSRStorage(address_width) + self.o_address = CSRStorage(address_width, write_from_dev=True) self.o_timestamp = CSRStorage(full_ts_width) self.o_we = CSR() self.o_status = CSRStatus(5) @@ -498,5 +498,13 @@ class RTIO(Module): << fine_ts_width) ) + # Auto clear/zero pad event data + self.comb += [ + self.kcsrs.o_data.dat_w.eq(0), + self.kcsrs.o_data.we.eq(self.kcsrs.o_timestamp.re), + self.kcsrs.o_address.dat_w.eq(0), + self.kcsrs.o_address.we.eq(self.kcsrs.o_timestamp.re), + ] + def get_csrs(self): return self.kcsrs.get_csrs() From 8cce5d2fcdaa936bb47d708007f2b4bd755a583a Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Mon, 21 Nov 2016 23:12:16 +0100 Subject: [PATCH 4/5] runtime.rs: wide rtio data --- artiq/runtime.rs/libksupport/api.rs | 1 + artiq/runtime.rs/libksupport/rtio.rs | 45 +++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/artiq/runtime.rs/libksupport/api.rs b/artiq/runtime.rs/libksupport/api.rs index dbfbd759b..57b6302d8 100644 --- a/artiq/runtime.rs/libksupport/api.rs +++ b/artiq/runtime.rs/libksupport/api.rs @@ -102,6 +102,7 @@ static mut API: &'static [(&'static str, *const ())] = &[ api!(rtio_get_counter = ::rtio::get_counter), api!(rtio_log), api!(rtio_output = ::rtio::output), + api!(rtio_output_list = ::rtio::output_list), api!(rtio_input_timestamp = ::rtio::input_timestamp), api!(rtio_input_data = ::rtio::input_data), diff --git a/artiq/runtime.rs/libksupport/rtio.rs b/artiq/runtime.rs/libksupport/rtio.rs index 4363b255d..eaeb4d01c 100644 --- a/artiq/runtime.rs/libksupport/rtio.rs +++ b/artiq/runtime.rs/libksupport/rtio.rs @@ -1,4 +1,6 @@ use board::csr; +use core::ptr::{read_volatile, write_volatile}; +use core::slice; const RTIO_O_STATUS_FULL: u32 = 1; const RTIO_O_STATUS_UNDERFLOW: u32 = 2; @@ -23,6 +25,21 @@ pub extern fn get_counter() -> i64 { } } +#[inline(always)] +pub unsafe fn rtio_o_data_write(w: u32) { + write_volatile( + csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1) as isize), + w); +} + +#[inline(always)] +pub unsafe fn rtio_i_data_read() -> u32 { + read_volatile( + csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize) + ) +} + + #[inline(never)] unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) { if status & RTIO_O_STATUS_FULL != 0 { @@ -59,7 +76,27 @@ pub extern fn output(timestamp: i64, channel: u32, addr: u32, data: u32) { csr::rtio::chan_sel_write(channel); csr::rtio::o_timestamp_write(timestamp as u64); csr::rtio::o_address_write(addr); - csr::rtio::o_data_write(data); + rtio_o_data_write(data); + csr::rtio::o_we_write(1); + let status = csr::rtio::o_status_read(); + if status != 0 { + process_exceptional_status(timestamp, channel, status); + } + } +} + +pub extern fn output_list(timestamp: i64, channel: u32, addr: u32, + &(len, ptr): &(usize, *const u32)) { + unsafe { + csr::rtio::chan_sel_write(channel); + csr::rtio::o_timestamp_write(timestamp as u64); + csr::rtio::o_address_write(addr); + let data = slice::from_raw_parts(ptr, len); + for i in 0..data.len() { + write_volatile( + csr::rtio::O_DATA_ADDR.offset((csr::rtio::O_DATA_SIZE - 1 - i) as isize), + data[i]); + } csr::rtio::o_we_write(1); let status = csr::rtio::o_status_read(); if status != 0 { @@ -119,7 +156,7 @@ pub extern fn input_data(channel: u32) -> u32 { } } - let data = csr::rtio::i_data_read(); + let data = rtio_i_data_read(); csr::rtio::i_re_write(1); data } @@ -136,14 +173,14 @@ pub fn log(timestamp: i64, data: &[u8]) { word <<= 8; word |= data[i] as u32; if i % 4 == 0 { - csr::rtio::o_data_write(word); + rtio_o_data_write(word); csr::rtio::o_we_write(1); word = 0; } } word <<= 8; - csr::rtio::o_data_write(word); + rtio_o_data_write(word); csr::rtio::o_we_write(1); } } From a964cf24f285849b9398fecab95a29372ec01547 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Wed, 23 Nov 2016 14:56:20 +0100 Subject: [PATCH 5/5] runtime.rs/rtio.rs: style --- artiq/runtime.rs/libksupport/rtio.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/artiq/runtime.rs/libksupport/rtio.rs b/artiq/runtime.rs/libksupport/rtio.rs index eaeb4d01c..60dadc815 100644 --- a/artiq/runtime.rs/libksupport/rtio.rs +++ b/artiq/runtime.rs/libksupport/rtio.rs @@ -35,11 +35,9 @@ pub unsafe fn rtio_o_data_write(w: u32) { #[inline(always)] pub unsafe fn rtio_i_data_read() -> u32 { read_volatile( - csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize) - ) + csr::rtio::I_DATA_ADDR.offset((csr::rtio::I_DATA_SIZE - 1) as isize)) } - #[inline(never)] unsafe fn process_exceptional_status(timestamp: i64, channel: u32, status: u32) { if status & RTIO_O_STATUS_FULL != 0 {