mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-24 10:54:02 +08:00
firmware: load slave FPGA in bootloader
This commit is contained in:
parent
389a8f587a
commit
a78e493b72
@ -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();
|
||||
|
@ -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)]
|
||||
|
@ -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;
|
||||
|
@ -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(())
|
||||
}
|
@ -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");
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user