firmware: load slave FPGA in bootloader

This commit is contained in:
Sebastien Bourdeauducq 2019-10-31 12:42:09 +08:00
parent 389a8f587a
commit a78e493b72
6 changed files with 48 additions and 38 deletions

View File

@ -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();

View File

@ -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)]

View File

@ -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;

View File

@ -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(())
}

View File

@ -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");

View File

@ -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 {