mirror of
https://github.com/m-labs/artiq.git
synced 2024-12-27 04:08:27 +08:00
remote coremgmt: restart device gracefully after flashing
This commit is contained in:
parent
644e24be34
commit
f6cf66966d
@ -143,6 +143,7 @@ pub enum Packet {
|
|||||||
CoreMgmtConfigReadReply { last: bool, length: u16, value: [u8; SAT_PAYLOAD_MAX_SIZE] },
|
CoreMgmtConfigReadReply { last: bool, length: u16, value: [u8; SAT_PAYLOAD_MAX_SIZE] },
|
||||||
CoreMgmtAck,
|
CoreMgmtAck,
|
||||||
CoreMgmtNack,
|
CoreMgmtNack,
|
||||||
|
CoreMgmtRebootImminent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Packet {
|
impl Packet {
|
||||||
@ -507,6 +508,7 @@ impl Packet {
|
|||||||
},
|
},
|
||||||
0xdd => Packet::CoreMgmtAck,
|
0xdd => Packet::CoreMgmtAck,
|
||||||
0xde => Packet::CoreMgmtNack,
|
0xde => Packet::CoreMgmtNack,
|
||||||
|
0xdf => Packet::CoreMgmtRebootImminent,
|
||||||
|
|
||||||
ty => return Err(Error::UnknownPacket(ty))
|
ty => return Err(Error::UnknownPacket(ty))
|
||||||
})
|
})
|
||||||
@ -878,6 +880,7 @@ impl Packet {
|
|||||||
},
|
},
|
||||||
Packet::CoreMgmtAck => writer.write_u8(0xdd)?,
|
Packet::CoreMgmtAck => writer.write_u8(0xdd)?,
|
||||||
Packet::CoreMgmtNack => writer.write_u8(0xde)?,
|
Packet::CoreMgmtNack => writer.write_u8(0xde)?,
|
||||||
|
Packet::CoreMgmtRebootImminent => writer.write_u8(0xdf)?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -372,6 +372,7 @@ mod remote_coremgmt {
|
|||||||
destination: destination, length: len as u16, last: status.is_last(), data: *slice});
|
destination: destination, length: len as u16, last: status.is_last(), data: *slice});
|
||||||
match reply {
|
match reply {
|
||||||
Ok(Packet::CoreMgmtAck) => Ok(()),
|
Ok(Packet::CoreMgmtAck) => Ok(()),
|
||||||
|
Ok(Packet::CoreMgmtRebootImminent) if status.is_last() => Ok(()),
|
||||||
Ok(packet) => {
|
Ok(packet) => {
|
||||||
error!("received unexpected aux packet: {:?}", packet);
|
error!("received unexpected aux packet: {:?}", packet);
|
||||||
Err(drtio::Error::UnexpectedReply)
|
Err(drtio::Error::UnexpectedReply)
|
||||||
|
@ -562,17 +562,10 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg
|
|||||||
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
forward!(router, _routing_table, _destination, *rank, *self_destination, _repeaters, &packet);
|
||||||
|
|
||||||
coremgr.add_data(&data, length as usize);
|
coremgr.add_data(&data, length as usize);
|
||||||
let mut succeeded = true;
|
|
||||||
if last {
|
if last {
|
||||||
succeeded = coremgr.write_config().is_ok();
|
coremgr.write_config()
|
||||||
debug!("Write succeeded: {}", succeeded);
|
|
||||||
coremgr.clear_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
if succeeded {
|
|
||||||
drtioaux::send(0, &drtioaux::Packet::CoreMgmtAck)
|
|
||||||
} else {
|
} else {
|
||||||
drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack)
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtAck)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
drtioaux::Packet::CoreMgmtConfigRemoveRequest { destination: _destination, length, key } => {
|
drtioaux::Packet::CoreMgmtConfigRemoveRequest { destination: _destination, length, key } => {
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
use routing::{Sliceable, SliceMeta};
|
use routing::{Sliceable, SliceMeta};
|
||||||
use board_misoc::config;
|
use board_artiq::drtioaux;
|
||||||
|
use board_misoc::{clock, config, csr, spiflash};
|
||||||
use io::{Cursor, ProtoRead, ProtoWrite};
|
use io::{Cursor, ProtoRead, ProtoWrite};
|
||||||
use proto_artiq::drtioaux_proto::SAT_PAYLOAD_MAX_SIZE;
|
use proto_artiq::drtioaux_proto::SAT_PAYLOAD_MAX_SIZE;
|
||||||
|
|
||||||
|
|
||||||
type Result<T> = core::result::Result<T, ()>;
|
|
||||||
|
|
||||||
pub struct Manager {
|
pub struct Manager {
|
||||||
current_payload: Cursor<Vec<u8>>,
|
current_payload: Cursor<Vec<u8>>,
|
||||||
last_value: Sliceable,
|
last_value: Sliceable,
|
||||||
@ -21,7 +20,7 @@ impl Manager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_config_value(&mut self, key: &str) -> Result<()> {
|
pub fn fetch_config_value(&mut self, key: &str) -> Result<(), ()> {
|
||||||
config::read(key, |result| result.map(
|
config::read(key, |result| result.map(
|
||||||
|value| self.last_value = Sliceable::new(0, value.to_vec())
|
|value| self.last_value = Sliceable::new(0, value.to_vec())
|
||||||
)).map_err(|_err| warn!("read error: no such key"))
|
)).map_err(|_err| warn!("read error: no such key"))
|
||||||
@ -40,13 +39,44 @@ impl Manager {
|
|||||||
self.current_payload.set_position(0);
|
self.current_payload.set_position(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_config(&mut self) -> Result<()> {
|
pub fn write_config(&mut self) -> Result<(), drtioaux::Error<!>> {
|
||||||
let key = self.current_payload.read_string().map_err(
|
let key = match self.current_payload.read_string() {
|
||||||
|err| error!("error on reading key: {:?}", err))?;
|
Ok(key) => key,
|
||||||
|
Err(err) => {
|
||||||
|
self.clear_data();
|
||||||
|
error!("error on reading key: {:?}", err);
|
||||||
|
return drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let value = self.current_payload.read_bytes().unwrap();
|
let value = self.current_payload.read_bytes().unwrap();
|
||||||
|
|
||||||
config::write(&key, &value).map_err(|err| {
|
match key.as_str() {
|
||||||
error!("error on writing config: {:?}", err);
|
"gateware" | "bootloader" | "firmware" => {
|
||||||
})
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtRebootImminent)?;
|
||||||
|
#[cfg(not(soc_platform = "efc"))]
|
||||||
|
unsafe {
|
||||||
|
clock::spin_us(10000);
|
||||||
|
csr::gt_drtio::txenable_write(0);
|
||||||
|
}
|
||||||
|
config::write(&key, &value).expect("failed to write to flash storage");
|
||||||
|
warn!("restarting");
|
||||||
|
unsafe { spiflash::reload(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {
|
||||||
|
let succeeded = config::write(&key, &value).map_err(|err| {
|
||||||
|
error!("error on writing config: {:?}", err);
|
||||||
|
}).is_ok();
|
||||||
|
|
||||||
|
self.clear_data();
|
||||||
|
|
||||||
|
if succeeded {
|
||||||
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtAck)
|
||||||
|
} else {
|
||||||
|
drtioaux::send(0, &drtioaux::Packet::CoreMgmtNack)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user