satman:
* added Zynq-specific impls of basic functions (main/panic/irq) * added makefile definition * fixed drtioaux compilation error (feature never_type)
This commit is contained in:
parent
ecc8a0ccc0
commit
f45fa28dac
17
src/Makefile
17
src/Makefile
@ -1,7 +1,11 @@
|
|||||||
TARGET := zc706
|
TARGET := zc706
|
||||||
GWARGS := -V simple
|
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
|
.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
|
../build/runtime.bin: ../build/firmware/armv7-none-eabihf/release/runtime
|
||||||
llvm-objcopy -O binary ../build/firmware/armv7-none-eabihf/release/runtime ../build/runtime.bin
|
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
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![feature(never_type)]
|
||||||
|
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate libboard_zynq;
|
extern crate libboard_zynq;
|
||||||
|
@ -9,15 +9,23 @@ name = "satman"
|
|||||||
crate-type = ["staticlib"]
|
crate-type = ["staticlib"]
|
||||||
path = "main.rs"
|
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-dependencies]
|
||||||
build_zynq = { path = "../libbuild_zynq" }
|
build_zynq = { path = "../libbuild_zynq" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = { version = "0.4", default-features = false }
|
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"]}
|
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" }
|
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" }
|
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" }
|
libasync = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git" }
|
||||||
libregister = { 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"] }
|
libconfig = { git = "https://git.m-labs.hk/M-Labs/zynq-rs.git", features = ["ipv6"] }
|
||||||
|
|
||||||
libboard_artiq = { path = "../libboard_artiq" }
|
libboard_artiq = { path = "../libboard_artiq" }
|
||||||
|
@ -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_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
use core::convert::TryFrom;
|
extern crate embedded_hal;
|
||||||
use libboard_zynq::i2c::I2c;
|
|
||||||
use libboard_zynq::timer::GlobalTimer;
|
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)]
|
#[cfg(has_si5324)]
|
||||||
use libboard_artiq::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 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;
|
mod repeater;
|
||||||
|
|
||||||
@ -230,33 +247,33 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
|||||||
drtioaux::send(0, &drtioaux::Packet::InjectionStatusReply { value: value })
|
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);
|
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::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);
|
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::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);
|
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::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);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
||||||
match i2c.write(busno, data) {
|
match i2c.write(data) {
|
||||||
Ok(ack) => drtioaux::send(0,
|
Ok(ack) => drtioaux::send(0,
|
||||||
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
&drtioaux::Packet::I2cWriteReply { succeeded: true, ack: ack }),
|
||||||
Err(_) => drtioaux::send(0,
|
Err(_) => drtioaux::send(0,
|
||||||
&drtioaux::Packet::I2cWriteReply { succeeded: false, ack: false })
|
&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);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
||||||
match i2c.read(busno, ack) {
|
match i2c.read(ack) {
|
||||||
Ok(data) => drtioaux::send(0,
|
Ok(data) => drtioaux::send(0,
|
||||||
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }),
|
&drtioaux::Packet::I2cReadReply { succeeded: true, data: data }),
|
||||||
Err(_) => drtioaux::send(0,
|
Err(_) => drtioaux::send(0,
|
||||||
@ -271,14 +288,14 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
|||||||
drtioaux::send(0,
|
drtioaux::send(0,
|
||||||
&drtioaux::Packet::SpiBasicReply { succeeded: false})
|
&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);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
||||||
// todo: reimplement when SPI is available
|
// todo: reimplement when SPI is available
|
||||||
//let succeeded = spi::write(busno, data).is_ok();
|
//let succeeded = spi::write(busno, data).is_ok();
|
||||||
drtioaux::send(0,
|
drtioaux::send(0,
|
||||||
&drtioaux::Packet::SpiBasicReply { succeeded: false })
|
&drtioaux::Packet::SpiBasicReply { succeeded: false })
|
||||||
}
|
}
|
||||||
drtioaux::Packet::SpiReadRequest { destination: _destination, busno } => {
|
drtioaux::Packet::SpiReadRequest { destination: _destination, _busno } => {
|
||||||
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
forward!(_routing_table, _destination, *_rank, _repeaters, &packet);
|
||||||
// todo: reimplement when SPI is available
|
// todo: reimplement when SPI is available
|
||||||
// match spi::read(busno) {
|
// match spi::read(busno) {
|
||||||
@ -308,7 +325,7 @@ fn process_aux_packet(_repeaters: &mut [repeater::Repeater],
|
|||||||
|
|
||||||
fn process_aux_packets(repeaters: &mut [repeater::Repeater],
|
fn process_aux_packets(repeaters: &mut [repeater::Repeater],
|
||||||
routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8,
|
routing_table: &mut drtio_routing::RoutingTable, rank: &mut u8,
|
||||||
timer::GlobalTimer, i2c: I2c) {
|
timer: GlobalTimer, i2c: I2c) {
|
||||||
let result =
|
let result =
|
||||||
drtioaux::recv(0).and_then(|packet| {
|
drtioaux::recv(0).and_then(|packet| {
|
||||||
if let Some(packet) = packet {
|
if let Some(packet) = packet {
|
||||||
@ -379,8 +396,10 @@ fn init_rtio_crg(timer: GlobalTimer) { }
|
|||||||
|
|
||||||
fn hardware_tick(ts: &mut u64, timer: GlobalTimer) {
|
fn hardware_tick(ts: &mut u64, timer: GlobalTimer) {
|
||||||
let now = timer.get_time();
|
let now = timer.get_time();
|
||||||
if now > *ts {
|
let mut ts_ms = Milliseconds(*ts);
|
||||||
*ts = now + 200;
|
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
|
crystal_ref: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static mut LOG_BUFFER: [u8; 1<<17] = [0; 1<<17];
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn main() -> i32 {
|
pub extern fn main_core0() -> i32 {
|
||||||
|
enable_l2_cache(0x8);
|
||||||
|
|
||||||
let mut timer = GlobalTimer::start();
|
let mut timer = GlobalTimer::start();
|
||||||
|
|
||||||
let buffer_logger = unsafe {
|
let buffer_logger = unsafe {
|
||||||
@ -420,10 +443,13 @@ pub extern fn main() -> i32 {
|
|||||||
buffer_logger.set_uart_log_level(log::LevelFilter::Info);
|
buffer_logger.set_uart_log_level(log::LevelFilter::Info);
|
||||||
buffer_logger.register();
|
buffer_logger.register();
|
||||||
|
|
||||||
|
//probably will have to copy init_gateware() from runtime here too
|
||||||
|
|
||||||
info!("ARTIQ satellite manager starting...");
|
info!("ARTIQ satellite manager starting...");
|
||||||
info!("software ident {}", csr::CONFIG_IDENTIFIER_STR);
|
|
||||||
info!("gateware ident {}", identifier_read(&mut [0; 64]));
|
info!("gateware ident {}", identifier_read(&mut [0; 64]));
|
||||||
|
|
||||||
|
ram::init_alloc_core0();
|
||||||
|
|
||||||
let mut i2c = I2c::i2c0();
|
let mut i2c = I2c::i2c0();
|
||||||
i2c.init().expect("I2C initialization failed");
|
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_expander0.service().expect("I2C I/O expander #0 service failed");
|
||||||
io_expander1.service().expect("I2C I/O expander #1 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");
|
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]
|
#[no_mangle]
|
||||||
pub extern fn exception(vect: u32, _regs: *const u32, pc: u32, ea: u32) {
|
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}
|
#[no_mangle] // https://github.com/rust-lang/rust/issues/{38281,51647}
|
||||||
#[panic_implementation]
|
#[panic_handler]
|
||||||
pub fn panic_fmt(info: &core::panic::PanicInfo) -> ! {
|
pub fn panic_fmt(info: &core::panic::PanicInfo) -> ! {
|
||||||
#[cfg(has_error_led)]
|
let id = MPIDR.read().cpu_id() as usize;
|
||||||
|
print!("Core {} ", id);
|
||||||
unsafe {
|
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() {
|
if let Some(location) = info.location() {
|
||||||
print!("panic at {}:{}:{}", location.file(), location.line(), location.column());
|
print!("{}:{}:{}", location.file(), location.line(), location.column());
|
||||||
} else {
|
} else {
|
||||||
print!("panic at unknown location");
|
print!("unknown location");
|
||||||
}
|
}
|
||||||
if let Some(message) = info.message() {
|
if let Some(message) = info.message() {
|
||||||
println!(": {}", message);
|
println!(": {}", message);
|
||||||
} else {
|
} else {
|
||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,8 @@ use libboard_artiq::{drtioaux, drtio_routing};
|
|||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
use libboard_artiq::{pl::csr};
|
use libboard_artiq::{pl::csr};
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
use libboard_zynq::timer::{GlobalTimer, Milliseconds};
|
use libboard_zynq::time::Milliseconds;
|
||||||
|
use libboard_zynq::timer::GlobalTimer;
|
||||||
|
|
||||||
#[cfg(has_drtio_routing)]
|
#[cfg(has_drtio_routing)]
|
||||||
fn rep_link_rx_up(repno: u8) -> bool {
|
fn rep_link_rx_up(repno: u8) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user