satman: implement boot file rewrite sequence

This commit is contained in:
occheung 2024-09-04 13:21:25 +08:00
parent c8f286307a
commit fc1fd96f71
4 changed files with 85 additions and 1 deletions

2
src/Cargo.lock generated
View File

@ -501,7 +501,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",

View File

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

View File

@ -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;
@ -1143,7 +1145,7 @@ fn process_aux_packet(
}, },
) )
} else { } else {
drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false })
} }
} }
} }
@ -1279,6 +1281,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);

View File

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