diff --git a/Cargo.lock b/Cargo.lock index 8b011cf142..b52da47372 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3074,7 +3074,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service#42eb9b5cd170488ce696ef87d18458f2496a1e70" +source = "git+https://github.com/oxidecomputer/management-gateway-service#c4567213406aeb515f86a3599dba15d7d4eba6a7" dependencies = [ "bitflags 2.9.4", "hubpack", diff --git a/task/control-plane-agent/src/main.rs b/task/control-plane-agent/src/main.rs index b0a1021644..2d0ee1490d 100644 --- a/task/control-plane-agent/src/main.rs +++ b/task/control-plane-agent/src/main.rs @@ -159,6 +159,9 @@ enum MgsMessage { slot: u16, persist: bool, }, + ComponentGetPersistentSlot { + component: SpComponent, + }, SerialConsoleBreak, SendHostNmi, SetIpccKeyValue { diff --git a/task/control-plane-agent/src/mgs_common.rs b/task/control-plane-agent/src/mgs_common.rs index 2d1079605d..693c4a662b 100644 --- a/task/control-plane-agent/src/mgs_common.rs +++ b/task/control-plane-agent/src/mgs_common.rs @@ -429,6 +429,31 @@ impl MgsCommon { } } + pub(crate) fn component_get_persistent_slot( + &mut self, + component: SpComponent, + ) -> Result { + match component { + SpComponent::SP_ITSELF => { + Ok(self.update_sp.get_pending_boot_slot().into()) + } + SpComponent::ROT => { + let slot = match self + .sprot + .rot_boot_info()? + .persistent_boot_preference + { + SpSlotId::A => 0, + SpSlotId::B => 1, + }; + Ok(slot) + } + // We know that the LPC55S69 RoT bootloader does not have switchable banks. + SpComponent::STAGE0 => Ok(0), + _ => Err(GwSpError::RequestUnsupportedForComponent), + } + } + pub(crate) fn read_sensor( &mut self, req: SensorRequest, diff --git a/task/control-plane-agent/src/mgs_compute_sled.rs b/task/control-plane-agent/src/mgs_compute_sled.rs index 2e81b376ec..d5fe80796d 100644 --- a/task/control-plane-agent/src/mgs_compute_sled.rs +++ b/task/control-plane-agent/src/mgs_compute_sled.rs @@ -991,6 +991,22 @@ impl SpHandler for MgsHandler { } } + fn component_get_persistent_slot( + &mut self, + component: SpComponent, + ) -> Result { + ringbuf_entry_root!(Log::MgsMessage( + MgsMessage::ComponentGetPersistentSlot { component } + )); + + match component { + SpComponent::HOST_CPU_BOOT_FLASH => { + self.host_flash_update.persistent_slot() + } + _ => self.common.component_get_persistent_slot(component), + } + } + fn component_clear_status( &mut self, component: SpComponent, diff --git a/task/control-plane-agent/src/mgs_psc.rs b/task/control-plane-agent/src/mgs_psc.rs index 2237550b7e..c97302b557 100644 --- a/task/control-plane-agent/src/mgs_psc.rs +++ b/task/control-plane-agent/src/mgs_psc.rs @@ -490,6 +490,17 @@ impl SpHandler for MgsHandler { .component_set_active_slot(component, slot, persist) } + fn component_get_persistent_slot( + &mut self, + component: SpComponent, + ) -> Result { + ringbuf_entry_root!(Log::MgsMessage( + MgsMessage::ComponentGetPersistentSlot { component } + )); + + self.common.component_get_persistent_slot(component) + } + fn component_clear_status( &mut self, component: SpComponent, diff --git a/task/control-plane-agent/src/mgs_sidecar.rs b/task/control-plane-agent/src/mgs_sidecar.rs index f21812e7cc..a19f9d3725 100644 --- a/task/control-plane-agent/src/mgs_sidecar.rs +++ b/task/control-plane-agent/src/mgs_sidecar.rs @@ -967,6 +967,17 @@ impl SpHandler for MgsHandler { .component_set_active_slot(component, slot, persist) } + fn component_get_persistent_slot( + &mut self, + component: SpComponent, + ) -> Result { + ringbuf_entry_root!(Log::MgsMessage( + MgsMessage::ComponentGetPersistentSlot { component } + )); + + self.common.component_get_persistent_slot(component) + } + fn component_clear_status( &mut self, component: SpComponent, diff --git a/task/control-plane-agent/src/update/host_flash.rs b/task/control-plane-agent/src/update/host_flash.rs index f1863d602a..c503c189cb 100644 --- a/task/control-plane-agent/src/update/host_flash.rs +++ b/task/control-plane-agent/src/update/host_flash.rs @@ -75,13 +75,23 @@ impl HostFlashUpdate { } pub(crate) fn active_slot(&self) -> Result { - match self - .task + self.task .get_dev() - .map_err(|err| SpError::ComponentOperationFailed(err as u32))? - { - HfDevSelect::Flash0 => Ok(0), - HfDevSelect::Flash1 => Ok(1), + .map(Self::dev_to_slot) + .map_err(|err| SpError::ComponentOperationFailed(err as u32)) + } + + pub(crate) fn persistent_slot(&self) -> Result { + self.task + .get_persistent_data() + .map(|data| Self::dev_to_slot(data.dev_select)) + .map_err(hf_to_gwhf) + } + + fn dev_to_slot(dev: HfDevSelect) -> u16 { + match dev { + HfDevSelect::Flash0 => 0, + HfDevSelect::Flash1 => 1, } }