diff --git a/artiq/firmware/libproto_artiq/drtioaux_proto.rs b/artiq/firmware/libproto_artiq/drtioaux_proto.rs index 267b983df..4e269fdd1 100644 --- a/artiq/firmware/libproto_artiq/drtioaux_proto.rs +++ b/artiq/firmware/libproto_artiq/drtioaux_proto.rs @@ -140,6 +140,8 @@ pub enum Packet { CoreMgmtRebootRequest { destination: u8 }, CoreMgmtAllocatorDebugRequest { destination: u8 }, CoreMgmtFlashRequest { destination: u8, last: bool, length: u16, data: [u8; MASTER_PAYLOAD_MAX_SIZE] }, + CoreMgmtDropLinkAck { destination: u8 }, + CoreMgmtDropLink, CoreMgmtGetLogReply { last: bool, length: u16, data: [u8; SAT_PAYLOAD_MAX_SIZE] }, CoreMgmtConfigReadReply { last: bool, length: u16, value: [u8; SAT_PAYLOAD_MAX_SIZE] }, CoreMgmtReply { succeeded: bool }, @@ -521,6 +523,10 @@ impl Packet { data: data, } }, + 0xdf => Packet::CoreMgmtDropLink, + 0xe0 => Packet::CoreMgmtDropLinkAck { + destination: reader.read_u8()?, + }, ty => return Err(Error::UnknownPacket(ty)) }) @@ -901,6 +907,12 @@ impl Packet { writer.write_u16(length)?; writer.write_all(&data[..length as usize])?; }, + Packet::CoreMgmtDropLink => + writer.write_u8(0xdf)?, + Packet::CoreMgmtDropLinkAck { destination } => { + writer.write_u8(0xe0)?; + writer.write_u8(destination)?; + }, } Ok(()) } diff --git a/artiq/firmware/runtime/mgmt.rs b/artiq/firmware/runtime/mgmt.rs index 65567b3bc..0c1b423d6 100644 --- a/artiq/firmware/runtime/mgmt.rs +++ b/artiq/firmware/runtime/mgmt.rs @@ -196,7 +196,7 @@ mod remote_coremgmt { use alloc::{string::String, vec::Vec}; use log::LevelFilter; - use board_artiq::{drtioaux::Packet, drtio_routing}; + use board_artiq::{drtioaux, drtioaux::Packet, drtio_routing}; use io::{Cursor, ProtoWrite}; use mgmt_proto::{Error, Reply}; use rtio_mgt::drtio; @@ -550,6 +550,16 @@ mod remote_coremgmt { destination: destination, length: len as u16, last: status.is_last(), data: *slice}); match reply { Ok(Packet::CoreMgmtReply { succeeded: true }) => Ok(()), + Ok(Packet::CoreMgmtDropLink) => { + if status.is_last() { + drtioaux::send( + linkno, &Packet::CoreMgmtDropLinkAck { destination: destination } + ).map_err(|_| drtio::Error::AuxError) + } else { + error!("received unexpected drop link packet"); + Err(drtio::Error::UnexpectedReply) + } + } Ok(packet) => { error!("received unexpected aux packet: {:?}", packet); Err(drtio::Error::UnexpectedReply) diff --git a/artiq/firmware/satman/main.rs b/artiq/firmware/satman/main.rs index 9a98528a6..1647c7955 100644 --- a/artiq/firmware/satman/main.rs +++ b/artiq/firmware/satman/main.rs @@ -592,11 +592,28 @@ fn process_aux_packet(dmamgr: &mut DmaManager, analyzer: &mut Analyzer, kernelmg coremgr.add_image_data(&data, length as usize); if last { - coremgr.flash_image() + 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); + + #[cfg(not(soc_platform = "efc"))] + unsafe { + csr::gt_drtio::txenable_write(0); + } + + #[cfg(has_drtio_eem)] + unsafe { + csr::eem_transceiver::txenable_write(0); + } + + coremgr.flash_image(); + warn!("restarting"); + unsafe { spiflash::reload(); } + } _ => { warn!("received unexpected aux packet"); diff --git a/artiq/firmware/satman/mgmt.rs b/artiq/firmware/satman/mgmt.rs index 911a15d5d..2b44bc4bb 100644 --- a/artiq/firmware/satman/mgmt.rs +++ b/artiq/firmware/satman/mgmt.rs @@ -4,7 +4,7 @@ use crc::crc32; use routing::{Sliceable, SliceMeta}; use board_artiq::drtioaux; -use board_misoc::{mem, clock, config, csr, spiflash}; +use board_misoc::{mem, config, spiflash}; use io::{Cursor, ProtoRead, ProtoWrite}; use proto_artiq::drtioaux_proto::SAT_PAYLOAD_MAX_SIZE; @@ -68,12 +68,7 @@ impl Manager { self.image_payload.write_all(&data[..data_len]).unwrap(); } - pub fn clear_image_data(&mut self) { - self.image_payload.get_mut().clear(); - self.image_payload.set_position(0); - } - - pub fn flash_image(&mut self) -> Result<(), drtioaux::Error> { + pub fn flash_image(&self) { let image = &self.image_payload.get_ref()[..]; let (expected_crc, mut image) = { @@ -84,13 +79,6 @@ impl Manager { let actual_crc = crc32::checksum_ieee(image); if actual_crc == expected_crc { - drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: true })?; - #[cfg(not(soc_platform = "efc"))] - unsafe { - clock::spin_us(10000); - csr::gt_drtio::txenable_write(0); - } - let bin_origins = [ ("gateware" , 0 ), ("bootloader", mem::ROM_BASE ), @@ -98,7 +86,7 @@ impl Manager { ]; for (name, origin) in bin_origins { - info!("Flashing {} binary...", name); + info!("flashing {} binary...", name); let size = NativeEndian::read_u32(&image[..4]) as usize; image = &image[4..]; @@ -108,13 +96,8 @@ impl Manager { unsafe { spiflash::flash_binary(origin, bin) }; } - warn!("restarting"); - unsafe { spiflash::reload(); } - } else { - error!("CRC failed in SDRAM (actual {:08x}, expected {:08x})", actual_crc, expected_crc); - self.clear_image_data(); - drtioaux::send(0, &drtioaux::Packet::CoreMgmtReply { succeeded: false }) + panic!("CRC failed in SDRAM (actual {:08x}, expected {:08x})", actual_crc, expected_crc); } } }