From a78e493b728174b77bbf751e3d474fa60cbcec8a Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 31 Oct 2019 12:42:09 +0800 Subject: [PATCH] firmware: load slave FPGA in bootloader --- artiq/firmware/bootloader/main.rs | 41 +++++++++++++++++++ artiq/firmware/libboard_artiq/lib.rs | 2 - artiq/firmware/libboard_misoc/lib.rs | 4 ++ .../slave_fpga.rs | 33 ++------------- artiq/firmware/runtime/main.rs | 3 -- artiq/firmware/satman/main.rs | 3 -- 6 files changed, 48 insertions(+), 38 deletions(-) rename artiq/firmware/{libboard_artiq => libboard_misoc}/slave_fpga.rs (71%) diff --git a/artiq/firmware/bootloader/main.rs b/artiq/firmware/bootloader/main.rs index 2c7e8a959..84fde93ac 100644 --- a/artiq/firmware/bootloader/main.rs +++ b/artiq/firmware/bootloader/main.rs @@ -11,6 +11,8 @@ use core::{ptr, slice}; use crc::crc32; use byteorder::{ByteOrder, BigEndian}; use board_misoc::{ident, cache, sdram, boot, mem as board_mem}; +#[cfg(has_slave_fpga_cfg)] +use board_misoc::slave_fpga; #[cfg(has_ethmac)] use board_misoc::{clock, ethmac, net_settings}; use board_misoc::uart_console::Console; @@ -110,6 +112,43 @@ fn startup() -> bool { true } +#[cfg(has_slave_fpga_cfg)] +fn load_slave_fpga() { + println!("Loading slave FPGA gateware..."); + + const GATEWARE: *mut u8 = board_misoc::csr::CONFIG_SLAVE_FPGA_GATEWARE as *mut u8; + + let header = unsafe { slice::from_raw_parts(GATEWARE, 8) }; + let magic = BigEndian::read_u32(&header[0..]); + let length = BigEndian::read_u32(&header[4..]) as usize; + println!(" magic: 0x{:08x}, length: 0x{:08x}", magic, length); + if magic != 0x5352544d { + println!(" ...Error: bad magic"); + return + } + if length > 0x220000 { + println!(" ...Error: too long (corrupted?)"); + return + } + let payload = unsafe { slice::from_raw_parts(GATEWARE.offset(8), length) }; + + if let Err(e) = slave_fpga::prepare() { + println!(" ...Error during preparation: {}", e); + return + } + if let Err(e) = slave_fpga::input(payload) { + println!(" ...Error during loading: {}", e); + return + } + if let Err(e) = slave_fpga::complete() { + println!(" ...Error during completion: {}", e); + return + } + + println!(" ...done"); +} + + fn flash_boot() { const FIRMWARE: *mut u8 = board_mem::FLASH_BOOT_ADDRESS as *mut u8; const MAIN_RAM: *mut u8 = board_mem::MAIN_RAM_BASE as *mut u8; @@ -379,6 +418,8 @@ pub extern fn main() -> i32 { if startup() { println!(""); + #[cfg(has_slave_fpga_cfg)] + load_slave_fpga(); flash_boot(); #[cfg(has_ethmac)] network_boot(); diff --git a/artiq/firmware/libboard_artiq/lib.rs b/artiq/firmware/libboard_artiq/lib.rs index 9a4e727b2..b9666732d 100644 --- a/artiq/firmware/libboard_artiq/lib.rs +++ b/artiq/firmware/libboard_artiq/lib.rs @@ -27,8 +27,6 @@ pub mod rpc_queue; #[cfg(has_si5324)] pub mod si5324; -#[cfg(has_slave_fpga_cfg)] -pub mod slave_fpga; #[cfg(has_hmc830_7043)] pub mod hmc830_7043; #[cfg(has_ad9154)] diff --git a/artiq/firmware/libboard_misoc/lib.rs b/artiq/firmware/libboard_misoc/lib.rs index b49a69446..8abddf898 100644 --- a/artiq/firmware/libboard_misoc/lib.rs +++ b/artiq/firmware/libboard_misoc/lib.rs @@ -27,8 +27,10 @@ pub mod uart; pub mod spiflash; pub mod config; #[cfg(feature = "uart_console")] +#[macro_use] pub mod uart_console; #[cfg(all(feature = "uart_console", feature = "log"))] +#[macro_use] pub mod uart_logger; #[cfg(all(has_ethmac, feature = "smoltcp"))] pub mod ethmac; @@ -37,3 +39,5 @@ pub mod i2c; pub mod i2c_eeprom; #[cfg(all(has_ethmac, feature = "smoltcp"))] pub mod net_settings; +#[cfg(has_slave_fpga_cfg)] +pub mod slave_fpga; diff --git a/artiq/firmware/libboard_artiq/slave_fpga.rs b/artiq/firmware/libboard_misoc/slave_fpga.rs similarity index 71% rename from artiq/firmware/libboard_artiq/slave_fpga.rs rename to artiq/firmware/libboard_misoc/slave_fpga.rs index 6a56e527a..40c6795e0 100644 --- a/artiq/firmware/libboard_artiq/slave_fpga.rs +++ b/artiq/firmware/libboard_misoc/slave_fpga.rs @@ -1,6 +1,4 @@ -use board_misoc::{csr, clock}; -use core::slice; -use byteorder::{ByteOrder, BigEndian}; +use super::{csr, clock}; const CCLK_BIT: u8 = 1 << 0; const DIN_BIT: u8 = 1 << 1; @@ -8,8 +6,6 @@ const DONE_BIT: u8 = 1 << 2; const INIT_B_BIT: u8 = 1 << 3; const PROGRAM_B_BIT: u8 = 1 << 4; -const GATEWARE: *mut u8 = csr::CONFIG_SLAVE_FPGA_GATEWARE as *mut u8; - unsafe fn shift_u8(data: u8) { for i in 0..8 { let mut bits: u8 = PROGRAM_B_BIT; @@ -27,10 +23,10 @@ unsafe fn shift_u8(data: u8) { pub fn prepare() -> Result<(), &'static str> { unsafe { if csr::slave_fpga_cfg::in_read() & DONE_BIT != 0 { - info!(" DONE before loading"); + println!(" DONE before loading"); } if csr::slave_fpga_cfg::in_read() & INIT_B_BIT == 0 { - info!(" INIT asserted before loading"); + println!(" INIT asserted before loading"); } csr::slave_fpga_cfg::out_write(0); @@ -78,26 +74,3 @@ pub fn complete() -> Result<(), &'static str> { } Ok(()) } - -pub fn load() -> Result<(), &'static str> { - info!("Loading slave FPGA gateware..."); - - let header = unsafe { slice::from_raw_parts(GATEWARE, 8) }; - - let magic = BigEndian::read_u32(&header[0..]); - let length = BigEndian::read_u32(&header[4..]) as usize; - info!(" magic: 0x{:08x}, length: 0x{:08x}", magic, length); - if magic != 0x5352544d { // "SRTM", see sayma_rtm target as well - return Err("Bad magic"); - } - if length > 0x220000 { - return Err("Too large (corrupted?)"); - } - - prepare()?; - input(unsafe { slice::from_raw_parts(GATEWARE.offset(8), length) })?; - complete()?; - - info!(" ...done"); - Ok(()) -} diff --git a/artiq/firmware/runtime/main.rs b/artiq/firmware/runtime/main.rs index 0f24877d8..d7f983090 100644 --- a/artiq/firmware/runtime/main.rs +++ b/artiq/firmware/runtime/main.rs @@ -89,9 +89,6 @@ fn setup_log_levels() { } fn sayma_hw_init() { - #[cfg(has_slave_fpga_cfg)] - board_artiq::slave_fpga::load().expect("cannot load RTM FPGA gateware"); - #[cfg(has_hmc830_7043)] /* must be the first SPI init because of HMC830 SPI mode selection */ board_artiq::hmc830_7043::init().expect("cannot initialize HMC830/7043"); diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 98cc844c9..dc66038c7 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -448,9 +448,6 @@ pub extern fn main() -> i32 { info!("software ident {}", csr::CONFIG_IDENTIFIER_STR); info!("gateware ident {}", ident::read(&mut [0; 64])); - #[cfg(has_slave_fpga_cfg)] - board_artiq::slave_fpga::load().expect("cannot load RTM FPGA gateware"); - i2c::init().expect("I2C initialization failed"); si5324::setup(&SI5324_SETTINGS, si5324::Input::Ckin1).expect("cannot initialize Si5324"); unsafe {