2022-12-02 16:27:03 +08:00
|
|
|
#![feature(lang_items, panic_info_message, const_btree_new, iter_advance_by)]
|
2016-08-17 16:39:05 +08:00
|
|
|
#![no_std]
|
|
|
|
|
2018-08-10 23:24:51 +08:00
|
|
|
extern crate eh;
|
2018-05-15 22:14:27 +08:00
|
|
|
#[macro_use]
|
2017-04-19 17:38:24 +08:00
|
|
|
extern crate alloc;
|
2018-05-15 21:27:23 +08:00
|
|
|
extern crate failure;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate failure_derive;
|
2017-02-03 19:46:45 +08:00
|
|
|
extern crate cslice;
|
2016-09-29 02:25:25 +08:00
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
2016-09-27 21:36:55 +08:00
|
|
|
extern crate byteorder;
|
2016-10-02 12:37:24 +08:00
|
|
|
extern crate fringe;
|
2018-05-05 07:44:51 +08:00
|
|
|
extern crate managed;
|
2017-01-16 22:15:24 +08:00
|
|
|
extern crate smoltcp;
|
2017-02-26 01:54:14 +08:00
|
|
|
|
2017-09-25 01:49:34 +08:00
|
|
|
extern crate alloc_list;
|
2018-05-14 15:32:55 +08:00
|
|
|
extern crate unwind_backtrace;
|
2018-05-15 00:52:14 +08:00
|
|
|
extern crate io;
|
2017-02-26 01:54:14 +08:00
|
|
|
#[macro_use]
|
2018-05-15 01:54:29 +08:00
|
|
|
extern crate board_misoc;
|
|
|
|
extern crate board_artiq;
|
2017-02-26 01:54:14 +08:00
|
|
|
extern crate logger_artiq;
|
2018-05-15 01:58:34 +08:00
|
|
|
extern crate proto_artiq;
|
2021-08-06 11:05:17 +08:00
|
|
|
extern crate riscv;
|
2016-08-17 16:39:05 +08:00
|
|
|
|
2018-09-11 14:12:41 +08:00
|
|
|
use core::cell::RefCell;
|
2018-05-05 07:44:51 +08:00
|
|
|
use core::convert::TryFrom;
|
2022-04-22 17:40:54 +08:00
|
|
|
use smoltcp::wire::HardwareAddress;
|
2017-12-28 03:14:41 +08:00
|
|
|
|
2021-10-08 14:34:56 +08:00
|
|
|
use board_misoc::{csr, ident, clock, spiflash, config, net_settings, pmp, boot};
|
2017-12-28 22:40:15 +08:00
|
|
|
#[cfg(has_ethmac)]
|
2018-05-15 01:54:29 +08:00
|
|
|
use board_misoc::ethmac;
|
2022-04-22 19:14:51 +08:00
|
|
|
use board_misoc::net_settings::{Ipv4AddrConfig};
|
2018-05-15 01:26:36 +08:00
|
|
|
#[cfg(has_drtio)]
|
|
|
|
use board_artiq::drtioaux;
|
2018-09-10 22:48:56 +08:00
|
|
|
use board_artiq::drtio_routing;
|
2018-05-15 01:54:29 +08:00
|
|
|
use board_artiq::{mailbox, rpc_queue};
|
2018-09-10 22:29:35 +08:00
|
|
|
use proto_artiq::{mgmt_proto, moninj_proto, rpc_proto, session_proto, kernel_proto};
|
2018-05-15 01:26:36 +08:00
|
|
|
#[cfg(has_rtio_analyzer)]
|
2018-05-15 01:58:34 +08:00
|
|
|
use proto_artiq::analyzer_proto;
|
2016-08-30 19:20:04 +08:00
|
|
|
|
2021-10-08 14:41:01 +08:00
|
|
|
use riscv::register::{mcause, mepc, mtval};
|
2022-04-22 19:14:51 +08:00
|
|
|
use ip_addr_storage::InterfaceBuilderEx;
|
2021-08-06 11:05:17 +08:00
|
|
|
|
2019-06-14 15:26:30 +08:00
|
|
|
mod rtio_clocking;
|
2016-12-09 19:24:00 +08:00
|
|
|
mod rtio_mgt;
|
2016-09-30 04:56:35 +08:00
|
|
|
|
2016-10-02 12:37:24 +08:00
|
|
|
mod urc;
|
|
|
|
mod sched;
|
2016-10-02 02:24:53 +08:00
|
|
|
mod cache;
|
2017-02-26 10:50:20 +08:00
|
|
|
mod rtio_dma;
|
2016-10-01 12:20:27 +08:00
|
|
|
|
2017-03-29 11:35:45 +08:00
|
|
|
mod mgmt;
|
2016-10-01 12:20:27 +08:00
|
|
|
mod kernel;
|
2017-06-18 12:45:07 +08:00
|
|
|
mod kern_hwreq;
|
2016-09-30 04:56:35 +08:00
|
|
|
mod session;
|
2017-02-25 12:07:00 +08:00
|
|
|
#[cfg(any(has_rtio_moninj, has_drtio))]
|
2016-10-04 20:38:52 +08:00
|
|
|
mod moninj;
|
2016-10-05 13:59:38 +08:00
|
|
|
#[cfg(has_rtio_analyzer)]
|
|
|
|
mod analyzer;
|
2022-01-15 00:52:12 +08:00
|
|
|
mod dhcp;
|
2022-04-22 19:14:51 +08:00
|
|
|
mod ip_addr_storage;
|
2022-01-15 00:52:12 +08:00
|
|
|
|
2019-06-14 15:26:30 +08:00
|
|
|
#[cfg(has_grabber)]
|
|
|
|
fn grabber_thread(io: sched::Io) {
|
|
|
|
loop {
|
|
|
|
board_artiq::grabber::tick();
|
|
|
|
io.sleep(200).unwrap();
|
|
|
|
}
|
|
|
|
}
|
2017-01-16 22:15:24 +08:00
|
|
|
|
2019-06-14 15:26:30 +08:00
|
|
|
fn setup_log_levels() {
|
2018-01-04 22:19:46 +08:00
|
|
|
match config::read_str("log_level", |r| r.map(|s| s.parse())) {
|
|
|
|
Ok(Ok(log_level_filter)) => {
|
|
|
|
info!("log level set to {} by `log_level` config key",
|
|
|
|
log_level_filter);
|
|
|
|
log::set_max_level(log_level_filter);
|
|
|
|
}
|
|
|
|
_ => info!("log level set to INFO by default")
|
|
|
|
}
|
|
|
|
match config::read_str("uart_log_level", |r| r.map(|s| s.parse())) {
|
|
|
|
Ok(Ok(uart_log_level_filter)) => {
|
|
|
|
info!("UART log level set to {} by `uart_log_level` config key",
|
|
|
|
uart_log_level_filter);
|
|
|
|
logger_artiq::BufferLogger::with(|logger|
|
|
|
|
logger.set_uart_log_level(uart_log_level_filter));
|
|
|
|
}
|
|
|
|
_ => info!("UART log level set to INFO by default")
|
|
|
|
}
|
2019-06-14 15:26:30 +08:00
|
|
|
}
|
2018-01-04 22:19:46 +08:00
|
|
|
|
2019-06-14 15:26:30 +08:00
|
|
|
fn startup() {
|
|
|
|
clock::init();
|
|
|
|
info!("ARTIQ runtime starting...");
|
|
|
|
info!("software ident {}", csr::CONFIG_IDENTIFIER_STR);
|
|
|
|
info!("gateware ident {}", ident::read(&mut [0; 64]));
|
2017-12-21 23:08:56 +08:00
|
|
|
|
2019-06-14 15:26:30 +08:00
|
|
|
setup_log_levels();
|
|
|
|
#[cfg(has_i2c)]
|
2019-10-21 12:58:52 +08:00
|
|
|
board_misoc::i2c::init().expect("I2C initialization failed");
|
2020-05-05 21:38:17 +08:00
|
|
|
#[cfg(all(soc_platform = "kasli", hw_rev = "v2.0"))]
|
|
|
|
let (mut io_expander0, mut io_expander1);
|
|
|
|
#[cfg(all(soc_platform = "kasli", hw_rev = "v2.0"))]
|
|
|
|
{
|
2022-12-13 01:24:32 +08:00
|
|
|
io_expander0 = board_misoc::io_expander::IoExpander::new(0).unwrap();
|
|
|
|
io_expander1 = board_misoc::io_expander::IoExpander::new(1).unwrap();
|
2020-05-05 21:38:17 +08:00
|
|
|
io_expander0.init().expect("I2C I/O expander #0 initialization failed");
|
|
|
|
io_expander1.init().expect("I2C I/O expander #1 initialization failed");
|
2020-12-22 00:43:44 +08:00
|
|
|
|
|
|
|
// Actively drive TX_DISABLE to false on SFP0..3
|
2020-08-24 21:32:04 +08:00
|
|
|
io_expander0.set_oe(0, 1 << 1).unwrap();
|
2020-12-22 00:43:44 +08:00
|
|
|
io_expander0.set_oe(1, 1 << 1).unwrap();
|
|
|
|
io_expander1.set_oe(0, 1 << 1).unwrap();
|
|
|
|
io_expander1.set_oe(1, 1 << 1).unwrap();
|
2020-08-24 21:32:04 +08:00
|
|
|
io_expander0.set(0, 1, false);
|
2020-12-22 00:43:44 +08:00
|
|
|
io_expander0.set(1, 1, false);
|
|
|
|
io_expander1.set(0, 1, false);
|
|
|
|
io_expander1.set(1, 1, false);
|
2020-08-24 21:32:04 +08:00
|
|
|
io_expander0.service().unwrap();
|
2020-12-22 00:43:44 +08:00
|
|
|
io_expander1.service().unwrap();
|
2020-05-05 21:38:17 +08:00
|
|
|
}
|
2019-06-14 15:26:30 +08:00
|
|
|
rtio_clocking::init();
|
2018-05-29 10:26:36 +08:00
|
|
|
|
2018-01-19 12:56:11 +08:00
|
|
|
let mut net_device = unsafe { ethmac::EthernetDevice::new() };
|
|
|
|
net_device.reset_phy_if_any();
|
2018-01-04 19:37:52 +08:00
|
|
|
|
2018-02-15 07:03:09 +08:00
|
|
|
let net_device = {
|
2022-01-15 00:51:43 +08:00
|
|
|
use smoltcp::phy::Tracer;
|
2018-02-15 07:03:09 +08:00
|
|
|
|
2022-01-15 00:51:43 +08:00
|
|
|
// We can't create the function pointer as a separate variable here because the type of
|
|
|
|
// the packet argument Packet isn't accessible and rust's type inference isn't sufficient
|
|
|
|
// to propagate in to a local var.
|
2018-02-15 07:03:09 +08:00
|
|
|
match config::read_str("net_trace", |r| r.map(|s| s == "1")) {
|
2022-01-15 00:51:43 +08:00
|
|
|
Ok(true) => Tracer::new(net_device, |timestamp, packet| {
|
|
|
|
print!("\x1b[37m[{:6}.{:03}s]\n{}\x1b[0m\n",
|
|
|
|
timestamp.secs(), timestamp.millis(), packet)
|
|
|
|
}),
|
|
|
|
_ => Tracer::new(net_device, |_, _| {}),
|
2018-02-15 07:03:09 +08:00
|
|
|
}
|
|
|
|
};
|
2018-01-04 19:37:52 +08:00
|
|
|
|
2017-12-19 23:51:03 +08:00
|
|
|
let neighbor_cache =
|
2021-08-06 11:07:47 +08:00
|
|
|
smoltcp::iface::NeighborCache::new(alloc::collections::btree_map::BTreeMap::new());
|
2019-10-19 17:56:35 +08:00
|
|
|
let net_addresses = net_settings::get_adresses();
|
2019-10-21 12:58:52 +08:00
|
|
|
info!("network addresses: {}", net_addresses);
|
2022-04-12 18:39:47 +08:00
|
|
|
let use_dhcp = if matches!(net_addresses.ipv4_addr, Ipv4AddrConfig::UseDhcp) {
|
2022-01-15 00:52:12 +08:00
|
|
|
info!("Will try to acquire an IPv4 address with DHCP");
|
|
|
|
true
|
|
|
|
} else {
|
|
|
|
false
|
2019-10-19 17:14:11 +08:00
|
|
|
};
|
2022-01-15 00:52:12 +08:00
|
|
|
let interface = smoltcp::iface::InterfaceBuilder::new(net_device, vec![])
|
|
|
|
.hardware_addr(HardwareAddress::Ethernet(net_addresses.hardware_addr))
|
2022-04-22 17:40:54 +08:00
|
|
|
.init_ip_addrs(&net_addresses)
|
2022-01-15 00:52:12 +08:00
|
|
|
.neighbor_cache(neighbor_cache)
|
|
|
|
.finalize();
|
2017-01-16 22:15:24 +08:00
|
|
|
|
2018-09-14 20:26:39 +08:00
|
|
|
#[cfg(has_drtio)]
|
2018-09-11 14:12:41 +08:00
|
|
|
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
|
|
|
drtio_routing::config_routing_table(csr::DRTIO.len())));
|
2018-09-14 20:26:39 +08:00
|
|
|
#[cfg(not(has_drtio))]
|
|
|
|
let drtio_routing_table = urc::Urc::new(RefCell::new(
|
|
|
|
drtio_routing::RoutingTable::default_empty()));
|
2018-09-15 19:11:22 +08:00
|
|
|
let up_destinations = urc::Urc::new(RefCell::new(
|
|
|
|
[false; drtio_routing::DEST_COUNT]));
|
2019-01-04 23:38:00 +08:00
|
|
|
#[cfg(has_drtio_routing)]
|
|
|
|
drtio_routing::interconnect_disable_all();
|
2018-09-19 11:16:21 +08:00
|
|
|
let aux_mutex = sched::Mutex::new();
|
2018-09-10 22:48:56 +08:00
|
|
|
|
2022-01-15 00:51:43 +08:00
|
|
|
let mut scheduler = sched::Scheduler::new(interface);
|
2017-01-16 22:15:24 +08:00
|
|
|
let io = scheduler.io();
|
2018-09-10 22:48:56 +08:00
|
|
|
|
2022-01-15 00:52:12 +08:00
|
|
|
if use_dhcp {
|
|
|
|
io.spawn(4096, dhcp::dhcp_thread);
|
|
|
|
}
|
|
|
|
|
2018-09-19 11:16:21 +08:00
|
|
|
rtio_mgt::startup(&io, &aux_mutex, &drtio_routing_table, &up_destinations);
|
2018-09-10 22:48:56 +08:00
|
|
|
|
2017-03-29 11:35:45 +08:00
|
|
|
io.spawn(4096, mgmt::thread);
|
2018-09-14 20:26:39 +08:00
|
|
|
{
|
2018-09-19 11:16:21 +08:00
|
|
|
let aux_mutex = aux_mutex.clone();
|
2018-09-14 20:26:39 +08:00
|
|
|
let drtio_routing_table = drtio_routing_table.clone();
|
2018-09-15 19:11:22 +08:00
|
|
|
let up_destinations = up_destinations.clone();
|
2018-09-19 11:16:21 +08:00
|
|
|
io.spawn(16384, move |io| { session::thread(io, &aux_mutex, &drtio_routing_table, &up_destinations) });
|
2018-09-14 20:26:39 +08:00
|
|
|
}
|
2017-02-25 12:07:00 +08:00
|
|
|
#[cfg(any(has_rtio_moninj, has_drtio))]
|
2018-09-14 20:26:39 +08:00
|
|
|
{
|
2018-09-19 11:16:21 +08:00
|
|
|
let aux_mutex = aux_mutex.clone();
|
2018-09-14 20:26:39 +08:00
|
|
|
let drtio_routing_table = drtio_routing_table.clone();
|
2018-09-19 11:16:21 +08:00
|
|
|
io.spawn(4096, move |io| { moninj::thread(io, &aux_mutex, &drtio_routing_table) });
|
2018-09-14 20:26:39 +08:00
|
|
|
}
|
2017-01-16 22:15:24 +08:00
|
|
|
#[cfg(has_rtio_analyzer)]
|
|
|
|
io.spawn(4096, analyzer::thread);
|
2018-09-10 22:48:56 +08:00
|
|
|
|
2018-05-29 10:26:36 +08:00
|
|
|
#[cfg(has_grabber)]
|
|
|
|
io.spawn(4096, grabber_thread);
|
2017-01-16 22:15:24 +08:00
|
|
|
|
2017-10-30 15:46:23 +08:00
|
|
|
let mut net_stats = ethmac::EthernetStatistics::new();
|
2017-01-16 22:15:24 +08:00
|
|
|
loop {
|
|
|
|
scheduler.run();
|
2022-01-15 00:51:43 +08:00
|
|
|
scheduler.run_network();
|
2017-10-30 15:46:23 +08:00
|
|
|
|
2017-12-15 14:07:16 +08:00
|
|
|
if let Some(_net_stats_diff) = net_stats.update() {
|
2018-03-07 21:28:21 +08:00
|
|
|
debug!("ethernet mac:{}", ethmac::EthernetStatistics::new());
|
2017-10-30 15:46:23 +08:00
|
|
|
}
|
2020-05-05 21:38:17 +08:00
|
|
|
|
|
|
|
#[cfg(all(soc_platform = "kasli", hw_rev = "v2.0"))]
|
|
|
|
{
|
|
|
|
io_expander0.service().expect("I2C I/O expander #0 service failed");
|
|
|
|
io_expander1.service().expect("I2C I/O expander #1 service failed");
|
|
|
|
}
|
2017-01-16 22:15:24 +08:00
|
|
|
}
|
2016-09-07 00:42:13 +08:00
|
|
|
}
|
|
|
|
|
2017-09-25 01:49:34 +08:00
|
|
|
#[global_allocator]
|
|
|
|
static mut ALLOC: alloc_list::ListAlloc = alloc_list::EMPTY;
|
|
|
|
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
|
|
|
|
2017-02-03 20:12:41 +08:00
|
|
|
#[no_mangle]
|
|
|
|
pub extern fn main() -> i32 {
|
|
|
|
unsafe {
|
|
|
|
extern {
|
|
|
|
static mut _fheap: u8;
|
|
|
|
static mut _eheap: u8;
|
2021-10-08 14:34:56 +08:00
|
|
|
static mut _sstack_guard: u8;
|
2017-02-03 20:12:41 +08:00
|
|
|
}
|
2017-09-25 01:49:34 +08:00
|
|
|
ALLOC.add_range(&mut _fheap, &mut _eheap);
|
2017-04-19 17:38:24 +08:00
|
|
|
|
2021-10-08 14:34:56 +08:00
|
|
|
pmp::init_stack_guard(&_sstack_guard as *const u8 as usize);
|
|
|
|
|
|
|
|
logger_artiq::BufferLogger::new(&mut LOG_BUFFER[..]).register(||
|
|
|
|
boot::start_user(startup as usize)
|
|
|
|
);
|
2017-09-25 01:49:34 +08:00
|
|
|
|
2017-02-03 20:12:41 +08:00
|
|
|
0
|
|
|
|
}
|
2016-10-30 05:34:25 +08:00
|
|
|
}
|
|
|
|
|
2021-08-06 11:02:38 +08:00
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct TrapFrame {
|
|
|
|
pub ra: usize,
|
|
|
|
pub t0: usize,
|
|
|
|
pub t1: usize,
|
|
|
|
pub t2: usize,
|
|
|
|
pub t3: usize,
|
|
|
|
pub t4: usize,
|
|
|
|
pub t5: usize,
|
|
|
|
pub t6: usize,
|
|
|
|
pub a0: usize,
|
|
|
|
pub a1: usize,
|
|
|
|
pub a2: usize,
|
|
|
|
pub a3: usize,
|
|
|
|
pub a4: usize,
|
|
|
|
pub a5: usize,
|
|
|
|
pub a6: usize,
|
|
|
|
pub a7: usize,
|
|
|
|
}
|
|
|
|
|
2016-08-17 16:39:05 +08:00
|
|
|
#[no_mangle]
|
2021-08-06 11:02:38 +08:00
|
|
|
pub extern fn exception(regs: *const TrapFrame) {
|
2021-08-25 15:22:19 +08:00
|
|
|
let pc = mepc::read();
|
|
|
|
let cause = mcause::read().cause();
|
|
|
|
match cause {
|
|
|
|
mcause::Trap::Interrupt(source) => {
|
|
|
|
info!("Called interrupt with {:?}", source);
|
|
|
|
},
|
2021-10-08 14:38:30 +08:00
|
|
|
|
|
|
|
mcause::Trap::Exception(mcause::Exception::UserEnvCall) => {
|
|
|
|
unsafe {
|
|
|
|
if (*regs).a7 == 0 {
|
|
|
|
pmp::pop_pmp_region()
|
|
|
|
} else {
|
|
|
|
pmp::push_pmp_region((*regs).a7)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mepc::write(pc + 4);
|
|
|
|
},
|
|
|
|
|
2021-08-25 15:22:19 +08:00
|
|
|
mcause::Trap::Exception(e) => {
|
|
|
|
println!("Trap frame: {:x?}", unsafe { *regs });
|
|
|
|
|
|
|
|
fn hexdump(addr: u32) {
|
|
|
|
let addr = (addr - addr % 4) as *const u32;
|
|
|
|
let mut ptr = addr;
|
|
|
|
println!("@ {:08p}", ptr);
|
|
|
|
for _ in 0..4 {
|
|
|
|
print!("+{:04x}: ", ptr as usize - addr as usize);
|
|
|
|
print!("{:08x} ", unsafe { *ptr }); ptr = ptr.wrapping_offset(1);
|
|
|
|
print!("{:08x} ", unsafe { *ptr }); ptr = ptr.wrapping_offset(1);
|
|
|
|
print!("{:08x} ", unsafe { *ptr }); ptr = ptr.wrapping_offset(1);
|
|
|
|
print!("{:08x}\n", unsafe { *ptr }); ptr = ptr.wrapping_offset(1);
|
2018-06-02 05:17:59 +08:00
|
|
|
}
|
2021-08-06 11:02:38 +08:00
|
|
|
}
|
2021-08-25 15:22:19 +08:00
|
|
|
|
|
|
|
hexdump(u32::try_from(pc).unwrap());
|
2021-10-08 14:41:01 +08:00
|
|
|
let mtval = mtval::read();
|
|
|
|
panic!("exception {:?} at PC 0x{:x}, trap value 0x{:x}", e, u32::try_from(pc).unwrap(), mtval)
|
2018-06-02 05:17:59 +08:00
|
|
|
}
|
2018-05-05 07:44:51 +08:00
|
|
|
}
|
2016-08-17 16:39:05 +08:00
|
|
|
}
|
2016-10-06 23:35:43 +08:00
|
|
|
|
2016-10-07 14:27:10 +08:00
|
|
|
#[no_mangle]
|
2017-02-03 20:12:41 +08:00
|
|
|
pub extern fn abort() {
|
2017-12-26 01:55:20 +08:00
|
|
|
println!("aborted");
|
|
|
|
loop {}
|
2016-10-07 14:27:10 +08:00
|
|
|
}
|
|
|
|
|
2018-08-10 23:24:51 +08:00
|
|
|
#[no_mangle] // https://github.com/rust-lang/rust/issues/{38281,51647}
|
|
|
|
#[lang = "oom"] // https://github.com/rust-lang/rust/issues/51540
|
|
|
|
pub fn oom(layout: core::alloc::Layout) -> ! {
|
|
|
|
panic!("heap view: {}\ncannot allocate layout: {:?}", unsafe { &ALLOC }, layout)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle] // https://github.com/rust-lang/rust/issues/{38281,51647}
|
2021-08-06 10:57:38 +08:00
|
|
|
#[panic_handler]
|
2018-08-10 23:24:51 +08:00
|
|
|
pub fn panic_impl(info: &core::panic::PanicInfo) -> ! {
|
2020-05-07 19:06:10 +08:00
|
|
|
#[cfg(has_error_led)]
|
|
|
|
unsafe {
|
|
|
|
csr::error_led::out_write(1);
|
|
|
|
}
|
|
|
|
|
2018-08-10 23:24:51 +08:00
|
|
|
if let Some(location) = info.location() {
|
|
|
|
print!("panic at {}:{}:{}", location.file(), location.line(), location.column());
|
|
|
|
} else {
|
|
|
|
print!("panic at unknown location");
|
|
|
|
}
|
|
|
|
if let Some(message) = info.message() {
|
2019-12-18 03:59:59 +08:00
|
|
|
println!(": {}", message);
|
2018-08-10 23:24:51 +08:00
|
|
|
} else {
|
|
|
|
println!("");
|
|
|
|
}
|
2017-03-14 17:02:28 +08:00
|
|
|
|
2018-07-15 17:21:17 +08:00
|
|
|
println!("backtrace for software version {}:", csr::CONFIG_IDENTIFIER_STR);
|
2018-05-14 15:32:55 +08:00
|
|
|
let _ = unwind_backtrace::backtrace(|ip| {
|
2021-08-06 10:57:38 +08:00
|
|
|
// Backtrace gives us the return address, i.e. the address after jal(r) insn,
|
2018-05-17 16:13:39 +08:00
|
|
|
// but we're interested in the call instruction.
|
2021-08-06 10:57:38 +08:00
|
|
|
println!("{:#08x}", ip - 4);
|
2017-12-26 01:55:20 +08:00
|
|
|
});
|
|
|
|
|
2021-08-06 15:08:30 +08:00
|
|
|
if config::read_str("panic_reset", |r| r == Ok("1")) &&
|
2023-01-06 17:41:12 +08:00
|
|
|
cfg!(any(soc_platform = "kasli", soc_platform = "kc705")) {
|
2017-12-28 21:17:49 +08:00
|
|
|
println!("restarting...");
|
2020-07-01 04:44:36 +08:00
|
|
|
unsafe {
|
|
|
|
kernel::stop();
|
2021-08-05 17:00:31 +08:00
|
|
|
spiflash::reload();
|
2020-07-01 04:44:36 +08:00
|
|
|
}
|
2017-03-14 17:02:28 +08:00
|
|
|
} else {
|
2017-04-15 15:29:21 +08:00
|
|
|
println!("halting.");
|
2019-09-11 02:30:38 +08:00
|
|
|
println!("use `artiq_coremgmt config write -s panic_reset 1` to restart instead");
|
2017-03-14 17:02:28 +08:00
|
|
|
loop {}
|
|
|
|
}
|
|
|
|
}
|