diff --git a/src/Makefile b/src/Makefile index e2dc094..393676e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,11 @@ TARGET := zc706 GWARGS := -V simple -all: ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin +all: runtime + +runtime: ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin + +satman: ../build/firmware/armv7-none-eabihf/release/satman ../build/satman.bin .PHONY: all @@ -19,3 +23,14 @@ all: ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin ../build/runtime.bin: ../build/firmware/armv7-none-eabihf/release/runtime llvm-objcopy -O binary ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin + + +../build/firmware/armv7-none-eabihf/release/satman: ../build/pl.rs ../build/rustc-cfg $(shell find . -print) + cd satman && \ + XBUILD_SYSROOT_PATH=`pwd`/../../build/sysroot \ + cargo xbuild --release \ + --target-dir ../../build/firmware \ + --no-default-features --features=target_$(TARGET) + +../build/satman.bin: ../build/firmware/armv7-none-eabihf/release/satman + llvm-objcopy -O binary ../build/firmware/armv7-none-eabihf/release/satman ../build/satman.bin diff --git a/src/libboard_artiq/src/lib.rs b/src/libboard_artiq/src/lib.rs index 8376b1d..dce8082 100644 --- a/src/libboard_artiq/src/lib.rs +++ b/src/libboard_artiq/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![feature(never_type)] extern crate log; extern crate libboard_zynq; diff --git a/src/satman/Cargo.toml b/src/satman/Cargo.toml index bb3a5ce..f4fdbd6 100644 --- a/src/satman/Cargo.toml +++ b/src/satman/Cargo.toml @@ -9,15 +9,23 @@ name = "satman" crate-type = ["staticlib"] path = "main.rs" +[features] +target_zc706 = ["libboard_zynq/target_zc706", "libsupport_zynq/target_zc706", "libconfig/target_zc706"] +target_kasli_soc = ["libboard_zynq/target_kasli_soc", "libsupport_zynq/target_kasli_soc", "libconfig/target_kasli_soc"] +default = ["target_zc706"] + [build-dependencies] build_zynq = { path = "../libbuild_zynq" } [dependencies] log = { version = "0.4", default-features = false } +embedded-hal = "0.2" + libboard_zynq = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git", features = ["ipv6"]} libsupport_zynq = { default-features = false, features = ["alloc_core"], git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } libcortex_a9 = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } libasync = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } libregister = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" } libconfig = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git", features = ["ipv6"] } + libboard_artiq = { path = "../libboard_artiq" } diff --git a/src/satman/main.rs b/src/satman/main.rs index 8058ebe..2f2f0c8 100644 --- a/src/satman/main.rs +++ b/src/satman/main.rs @@ -1,16 +1,33 @@ -#![feature(never_type, panic_implementation, panic_info_message, const_slice_len, try_from)] +#![feature(never_type, panic_info_message, const_slice_len, try_from, asm, naked_functions)] +#![feature(alloc_error_handler)] #![no_std] +#![no_main] #[macro_use] extern crate log; -use core::convert::TryFrom; -use libboard_zynq::i2c::I2c; -use libboard_zynq::timer::GlobalTimer; +extern crate embedded_hal; + +extern crate libboard_zynq; +extern crate libboard_artiq; +extern crate libsupport_zynq; +extern crate libcortex_a9; +extern crate libregister; + +extern crate alloc; + +use libboard_zynq::{i2c::I2c, timer::GlobalTimer, time::Milliseconds, print, println, mpcore, gic}; +use libsupport_zynq::ram; #[cfg(has_si5324)] use libboard_artiq::si5324; -// use libboard_zynq::spi; // not yet supported in board/csr use libboard_artiq::{pl::csr, drtio_routing, drtioaux, logger, identifier_read}; +use libcortex_a9::{spin_lock_yield, interrupt_handler, regs::{MPIDR, SP}, notify_spin_lock, asm, l2c::enable_l2_cache}; + +use embedded_hal::blocking::delay::DelayUs; + +use core::sync::atomic::{AtomicBool, Ordering}; + +use libregister::{RegisterW, RegisterR}; mod repeater; @@ -230,33 +247,33 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], drtioaux::send(0, &drtioaux::Packet::InjectionStatusReply { value: value }) }, - drtioaux::Packet::I2cStartRequest { destination: _destination, busno } => { + drtioaux::Packet::I2cStartRequest { destination: _destination, _busno } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - let succeeded = i2c.start(busno).is_ok(); + let succeeded = i2c.start().is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::I2cRestartRequest { destination: _destination, busno } => { + drtioaux::Packet::I2cRestartRequest { destination: _destination, _busno } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - let succeeded = i2c.restart(busno).is_ok(); + let succeeded = i2c.restart().is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::I2cStopRequest { destination: _destination, busno } => { + drtioaux::Packet::I2cStopRequest { destination: _destination, _busno } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - let succeeded = i2c.stop(busno).is_ok(); + let succeeded = i2c.stop().is_ok(); drtioaux::send(0, &drtioaux::Packet::I2cBasicReply { succeeded: succeeded }) } - drtioaux::Packet::I2cWriteRequest { destination: _destination, busno, data } => { + drtioaux::Packet::I2cWriteRequest { destination: _destination, _busno, data } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - match i2c.write(busno, data) { + match i2c.write(data) { Ok(ack) => drtioaux::send(0, &drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }), Err(_) => drtioaux::send(0, &drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false }) } } - drtioaux::Packet::I2cReadRequest { destination: _destination, busno, ack } => { + drtioaux::Packet::I2cReadRequest { destination: _destination, _busno, ack } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); - match i2c.read(busno, ack) { + match i2c.read(ack) { Ok(data) => drtioaux::send(0, &drtioaux::Packet::I2cReadReply { succeeded: true, data: data }), Err(_) => drtioaux::send(0, @@ -271,14 +288,14 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], drtioaux::send(0, &drtioaux::Packet::SpiBasicReply { succeeded: false}) }, - drtioaux::Packet::SpiWriteRequest { destination: _destination, busno, data } => { + drtioaux::Packet::SpiWriteRequest { destination: _destination, _busno, data } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); // todo: reimplement when SPI is available //let succeeded = spi::write(busno, data).is_ok(); drtioaux::send(0, &drtioaux::Packet::SpiBasicReply { succeeded: false }) } - drtioaux::Packet::SpiReadRequest { destination: _destination, busno } => { + drtioaux::Packet::SpiReadRequest { destination: _destination, _busno } => { forward!(_routing_table, _destination, *_rank, _repeaters, &packet); // todo: reimplement when SPI is available // match spi::read(busno) { @@ -308,7 +325,7 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater], fn process_aux_packets(repeaters: &mut [repeater::Repeater], routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8, - timer::GlobalTimer, i2c: I2c) { + timer: GlobalTimer, i2c: I2c) { let result = drtioaux::recv(0).and_then(|packet| { if let Some(packet) = packet { @@ -379,8 +396,10 @@ fn init_rtio_crg(timer: GlobalTimer) { } fn hardware_tick(ts: &mut u64, timer: GlobalTimer) { let now = timer.get_time(); - if now > *ts { - *ts = now + 200; + let mut ts_ms = Milliseconds(*ts); + if now > ts_ms { + ts_ms = now + Milliseconds(200); + *ts = ts_ms.0; } } @@ -410,8 +429,12 @@ const SI5324_SETTINGS: si5324::FrequencySettings crystal_ref: true }; +static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17]; + #[no_mangle] -pub extern fn main() -> i32 { +pub extern fn main_core0() -> i32 { + enable_l2_cache(0x8); + let mut timer = GlobalTimer::start(); let buffer_logger = unsafe { @@ -420,10 +443,13 @@ pub extern fn main() -> i32 { buffer_logger.set_uart_log_level(log::LevelFilter::Info); buffer_logger.register(); + //probably will have to copy init_gateware() from runtime here too + info!("ARTIQ satellite manager starting..."); - info!("software ident {}", csr::CONFIG_IDENTIFIER_STR); info!("gateware ident {}", identifier_read(&mut [0; 64])); + ram::init_alloc_core0(); + let mut i2c = I2c::i2c0(); i2c.init().expect("I2C initialization failed"); @@ -488,7 +514,7 @@ pub extern fn main() -> i32 { io_expander0.service().expect("I2C I/O expander #0 service failed"); io_expander1.service().expect("I2C I/O expander #1 service failed"); } - hardware_tick(&mut hardware_tick_ts); + hardware_tick(&mut hardware_tick_ts, timer); } info!("uplink is up, switching to recovered clock"); @@ -536,6 +562,49 @@ pub extern fn main() -> i32 { } } +extern "C" { + static mut __stack1_start: u32; +} + +interrupt_handler!(IRQ, irq, __irq_stack0_start, __irq_stack1_start, { + if MPIDR.read().cpu_id() == 1{ + let mpcore = mpcore::RegisterBlock::mpcore(); + let mut gic = gic::InterruptController::gic(mpcore); + let id = gic.get_interrupt_id(); + if id.0 == 0 { + gic.end_interrupt(id); + asm::exit_irq(); + SP.write(&mut __stack1_start as *mut _ as u32); + asm::enable_irq(); + CORE1_RESTART.store(false, Ordering::Relaxed); + notify_spin_lock(); + main_core1(); + } + } + loop {} +}); + +static mut PANICKED: [bool; 2] = [false; 2]; + +static CORE1_RESTART: AtomicBool = AtomicBool::new(false); + +pub fn restart_core1() { + let mut interrupt_controller = gic::InterruptController::gic(mpcore::RegisterBlock::mpcore()); + CORE1_RESTART.store(true, Ordering::Relaxed); + interrupt_controller.send_sgi(gic::InterruptId(0), gic::CPUCore::Core1.into()); + while CORE1_RESTART.load(Ordering::Relaxed) { + spin_lock_yield(); + } +} + +#[no_mangle] +pub fn main_core1() { + let mut interrupt_controller = gic::InterruptController::gic(mpcore::RegisterBlock::mpcore()); + interrupt_controller.enable_interrupts(); + + loop {} +} + #[no_mangle] pub extern fn exception(vect: u32, _regs: *const u32, pc: u32, ea: u32) { @@ -564,22 +633,29 @@ pub extern fn abort() { } #[no_mangle] // https://github.com/rust-lang/rust/issues/{38281,51647} -#[panic_implementation] +#[panic_handler] pub fn panic_fmt(info: &core::panic::PanicInfo) -> ! { - #[cfg(has_error_led)] + let id = MPIDR.read().cpu_id() as usize; + print!("Core {} ", id); unsafe { - csr::error_led::out_write(1); + if PANICKED[id] { + println!("nested panic!"); + loop {} + } + PANICKED[id] = true; } - + print!("panic at "); if let Some(location) = info.location() { - print!("panic at {}:{}:{}", location.file(), location.line(), location.column()); + print!("{}:{}:{}", location.file(), location.line(), location.column()); } else { - print!("panic at unknown location"); + print!("unknown location"); } if let Some(message) = info.message() { println!(": {}", message); } else { println!(""); } + + loop {} } diff --git a/src/satman/repeater.rs b/src/satman/repeater.rs index 82a716b..ef9145c 100644 --- a/src/satman/repeater.rs +++ b/src/satman/repeater.rs @@ -2,7 +2,8 @@ use libboard_artiq::{drtioaux, drtio_routing}; #[cfg(has_drtio_routing)] use libboard_artiq::{pl::csr}; #[cfg(has_drtio_routing)] -use libboard_zynq::timer::{GlobalTimer, Milliseconds}; +use libboard_zynq::time::Milliseconds; +use libboard_zynq::timer::GlobalTimer; #[cfg(has_drtio_routing)] fn rep_link_rx_up(repno: u8) -> bool {