forked from M-Labs/artiq-zynq
satman: implement boot file rewrite sequence
This commit is contained in:
parent
5cb565a7e0
commit
2985875f9a
|
@ -559,7 +559,9 @@ name = "satman"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"build_zynq",
|
"build_zynq",
|
||||||
|
"byteorder",
|
||||||
"core_io",
|
"core_io",
|
||||||
|
"crc",
|
||||||
"cslice",
|
"cslice",
|
||||||
"embedded-hal",
|
"embedded-hal",
|
||||||
"io",
|
"io",
|
||||||
|
|
|
@ -15,7 +15,9 @@ build_zynq = { path = "../libbuild_zynq" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = { version = "0.4", default-features = false }
|
log = { version = "0.4", default-features = false }
|
||||||
|
byteorder = { version = "1.3", default-features = false }
|
||||||
core_io = { version = "0.1", features = ["collections"] }
|
core_io = { version = "0.1", features = ["collections"] }
|
||||||
|
crc = { version = "1.7", default-features = false }
|
||||||
cslice = "0.3"
|
cslice = "0.3"
|
||||||
embedded-hal = "0.2"
|
embedded-hal = "0.2"
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
extern crate byteorder;
|
||||||
extern crate core_io;
|
extern crate core_io;
|
||||||
|
extern crate crc;
|
||||||
extern crate cslice;
|
extern crate cslice;
|
||||||
extern crate embedded_hal;
|
extern crate embedded_hal;
|
||||||
|
|
||||||
|
@ -1144,7 +1146,7 @@ fn process_aux_packet(
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false })
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1280,6 +1282,53 @@ fn process_aux_packet(
|
||||||
error!("debug allocator not supported on zynq device");
|
error!("debug allocator not supported on zynq device");
|
||||||
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false })
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false })
|
||||||
}
|
}
|
||||||
|
drtioaux::Packet::CoreMgmtFlashRequest {
|
||||||
|
destination: _destination,
|
||||||
|
last,
|
||||||
|
length,
|
||||||
|
data,
|
||||||
|
} => {
|
||||||
|
forward!(
|
||||||
|
router,
|
||||||
|
_routing_table,
|
||||||
|
_destination,
|
||||||
|
*rank,
|
||||||
|
*self_destination,
|
||||||
|
_repeaters,
|
||||||
|
&packet,
|
||||||
|
timer
|
||||||
|
);
|
||||||
|
|
||||||
|
core_manager.add_image_data(&data, length as usize);
|
||||||
|
|
||||||
|
if last {
|
||||||
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtDropLink)
|
||||||
|
} else {
|
||||||
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drtioaux::Packet::CoreMgmtDropLinkAck {
|
||||||
|
destination: _destination,
|
||||||
|
} => {
|
||||||
|
forward!(
|
||||||
|
router,
|
||||||
|
_routing_table,
|
||||||
|
_destination,
|
||||||
|
*rank,
|
||||||
|
*self_destination,
|
||||||
|
_repeaters,
|
||||||
|
&packet,
|
||||||
|
timer
|
||||||
|
);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
csr::gt_drtio::txenable_write(0);
|
||||||
|
}
|
||||||
|
core_manager.write_image();
|
||||||
|
info!("reboot imminent");
|
||||||
|
slcr::reboot();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
p => {
|
p => {
|
||||||
warn!("received unexpected aux packet: {:?}", p);
|
warn!("received unexpected aux packet: {:?}", p);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
|
use byteorder::{ByteOrder, NativeEndian};
|
||||||
|
use crc::crc32;
|
||||||
use io::{Cursor, ProtoRead, ProtoWrite};
|
use io::{Cursor, ProtoRead, ProtoWrite};
|
||||||
use libboard_artiq::{drtioaux_proto::SAT_PAYLOAD_MAX_SIZE,
|
use libboard_artiq::{drtioaux_proto::SAT_PAYLOAD_MAX_SIZE,
|
||||||
logger::{BufferLogger, LogBufferRef}};
|
logger::{BufferLogger, LogBufferRef}};
|
||||||
|
@ -48,6 +50,7 @@ pub struct Manager<'a> {
|
||||||
last_log: Sliceable,
|
last_log: Sliceable,
|
||||||
config_payload: Cursor<Vec<u8>>,
|
config_payload: Cursor<Vec<u8>>,
|
||||||
last_value: Sliceable,
|
last_value: Sliceable,
|
||||||
|
image_payload: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Manager<'_> {
|
impl<'a> Manager<'_> {
|
||||||
|
@ -57,6 +60,7 @@ impl<'a> Manager<'_> {
|
||||||
last_log: Sliceable::new(0, Vec::new()),
|
last_log: Sliceable::new(0, Vec::new()),
|
||||||
config_payload: Cursor::new(Vec::new()),
|
config_payload: Cursor::new(Vec::new()),
|
||||||
last_value: Sliceable::new(0, Vec::new()),
|
last_value: Sliceable::new(0, Vec::new()),
|
||||||
|
image_payload: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,4 +117,31 @@ impl<'a> Manager<'_> {
|
||||||
.map(|()| debug!("erase success"))
|
.map(|()| debug!("erase success"))
|
||||||
.map_err(|err| warn!("failed to erase: {:?}", err))
|
.map_err(|err| warn!("failed to erase: {:?}", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_image_data(&mut self, data: &[u8], data_len: usize) {
|
||||||
|
self.image_payload.extend(&data[..data_len]);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_image(&self) {
|
||||||
|
let mut image = self.image_payload.clone();
|
||||||
|
let image_ref = &image[..];
|
||||||
|
let bin_len = image.len() - 4;
|
||||||
|
|
||||||
|
let (image_ref, expected_crc) = {
|
||||||
|
let (image_ref, crc_slice) = image_ref.split_at(bin_len);
|
||||||
|
(image_ref, NativeEndian::read_u32(crc_slice))
|
||||||
|
};
|
||||||
|
|
||||||
|
let actual_crc = crc32::checksum_ieee(image_ref);
|
||||||
|
|
||||||
|
if actual_crc == expected_crc {
|
||||||
|
image.truncate(bin_len);
|
||||||
|
self.cfg.write("boot", image).expect("failed to write boot image");
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"CRC failed in SDRAM (actual {:08x}, expected {:08x})",
|
||||||
|
actual_crc, expected_crc
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue