artiq/artiq/firmware/runtime/lib.rs

160 lines
4.1 KiB
Rust
Raw Normal View History

2016-08-17 16:39:05 +08:00
#![no_std]
#![feature(libc, repr_simd)]
2016-08-17 16:39:05 +08:00
extern crate alloc_artiq;
2016-08-17 16:39:05 +08:00
#[macro_use]
extern crate std_artiq as std;
extern crate libc;
2016-09-29 02:25:25 +08:00
#[macro_use]
extern crate log;
extern crate logger_artiq;
extern crate byteorder;
extern crate fringe;
extern crate smoltcp;
#[macro_use]
2016-12-31 21:32:50 +08:00
extern crate board;
2016-08-17 16:39:05 +08:00
use std::boxed::Box;
2016-08-30 19:20:04 +08:00
extern {
fn readchar() -> libc::c_char;
fn readchar_nonblock() -> libc::c_int;
}
macro_rules! borrow_mut {
($x:expr) => ({
match $x.try_borrow_mut() {
Ok(x) => x,
Err(_) => panic!("cannot borrow mutably at {}:{}", file!(), line!())
}
})
}
2016-09-30 04:56:35 +08:00
mod config;
mod ethmac;
2016-12-09 19:24:00 +08:00
mod rtio_mgt;
2016-09-30 08:15:20 +08:00
mod mailbox;
mod rpc_queue;
2016-09-30 04:56:35 +08:00
mod urc;
mod sched;
2016-10-02 02:24:53 +08:00
mod cache;
2016-09-30 04:56:35 +08:00
2016-10-04 20:38:52 +08:00
mod proto;
mod kernel_proto;
2016-09-30 04:56:35 +08:00
mod session_proto;
#[cfg(has_rtio_moninj)]
2016-10-04 20:38:52 +08:00
mod moninj_proto;
#[cfg(has_rtio_analyzer)]
2016-10-05 13:59:38 +08:00
mod analyzer_proto;
mod rpc_proto;
mod kernel;
2016-09-30 04:56:35 +08:00
mod session;
#[cfg(has_rtio_moninj)]
2016-10-04 20:38:52 +08:00
mod moninj;
2016-10-05 13:59:38 +08:00
#[cfg(has_rtio_analyzer)]
mod analyzer;
fn startup() {
board::clock::init();
info!("ARTIQ runtime starting...");
info!("software version {}", cfg!(git_describe));
info!("gateware version {}", board::ident(&mut [0; 64]));
let t = board::clock::get_ms();
info!("press 'e' to erase startup and idle kernels...");
while board::clock::get_ms() < t + 1000 {
if unsafe { readchar_nonblock() != 0 && readchar() == b'e' as libc::c_char } {
config::remove("startup_kernel");
config::remove("idle_kernel");
info!("startup and idle kernels erased");
break
}
}
info!("continuing boot");
#[cfg(has_i2c)]
board::i2c::init();
#[cfg(has_ad9516)]
board::ad9516::init().expect("cannot initialize ad9516");
#[cfg(has_converter_spi)]
board::ad9154::init().expect("cannot initialize ad9154");
fn _net_trace_writer<U>(printer: smoltcp::wire::PrettyPrinter<U>)
where U: smoltcp::wire::pretty_print::PrettyPrint {
print!("\x1b[37m{}\x1b[0m", printer)
}
let net_device = ethmac::EthernetDevice;
// let net_device = smoltcp::phy::Tracer::<_, smoltcp::wire::EthernetFrame<&[u8]>>
// ::new(net_device, _net_trace_writer);
let arp_cache = smoltcp::iface::SliceArpCache::new([Default::default(); 8]);
let hardware_addr = smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
let protocol_addrs = [smoltcp::wire::IpAddress::v4(192, 168, 1, 50)];
let mut interface = smoltcp::iface::EthernetInterface::new(
Box::new(net_device), Box::new(arp_cache) as Box<smoltcp::iface::ArpCache>,
hardware_addr, protocol_addrs);
let mut scheduler = sched::Scheduler::new();
let io = scheduler.io();
rtio_mgt::startup(&io);
io.spawn(16384, session::thread);
#[cfg(has_rtio_moninj)]
io.spawn(4096, moninj::thread);
#[cfg(has_rtio_analyzer)]
io.spawn(4096, analyzer::thread);
loop {
scheduler.run();
match interface.poll(&mut *borrow_mut!(scheduler.sockets()),
board::clock::get_ms()) {
Ok(()) => (),
Err(smoltcp::Error::Exhausted) => (),
Err(smoltcp::Error::Unrecognized) => (),
Err(e) => warn!("network error: {}", e)
}
}
}
use board::{irq, csr};
extern {
fn uart_init();
fn uart_isr();
2016-09-30 06:04:52 +08:00
fn alloc_give(ptr: *mut u8, length: usize);
static mut _fheap: u8;
static mut _eheap: u8;
}
2016-08-17 16:39:05 +08:00
#[no_mangle]
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
2016-08-17 16:39:05 +08:00
}
2016-10-07 14:27:10 +08:00
#[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.
#[allow(non_snake_case)]
#[no_mangle]
pub extern "C" fn _Unwind_Resume() -> ! {
loop {}
}