From 3633671656cc9a5920947d43fbe5f3e7b4f363d1 Mon Sep 17 00:00:00 2001 From: whitequark Date: Tue, 24 Jan 2017 21:55:51 +0000 Subject: [PATCH] firmware: factor out console and logging from runtime/satman. --- artiq/firmware/Cargo.lock | 13 ++- artiq/firmware/libboard/Cargo.toml | 3 + artiq/firmware/libboard/lib.rs | 7 +- artiq/firmware/libboard/uart_console.rs | 32 ++++++ artiq/firmware/liblogger_artiq/Cargo.toml | 13 +++ .../logger.rs => liblogger_artiq/lib.rs} | 33 ++++--- artiq/firmware/runtime/Cargo.toml | 6 +- artiq/firmware/runtime/lib.rs | 47 +-------- artiq/firmware/runtime/session.rs | 2 +- artiq/firmware/satman/Cargo.toml | 2 +- artiq/firmware/satman/Makefile | 2 - artiq/firmware/satman/lib.rs | 99 +++++++------------ artiq/firmware/satman/logger.rs | 83 ---------------- artiq/firmware/satman/main.c | 22 ----- 14 files changed, 129 insertions(+), 235 deletions(-) create mode 100644 artiq/firmware/libboard/uart_console.rs create mode 100644 artiq/firmware/liblogger_artiq/Cargo.toml rename artiq/firmware/{runtime/logger.rs => liblogger_artiq/lib.rs} (79%) delete mode 100644 artiq/firmware/satman/logger.rs delete mode 100644 artiq/firmware/satman/main.c diff --git a/artiq/firmware/Cargo.lock b/artiq/firmware/Cargo.lock index af2449dc6..4e7c9b6fd 100644 --- a/artiq/firmware/Cargo.lock +++ b/artiq/firmware/Cargo.lock @@ -71,6 +71,15 @@ name = "log_buffer" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "logger_artiq" +version = "0.0.0" +dependencies = [ + "board 0.0.0", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "managed" version = "0.2.1" @@ -86,7 +95,7 @@ dependencies = [ "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "fringe 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "logger_artiq 0.0.0", "smoltcp 0.2.0 (git+https://github.com/m-labs/smoltcp?rev=b90495f)", "std_artiq 0.0.0", ] @@ -99,7 +108,7 @@ dependencies = [ "board 0.0.0", "build_artiq 0.0.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "log_buffer 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "logger_artiq 0.0.0", "std_artiq 0.0.0", ] diff --git a/artiq/firmware/libboard/Cargo.toml b/artiq/firmware/libboard/Cargo.toml index bb9a80f96..950fbcff2 100644 --- a/artiq/firmware/libboard/Cargo.toml +++ b/artiq/firmware/libboard/Cargo.toml @@ -10,3 +10,6 @@ path = "lib.rs" [dependencies] log = { version = "0.3", default-features = false } + +[features] +uart_console = [] diff --git a/artiq/firmware/libboard/lib.rs b/artiq/firmware/libboard/lib.rs index 233453b5b..4c97cd7bc 100644 --- a/artiq/firmware/libboard/lib.rs +++ b/artiq/firmware/libboard/lib.rs @@ -1,4 +1,4 @@ -#![feature(asm)] +#![feature(asm, lang_items)] #![no_std] #[macro_use] @@ -12,6 +12,8 @@ pub mod spr; pub mod irq; pub mod clock; pub mod uart; +#[cfg(feature = "uart_console")] +pub mod uart_console; #[cfg(has_i2c)] pub mod i2c; @@ -29,6 +31,9 @@ mod ad9154_reg; #[cfg(has_converter_spi)] pub mod ad9154; +#[cfg(feature = "uart_console")] +pub use uart_console::Console; + extern { pub fn flush_cpu_dcache(); pub fn flush_l2_cache(); diff --git a/artiq/firmware/libboard/uart_console.rs b/artiq/firmware/libboard/uart_console.rs new file mode 100644 index 000000000..b43b6064e --- /dev/null +++ b/artiq/firmware/libboard/uart_console.rs @@ -0,0 +1,32 @@ +use core::fmt; + +pub struct Console; + +impl fmt::Write for Console { + fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { + extern { fn putchar(c: i32) -> i32; } + for c in s.bytes() { unsafe { putchar(c as i32); } } + Ok(()) + } +} + +#[macro_export] +macro_rules! print { + ($($arg:tt)*) => ({ + use core::fmt::Write; + write!($crate::uart_console::Console, $($arg)*).unwrap() + }) +} + +#[macro_export] +macro_rules! println { + ($fmt:expr) => (print!(concat!($fmt, "\n"))); + ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); +} + +#[no_mangle] +#[lang = "panic_fmt"] +pub extern fn panic_fmt(args: fmt::Arguments, file: &'static str, line: u32) -> ! { + println!("panic at {}:{}: {}", file, line, args); + loop {} +} diff --git a/artiq/firmware/liblogger_artiq/Cargo.toml b/artiq/firmware/liblogger_artiq/Cargo.toml new file mode 100644 index 000000000..d9e6e2299 --- /dev/null +++ b/artiq/firmware/liblogger_artiq/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors = ["M-Labs"] +name = "logger_artiq" +version = "0.0.0" + +[lib] +name = "logger_artiq" +path = "lib.rs" + +[dependencies] +log = { version = "0.3", default-features = false, features = [] } +log_buffer = { version = "1.0" } +board = { path = "../libboard" } diff --git a/artiq/firmware/runtime/logger.rs b/artiq/firmware/liblogger_artiq/lib.rs similarity index 79% rename from artiq/firmware/runtime/logger.rs rename to artiq/firmware/liblogger_artiq/lib.rs index 6555a8811..6a424eae0 100644 --- a/artiq/firmware/runtime/logger.rs +++ b/artiq/firmware/liblogger_artiq/lib.rs @@ -1,17 +1,23 @@ +#![no_std] + +#[macro_use] +extern crate log; +extern crate log_buffer; +extern crate board; + use core::{mem, ptr}; use core::cell::{Cell, RefCell}; -use log::{self, Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter}; +use core::fmt::Write; +use log::{Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter}; use log_buffer::LogBuffer; -use board; +use board::{Console, clock}; pub struct BufferLogger { - buffer: RefCell>, + buffer: RefCell>, trace_to_uart: Cell } -unsafe impl Sync for BufferLogger {} - -static mut LOGGER: *const BufferLogger = ptr::null(); +static mut LOGGER: *const BufferLogger = 0 as *const _; impl BufferLogger { pub fn new(buffer: &'static mut [u8]) -> BufferLogger { @@ -44,11 +50,11 @@ impl BufferLogger { } pub fn clear(&self) { - borrow_mut!(self.buffer).clear() + self.buffer.borrow_mut().clear() } pub fn extract R>(&self, f: F) -> R { - f(borrow_mut!(self.buffer).extract()) + f(self.buffer.borrow_mut().extract()) } pub fn disable_trace_to_uart(&self) { @@ -60,6 +66,9 @@ impl BufferLogger { } } +// required for impl Log +unsafe impl Sync for BufferLogger {} + impl Log for BufferLogger { fn enabled(&self, _metadata: &LogMetadata) -> bool { true @@ -69,9 +78,8 @@ impl Log for BufferLogger { if self.enabled(record.metadata()) { let force_uart = match self.buffer.try_borrow_mut() { Ok(mut buffer) => { - use core::fmt::Write; writeln!(buffer, "[{:12}us] {:>5}({}): {}", - board::clock::get_us(), record.level(), + clock::get_us(), record.level(), record.target(), record.args()).unwrap(); false } @@ -85,8 +93,9 @@ impl Log for BufferLogger { // 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 || force_uart { - println!("[{:12}us] {:>5}({}): {}", - board::clock::get_us(), record.level(), record.target(), record.args()); + writeln!(Console, "[{:12}us] {:>5}({}): {}", + clock::get_us(), record.level(), + record.target(), record.args()).unwrap(); } } } diff --git a/artiq/firmware/runtime/Cargo.toml b/artiq/firmware/runtime/Cargo.toml index 16ad8e8b5..b1e7fdb18 100644 --- a/artiq/firmware/runtime/Cargo.toml +++ b/artiq/firmware/runtime/Cargo.toml @@ -15,10 +15,10 @@ build_artiq = { path = "../libbuild_artiq" } [dependencies] alloc_artiq = { path = "../liballoc_artiq" } std_artiq = { path = "../libstd_artiq", features = ["alloc"] } -board = { path = "../libboard" } -fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] } +logger_artiq = { path = "../liblogger_artiq" } log = { version = "0.3", default-features = false, features = [] } -log_buffer = { version = "1.0" } +board = { path = "../libboard", features = ["uart_console"] } +fringe = { version = "= 1.1.0", default-features = false, features = ["alloc"] } byteorder = { version = "1.0", default-features = false } [dependencies.smoltcp] diff --git a/artiq/firmware/runtime/lib.rs b/artiq/firmware/runtime/lib.rs index 497353318..ec3fa90a6 100644 --- a/artiq/firmware/runtime/lib.rs +++ b/artiq/firmware/runtime/lib.rs @@ -1,5 +1,5 @@ #![no_std] -#![feature(libc, const_fn, repr_simd, asm, lang_items)] +#![feature(libc, repr_simd)] extern crate alloc_artiq; #[macro_use] @@ -7,56 +7,20 @@ extern crate std_artiq as std; extern crate libc; #[macro_use] extern crate log; -extern crate log_buffer; +extern crate logger_artiq; extern crate byteorder; extern crate fringe; extern crate smoltcp; +#[macro_use] extern crate board; -use core::fmt::Write; use std::boxed::Box; extern { - fn putchar(c: libc::c_int) -> libc::c_int; fn readchar() -> libc::c_char; fn readchar_nonblock() -> libc::c_int; } -#[macro_export] -macro_rules! print { - ($($arg:tt)*) => ($crate::print_fmt(format_args!($($arg)*))); -} - -#[macro_export] -macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -} - -pub struct Console; - -impl core::fmt::Write for Console { - fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { - for c in s.bytes() { unsafe { putchar(c as i32); } } - Ok(()) - } -} - -pub fn print_fmt(args: self::core::fmt::Arguments) { - let _ = Console.write_fmt(args); -} - -#[no_mangle] -#[lang = "panic_fmt"] -pub extern fn panic_fmt(args: self::core::fmt::Arguments, file: &'static str, line: u32) -> ! { - let _ = write!(Console, "panic at {}:{}: {}\n", file, line, args); - let _ = write!(Console, "waiting for debugger...\n"); - unsafe { - let _ = readchar(); - loop { asm!("l.trap 0") } - } -} - macro_rules! borrow_mut { ($x:expr) => ({ match $x.try_borrow_mut() { @@ -74,7 +38,6 @@ mod rpc_queue; mod urc; mod sched; -mod logger; mod cache; mod proto; @@ -96,7 +59,7 @@ mod analyzer; fn startup() { board::uart::set_speed(921600); board::clock::init(); - info!("booting ARTIQ"); + info!("ARTIQ runtime starting..."); info!("software version {}", cfg!(git_describe)); info!("gateware version {}", board::ident(&mut [0; 64])); @@ -176,7 +139,7 @@ pub unsafe extern fn main() -> i32 { &_eheap as *const u8 as usize - &_fheap as *const u8 as usize); static mut LOG_BUFFER: [u8; 65536] = [0; 65536]; - logger::BufferLogger::new(&mut LOG_BUFFER[..]).register(startup); + logger_artiq::BufferLogger::new(&mut LOG_BUFFER[..]).register(startup); 0 } diff --git a/artiq/firmware/runtime/session.rs b/artiq/firmware/runtime/session.rs index b073bbb4f..cd81e7479 100644 --- a/artiq/firmware/runtime/session.rs +++ b/artiq/firmware/runtime/session.rs @@ -4,7 +4,7 @@ use std::cell::RefCell; use std::io::{self, Read, Write}; use std::btree_set::BTreeSet; use {config, rtio_mgt, mailbox, rpc_queue, kernel}; -use logger::BufferLogger; +use logger_artiq::BufferLogger; use cache::Cache; use urc::Urc; use sched::{ThreadHandle, Io}; diff --git a/artiq/firmware/satman/Cargo.toml b/artiq/firmware/satman/Cargo.toml index 1ff6e1bf5..815ae0ea5 100644 --- a/artiq/firmware/satman/Cargo.toml +++ b/artiq/firmware/satman/Cargo.toml @@ -15,6 +15,6 @@ build_artiq = { path = "../libbuild_artiq" } [dependencies] alloc_artiq = { path = "../liballoc_artiq" } std_artiq = { path = "../libstd_artiq", features = ["alloc"] } +logger_artiq = { path = "../liblogger_artiq" } board = { path = "../libboard" } log = { version = "0.3", default-features = false } -log_buffer = { version = "1.0" } diff --git a/artiq/firmware/satman/Makefile b/artiq/firmware/satman/Makefile index 230586203..9aec66566 100644 --- a/artiq/firmware/satman/Makefile +++ b/artiq/firmware/satman/Makefile @@ -7,8 +7,6 @@ OBJECTS := main.o RUSTOUT := cargo/or1k-unknown-none/debug -CFLAGS += -I$(LIBALLOC_DIRECTORY) - LDFLAGS += --gc-sections \ -L../libcompiler-rt \ -L../libbase \ diff --git a/artiq/firmware/satman/lib.rs b/artiq/firmware/satman/lib.rs index 09118cf58..0eafbf6e0 100644 --- a/artiq/firmware/satman/lib.rs +++ b/artiq/firmware/satman/lib.rs @@ -1,60 +1,53 @@ #![no_std] -#![feature(libc, const_fn, repr_simd, asm, lang_items)] extern crate alloc_artiq; #[macro_use] extern crate std_artiq as std; -extern crate libc; #[macro_use] extern crate log; -extern crate log_buffer; +extern crate logger_artiq; extern crate board; -use core::fmt::Write; -use logger::BufferLogger; +fn startup() { + board::clock::init(); + info!("ARTIQ satellite manager starting..."); + info!("software version {}", cfg!(git_describe)); + info!("gateware version {}", board::ident(&mut [0; 64])); + loop {} +} + +use board::{irq, csr}; extern { - fn putchar(c: libc::c_int) -> libc::c_int; - fn readchar() -> libc::c_char; - fn readchar_nonblock() -> libc::c_int; -} + fn uart_init(); + fn uart_isr(); -#[macro_export] -macro_rules! print { - ($($arg:tt)*) => ($crate::print_fmt(format_args!($($arg)*))); -} - -#[macro_export] -macro_rules! println { - ($fmt:expr) => (print!(concat!($fmt, "\n"))); - ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*)); -} - -pub struct Console; - -impl core::fmt::Write for Console { - fn write_str(&mut self, s: &str) -> Result<(), core::fmt::Error> { - for c in s.bytes() { unsafe { putchar(c as i32); } } - Ok(()) - } -} - -pub fn print_fmt(args: self::core::fmt::Arguments) { - let _ = Console.write_fmt(args); + fn alloc_give(ptr: *mut u8, length: usize); + static mut _fheap: u8; + static mut _eheap: u8; } #[no_mangle] -#[lang = "panic_fmt"] -pub extern fn panic_fmt(args: self::core::fmt::Arguments, file: &'static str, line: u32) -> ! { - let _ = write!(Console, "panic at {}:{}: {}\n", file, line, args); - let _ = write!(Console, "waiting for debugger...\n"); - unsafe { - let _ = readchar(); - loop { asm!("l.trap 0") } - } +pub unsafe extern fn main() -> i32 { + irq::set_mask(0); + irq::set_ie(true); + uart_init(); + + alloc_give(&mut _fheap as *mut u8, + &_eheap as *const u8 as usize - &_fheap as *const u8 as usize); + + static mut LOG_BUFFER: [u8; 65536] = [0; 65536]; + logger_artiq::BufferLogger::new(&mut LOG_BUFFER[..]).register(startup); + 0 } -mod logger; +#[no_mangle] +pub unsafe extern fn isr() { + let irqs = irq::pending() & irq::get_mask(); + if irqs & (1 << csr::UART_INTERRUPT) != 0 { + uart_isr() + } +} // Allow linking with crates that are built as -Cpanic=unwind even if we use -Cpanic=abort. // This is never called. @@ -63,29 +56,3 @@ mod logger; pub extern "C" fn _Unwind_Resume() -> ! { loop {} } - -#[no_mangle] -pub unsafe extern fn rust_main() { - static mut LOG_BUFFER: [u8; 65536] = [0; 65536]; - BufferLogger::new(&mut LOG_BUFFER[..]) - .register(move || { - board::clock::init(); - info!("ARTIQ satellite manager starting..."); - info!("software version {}", cfg!(git_describe)); - info!("gateware version {}", board::ident(&mut [0; 64])); - - loop { - } - }) -} - -#[no_mangle] -pub unsafe extern fn isr() { - use board::{irq, csr}; - extern { fn uart_isr(); } - - let irqs = irq::pending() & irq::get_mask(); - if irqs & (1 << csr::UART_INTERRUPT) != 0 { - uart_isr() - } -} diff --git a/artiq/firmware/satman/logger.rs b/artiq/firmware/satman/logger.rs deleted file mode 100644 index 4177f8e24..000000000 --- a/artiq/firmware/satman/logger.rs +++ /dev/null @@ -1,83 +0,0 @@ -use core::{mem, ptr}; -use core::cell::{Cell, RefCell}; -use log::{self, Log, LogLevel, LogMetadata, LogRecord, LogLevelFilter}; -use log_buffer::LogBuffer; -use board; - -pub struct BufferLogger { - buffer: RefCell>, - trace_to_uart: Cell -} - -unsafe impl Sync for BufferLogger {} - -static mut LOGGER: *const BufferLogger = ptr::null(); - -impl BufferLogger { - pub fn new(buffer: &'static mut [u8]) -> BufferLogger { - BufferLogger { - buffer: RefCell::new(LogBuffer::new(buffer)), - trace_to_uart: Cell::new(true) - } - } - - pub fn register(&self, f: F) { - // log::set_logger_raw captures a pointer to ourselves, so we must prevent - // ourselves from being moved or dropped after that function is called (and - // before log::shutdown_logger_raw is called). - unsafe { - log::set_logger_raw(|max_log_level| { - max_log_level.set(LogLevelFilter::Trace); - self as *const Log - }).expect("global logger can only be initialized once"); - LOGGER = self; - } - f(); - log::shutdown_logger_raw().unwrap(); - unsafe { - LOGGER = ptr::null(); - } - } - - pub fn with_instance R>(f: F) -> R { - f(unsafe { mem::transmute::<*const BufferLogger, &BufferLogger>(LOGGER) }) - } - - pub fn clear(&self) { - self.buffer.borrow_mut().clear() - } - - 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 { - fn enabled(&self, _metadata: &LogMetadata) -> bool { - true - } - - fn log(&self, record: &LogRecord) { - if self.enabled(record.metadata()) { - use core::fmt::Write; - writeln!(self.buffer.borrow_mut(), - "[{:12}us] {:>5}({}): {}", - board::clock::get_us(), record.level(), record.target(), record.args()).unwrap(); - - // 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}({}): {}", - board::clock::get_us(), record.level(), record.target(), record.args()); - } - } - } -} diff --git a/artiq/firmware/satman/main.c b/artiq/firmware/satman/main.c deleted file mode 100644 index 92b838013..000000000 --- a/artiq/firmware/satman/main.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include -#include -#include - -extern void _fheap, _eheap; - -extern void rust_main(); - -int main(void) -{ - irq_setmask(0); - irq_setie(1); - uart_init(); - - alloc_give(&_fheap, &_eheap - &_fheap); - - rust_main(); - - return 0; -}