forked from M-Labs/artiq
1
0
Fork 0

firmware: prepare config block for access from BIOS/bootloader.

* remove liballoc dependency from mod config,
  * move mod config to libboard,
  * move config sector immediately after BIOS sector.
This commit is contained in:
whitequark 2017-12-27 19:14:41 +00:00
parent 5a2cbe7088
commit d7cb4963e1
11 changed files with 105 additions and 119 deletions

View File

@ -28,6 +28,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"build_artiq 0.0.0", "build_artiq 0.0.0",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]

View File

@ -12,8 +12,9 @@ path = "lib.rs"
build_artiq = { path = "../libbuild_artiq" } build_artiq = { path = "../libbuild_artiq" }
[dependencies] [dependencies]
bitflags = "1.0"
byteorder = { version = "1.0", default-features = false }
log = { version = "0.3", default-features = false } log = { version = "0.3", default-features = false }
bitflags = { version = "1.0" }
[features] [features]
uart_console = [] uart_console = []

View File

@ -1,14 +1,17 @@
#[cfg(has_spiflash)] #[cfg(has_spiflash)]
mod imp { mod imp {
use core::str; use core::str;
use std::btree_map::BTreeMap;
use byteorder::{ByteOrder, BigEndian}; use byteorder::{ByteOrder, BigEndian};
use board::{cache, spiflash}; use cache;
use spiflash;
// One flash sector immediately after the bootloader.
const ADDR: usize = ::mem::FLASH_BOOT_ADDRESS - spiflash::PAGE_SIZE;
const SIZE: usize = spiflash::PAGE_SIZE;
mod lock { mod lock {
use core::slice; use core::slice;
use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT}; use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use board;
static LOCKED: AtomicUsize = ATOMIC_USIZE_INIT; static LOCKED: AtomicUsize = ATOMIC_USIZE_INIT;
@ -24,22 +27,7 @@ mod imp {
} }
pub fn data(&self) -> &'static [u8] { pub fn data(&self) -> &'static [u8] {
extern { unsafe { slice::from_raw_parts(super::ADDR as *const u8, super::SIZE) }
static _ftext: u8;
static _fstorage: u8;
static _estorage: u8;
}
unsafe {
let base = &_ftext as *const _ as usize;
let begin = &_fstorage as *const _ as usize;
let end = &_estorage as *const _ as usize;
let ptr = board::mem::FLASH_BOOT_ADDRESS + (begin - base);
let len = end - begin;
slice::from_raw_parts(ptr as *const u8, len)
}
} }
} }
@ -52,6 +40,7 @@ mod imp {
use self::lock::Lock; use self::lock::Lock;
#[derive(Clone)]
struct Iter<'a> { struct Iter<'a> {
data: &'a [u8], data: &'a [u8],
offset: usize offset: usize
@ -140,28 +129,39 @@ mod imp {
spiflash::write(data.as_ptr() as usize, value); spiflash::write(data.as_ptr() as usize, value);
data = &data[value.len()..]; data = &data[value.len()..];
cache::flush_l2_cache();
Ok(data) Ok(data)
} }
fn compact() -> Result<(), ()> { fn compact() -> Result<(), ()> {
let lock = Lock::take()?; let lock = Lock::take()?;
let mut items = BTreeMap::new(); static mut OLD_DATA: [u8; SIZE] = [0; SIZE];
{ let old_data = unsafe {
let mut iter = Iter::new(lock.data()); OLD_DATA.copy_from_slice(lock.data());
while let Some(result) = iter.next() { &OLD_DATA[..]
let (key, value) = result?; };
items.insert(key, value);
}
}
let mut data = lock.data(); let mut data = lock.data();
spiflash::erase_sector(data.as_ptr() as usize); unsafe { spiflash::erase_sector(data.as_ptr() as usize) };
for (key, value) in items {
// This is worst-case quadratic, but we're limited by a small SPI flash sector size,
// so it does not really matter.
let mut iter = Iter::new(old_data);
while let Some(result) = iter.next() {
let (key, mut value) = result?;
let mut next_iter = iter.clone();
while let Some(next_result) = next_iter.next() {
let (next_key, next_value) = next_result?;
if key == next_key {
value = next_value
}
}
data = unsafe { append_at(data, key, value)? }; data = unsafe { append_at(data, key, value)? };
} }
cache::flush_l2_cache();
Ok(()) Ok(())
} }
@ -178,7 +178,6 @@ mod imp {
unsafe { append_at(free, key.as_bytes(), value)? }; unsafe { append_at(free, key.as_bytes(), value)? };
cache::flush_l2_cache();
Ok(()) Ok(())
} }
@ -200,7 +199,7 @@ mod imp {
pub fn erase() -> Result<(), ()> { pub fn erase() -> Result<(), ()> {
let lock = Lock::take()?; let lock = Lock::take()?;
spiflash::erase_sector(lock.data().as_ptr() as usize); unsafe { spiflash::erase_sector(lock.data().as_ptr() as usize) };
cache::flush_l2_cache(); cache::flush_l2_cache();
Ok(()) Ok(())

View File

@ -1,10 +1,11 @@
#![feature(asm, lang_items)] #![feature(asm, lang_items)]
#![no_std] #![no_std]
#[macro_use]
extern crate log;
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
extern crate byteorder;
#[macro_use]
extern crate log;
use core::{cmp, ptr, str}; use core::{cmp, ptr, str};
@ -21,6 +22,7 @@ pub mod uart_console;
#[cfg(has_spiflash)] #[cfg(has_spiflash)]
pub mod spiflash; pub mod spiflash;
pub mod config;
pub mod i2c; pub mod i2c;
pub mod spi; pub mod spi;

View File

@ -3,6 +3,10 @@
use core::cmp; use core::cmp;
use csr; use csr;
pub const PAGE_SIZE: usize = csr::CONFIG_SPIFLASH_PAGE_SIZE as usize;
const PAGE_MASK: usize = PAGE_SIZE - 1;
const CMD_PP: u8 = 0x02; const CMD_PP: u8 = 0x02;
const CMD_WRDI: u8 = 0x04; const CMD_WRDI: u8 = 0x04;
const CMD_RDSR: u8 = 0x05; const CMD_RDSR: u8 = 0x05;
@ -15,8 +19,7 @@ const PIN_DQ_I: u8 = 1 << 3;
const SR_WIP: u8 = 1; const SR_WIP: u8 = 1;
fn write_byte(mut byte: u8) { unsafe fn write_byte(mut byte: u8) {
unsafe {
csr::spiflash::bitbang_write(0); csr::spiflash::bitbang_write(0);
for _ in 0..8 { for _ in 0..8 {
csr::spiflash::bitbang_write((byte & 0x80) >> 7); csr::spiflash::bitbang_write((byte & 0x80) >> 7);
@ -24,11 +27,9 @@ fn write_byte(mut byte: u8) {
byte <<= 1; byte <<= 1;
} }
csr::spiflash::bitbang_write(0); csr::spiflash::bitbang_write(0);
}
} }
fn write_addr(mut addr: usize) { unsafe fn write_addr(mut addr: usize) {
unsafe {
csr::spiflash::bitbang_write(0); csr::spiflash::bitbang_write(0);
for _ in 0..24 { for _ in 0..24 {
csr::spiflash::bitbang_write(((addr & 0x800000) >> 23) as u8); csr::spiflash::bitbang_write(((addr & 0x800000) >> 23) as u8);
@ -36,7 +37,6 @@ fn write_addr(mut addr: usize) {
addr <<= 1; addr <<= 1;
} }
csr::spiflash::bitbang_write(0); csr::spiflash::bitbang_write(0);
}
} }
fn wait_until_ready() { fn wait_until_ready() {
@ -59,8 +59,7 @@ fn wait_until_ready() {
} }
} }
pub fn erase_sector(addr: usize) { pub unsafe fn erase_sector(addr: usize) {
unsafe {
let sector_addr = addr & !(csr::CONFIG_SPIFLASH_SECTOR_SIZE as usize - 1); let sector_addr = addr & !(csr::CONFIG_SPIFLASH_SECTOR_SIZE as usize - 1);
csr::spiflash::bitbang_en_write(1); csr::spiflash::bitbang_en_write(1);
@ -77,11 +76,9 @@ pub fn erase_sector(addr: usize) {
wait_until_ready(); wait_until_ready();
csr::spiflash::bitbang_en_write(0); csr::spiflash::bitbang_en_write(0);
}
} }
fn write_page(addr: usize, data: &[u8]) { unsafe fn write_page(addr: usize, data: &[u8]) {
unsafe {
csr::spiflash::bitbang_en_write(1); csr::spiflash::bitbang_en_write(1);
wait_until_ready(); wait_until_ready();
@ -100,13 +97,9 @@ fn write_page(addr: usize, data: &[u8]) {
wait_until_ready(); wait_until_ready();
csr::spiflash::bitbang_en_write(0); csr::spiflash::bitbang_en_write(0);
}
} }
const PAGE_SIZE: usize = csr::CONFIG_SPIFLASH_PAGE_SIZE as usize; pub unsafe fn write(mut addr: usize, mut data: &[u8]) {
const PAGE_MASK: usize = PAGE_SIZE - 1;
pub fn write(mut addr: usize, mut data: &[u8]) {
if addr & PAGE_MASK != 0 { if addr & PAGE_MASK != 0 {
let size = cmp::min((PAGE_SIZE - (addr & PAGE_MASK)) as usize, data.len()); let size = cmp::min((PAGE_SIZE - (addr & PAGE_MASK)) as usize, data.len());
write_page(addr, &data[..size]); write_page(addr, &data[..size]);

View File

@ -23,10 +23,11 @@ extern crate amp;
extern crate drtioaux; extern crate drtioaux;
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
use board::config;
use proto::{mgmt_proto, analyzer_proto, moninj_proto, rpc_proto, session_proto, kernel_proto}; use proto::{mgmt_proto, analyzer_proto, moninj_proto, rpc_proto, session_proto, kernel_proto};
use amp::{mailbox, rpc_queue}; use amp::{mailbox, rpc_queue};
mod config;
#[cfg(has_ethmac)] #[cfg(has_ethmac)]
mod ethmac; mod ethmac;
#[cfg(has_rtio_core)] #[cfg(has_rtio_core)]

View File

@ -1,5 +1,4 @@
use config; use board::{csr, config};
use board::csr;
use sched::Io; use sched::Io;
#[cfg(has_rtio_crg)] #[cfg(has_rtio_crg)]

View File

@ -66,15 +66,6 @@ SECTIONS
_edata = .; _edata = .;
} > runtime } > runtime
.storage :
{
/* Keep in sync with artiq_flash.py */
. = _ftext + 0x100000;
_fstorage = .;
. += /*SPIFLASH_SECTOR_SIZE*/ 0x10000;
_estorage = .;
} > runtime
.bss : .bss :
{ {
. = ALIGN(4); . = ALIGN(4);

View File

@ -8,8 +8,8 @@ use byteorder::{ByteOrder, NetworkEndian};
use urc::Urc; use urc::Urc;
use sched::{ThreadHandle, Io}; use sched::{ThreadHandle, Io};
use sched::{TcpListener, TcpStream}; use sched::{TcpListener, TcpStream};
use board; use board::{self, config};
use {config, mailbox, rpc_queue, kernel}; use {mailbox, rpc_queue, kernel};
#[cfg(has_rtio_core)] #[cfg(has_rtio_core)]
use rtio_mgt; use rtio_mgt;
use rtio_dma::Manager as DmaManager; use rtio_dma::Manager as DmaManager;

View File

@ -20,9 +20,9 @@ Valid actions:
* proxy: load the flash proxy gateware bitstream * proxy: load the flash proxy gateware bitstream
* gateware: write gateware bitstream to flash * gateware: write gateware bitstream to flash
* bios: write bios to flash * bootloader: write bootloader to flash
* runtime: write runtime to flash
* storage: write storage image to flash * storage: write storage image to flash
* runtime: write runtime to flash
* load: load gateware bitstream into device (volatile but fast) * load: load gateware bitstream into device (volatile but fast)
* start: trigger the target to (re)load its gateware bitstream from flash * start: trigger the target to (re)load its gateware bitstream from flash
@ -48,7 +48,7 @@ Prerequisites:
parser.add_argument("--srcbuild", help="look for bitstream, BIOS and runtime in this " parser.add_argument("--srcbuild", help="look for bitstream, BIOS and runtime in this "
"ARTIQ source build tree") "ARTIQ source build tree")
parser.add_argument("action", metavar="ACTION", nargs="*", parser.add_argument("action", metavar="ACTION", nargs="*",
default="proxy gateware bios runtime start".split(), default="proxy gateware bootloader runtime start".split(),
help="actions to perform, default: %(default)s") help="actions to perform, default: %(default)s")
return parser return parser
@ -188,25 +188,24 @@ def main():
parser = get_argparser() parser = get_argparser()
opts = parser.parse_args() opts = parser.parse_args()
storage_at = 0x100000 # Keep in sync with runtime.ld
config = { config = {
"kc705": { "kc705": {
"programmer_factory": partial(ProgrammerJtagSpi7, "kc705"), "programmer_factory": partial(ProgrammerJtagSpi7, "kc705"),
"proxy_bitfile": "bscan_spi_xc7k325t.bit", "proxy_bitfile": "bscan_spi_xc7k325t.bit",
"variants": ["nist_clock", "nist_qc2"], "variants": ["nist_clock", "nist_qc2"],
"gateware": (0, 0x000000), "gateware": (0, 0x000000),
"bios": (0, 0xaf0000), "bootloader": (0, 0xaf0000),
"runtime": (0, 0xb00000), "storage": (0, 0xb00000),
"storage": (0, 0xb00000 + storage_at), "runtime": (0, 0xb10000),
}, },
"sayma": { "sayma": {
"programmer_factory": ProgrammerSayma, "programmer_factory": ProgrammerSayma,
"proxy_bitfile": "bscan_spi_xcku040-sayma.bit", "proxy_bitfile": "bscan_spi_xcku040-sayma.bit",
"variants": ["standalone"], "variants": ["standalone"],
"gateware": (0, 0x000000), "gateware": (0, 0x000000),
"bios": (1, 0x000000), "bootloader": (1, 0x000000),
"runtime": (1, 0x010000), "storage": (1, 0x010000),
"storage": (1, 0x010000 + storage_at), "runtime": (1, 0x020000),
}, },
}[opts.target] }[opts.target]
@ -256,20 +255,20 @@ def main():
bit2bin(f, g) bit2bin(f, g)
conv = True conv = True
programmer.flash_binary(*config["gateware"], bin) programmer.flash_binary(*config["gateware"], bin)
elif action == "bios": elif action == "bootloader":
if opts.srcbuild is None: if opts.srcbuild is None:
path = bin_dir path = bin_dir
else: else:
path = os.path.join(opts.srcbuild, "software", "bios") path = os.path.join(opts.srcbuild, "software", "bios")
programmer.flash_binary(*config["bios"], os.path.join(path, "bios.bin")) programmer.flash_binary(*config["bootloader"], os.path.join(path, "bios.bin"))
elif action == "storage":
programmer.flash_binary(*config["storage"], opts.storage)
elif action == "runtime": elif action == "runtime":
if opts.srcbuild is None: if opts.srcbuild is None:
path = bin_dir path = bin_dir
else: else:
path = os.path.join(opts.srcbuild, "software", "runtime") path = os.path.join(opts.srcbuild, "software", "runtime")
programmer.flash_binary(*config["runtime"], os.path.join(path, "runtime.fbi")) programmer.flash_binary(*config["runtime"], os.path.join(path, "runtime.fbi"))
elif action == "storage":
programmer.flash_binary(*config["storage"], opts.storage)
elif action == "load": elif action == "load":
if opts.srcbuild is None: if opts.srcbuild is None:
path = bin_dir path = bin_dir

View File

@ -15,7 +15,7 @@ requirements:
- python >=3.5.3,<3.6 - python >=3.5.3,<3.6
- setuptools 33.1.1 - setuptools 33.1.1
- migen 0.6.dev py35_50+git82b06ee - migen 0.6.dev py35_50+git82b06ee
- misoc 0.8.dev py35_30+gitd95f4edb - misoc 0.8.dev py35_35+git6845fc0a
- jesd204b 0.4 - jesd204b 0.4
- binutils-or1k-linux >=2.27 - binutils-or1k-linux >=2.27
- llvm-or1k 4.0.1 - llvm-or1k 4.0.1