From 6dec1aff96afd005a94cda054581d25d97523929 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Mon, 4 Aug 2025 14:37:07 -0700 Subject: [PATCH 01/14] Fix version translaterion for VersionedRotBootInfo Translate MGS 1-based versions to RoT 0-based versions for the SP/RoT `versioned_rot_boot_info()` call and clamp the version to be the lesser of the MGS's and SP's `RotBootInfo::HIGHEST_KNOWN_VERSION`. The version argument of the VersionedRotBootInfo message was being used directly for the sprot `versioned_rot_boot_info` call. These are actually two different name spaces. This change helps when an upcoming PR introduces new MGS and RoT varients to support the `BootDecisionLog`. Without this change, a new MGS and RoT running against an old SP will have some cases where an MGS request is understood by the RoT but the RoT response cannot be deserialized by the SP and results in sending an error to the MGS. --- Cargo.lock | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index daa79217d..2c8ed4749 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5282,6 +5282,22 @@ dependencies = [ "zerocopy-derive 0.8.26", ] +[[package]] +name = "task-caboose-reader" +version = "0.1.0" +dependencies = [ + "build-util", + "cfg-if", + "drv-caboose", + "drv-caboose-pos", + "idol", + "idol-runtime", + "num-traits", + "userlib", + "zerocopy 0.8.26", + "zerocopy-derive 0.8.26", +] + [[package]] name = "task-config" version = "0.1.0" @@ -5987,6 +6003,29 @@ dependencies = [ "userlib", ] +[[package]] +name = "task-spd" +version = "0.1.0" +dependencies = [ + "anyhow", + "build-i2c", + "build-util", + "cfg-if", + "cortex-m", + "drv-cpu-seq-api", + "drv-i2c-api", + "drv-stm32xx-i2c", + "drv-stm32xx-sys-api", + "idol", + "num-traits", + "ringbuf", + "spd", + "stm32h7", + "task-jefe-api", + "task-packrat-api", + "userlib", +] + [[package]] name = "task-template" version = "0.1.0" From fcc6adff43eae84e022c15cc00e9a9b2aa97a260 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Thu, 23 May 2024 18:19:40 -0700 Subject: [PATCH 02/14] Implement transient override for RoT Hubris boot selection. See bootleby:src/lib.rs for the receiving end of the override selection. --- Cargo.lock | 7 +++++ Cargo.toml | 1 + app/rot-carrier/app.toml | 2 +- chips/lpc55/memory.toml | 16 ++++++++++ drv/lpc55-update-server/Cargo.toml | 1 + drv/lpc55-update-server/src/main.rs | 47 +++++++++++++++++++++++++++-- 6 files changed, 71 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2c8ed4749..6237e8767 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3219,6 +3219,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + [[package]] name = "hif" version = "0.3.1" @@ -3710,6 +3716,7 @@ dependencies = [ "drv-lpc55-syscon-api", "drv-lpc55-update-api", "drv-update-api", + "hex-literal", "hubpack", "idol", "idol-runtime", diff --git a/Cargo.toml b/Cargo.toml index 9a739c230..06a616bc4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,6 +82,7 @@ getrandom = { version = "0.2", default-features = false } goblin = { version = "0.4.3", default-features = true } # goblin::Object doesn't work without everything enabled heapless = { version = "0.7.17", default-features = false } heck = { version = "0.5.0", default-features = false } +hex-literal = { version = "0.4.1" } hkdf = { version = "0.12", default-features = false } hmac = { version = "0.12.1", default-features = false } hubpack = { version = "0.1.2", default-features = false } diff --git a/app/rot-carrier/app.toml b/app/rot-carrier/app.toml index 3baaacf7e..bf09cc836 100644 --- a/app/rot-carrier/app.toml +++ b/app/rot-carrier/app.toml @@ -42,7 +42,7 @@ priority = 3 # TODO size this appropriately stacksize = 8192 start = true -sections = {bootstate = "usbsram"} +sections = {bootstate = "usbsram", transient_override = "override"} uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/chips/lpc55/memory.toml b/chips/lpc55/memory.toml index 47be0adc4..844b85d2c 100644 --- a/chips/lpc55/memory.toml +++ b/chips/lpc55/memory.toml @@ -93,6 +93,22 @@ write = true execute = false dma = true +[[override]] +name = "a" +address = 0x3003ffe0 +size = 32 +read = true +write = true +execute = false + +[[override]] +name = "b" +address = 0x3003ffe0 +size = 32 +read = true +write = true +execute = false + # Info about the images loaded into flash and dumped by stage0 into USB SRAM # for hubris use. [[usbsram]] diff --git a/drv/lpc55-update-server/Cargo.toml b/drv/lpc55-update-server/Cargo.toml index caaa5dfd9..092d27c5f 100644 --- a/drv/lpc55-update-server/Cargo.toml +++ b/drv/lpc55-update-server/Cargo.toml @@ -21,6 +21,7 @@ mutable-statics = { path = "../../lib/mutable-statics" } cfg-if.workspace = true hubpack.workspace = true +hex-literal.workspace = true idol-runtime.workspace = true lpc55-pac.workspace = true num-traits.workspace = true diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index 554c1283b..6f19df549 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -18,6 +18,7 @@ use drv_lpc55_update_api::{ SlotId, SwitchDuration, UpdateTarget, VersionedRotBootInfo, }; use drv_update_api::UpdateError; +use hex_literal::hex; use idol_runtime::{ ClientError, Leased, LenLimit, NotificationHandler, RequestError, R, W, }; @@ -40,6 +41,10 @@ const PAGE_SIZE: u32 = BYTES_PER_FLASH_PAGE as u32; #[link_section = ".bootstate"] static BOOTSTATE: MaybeUninit<[u8; 0x1000]> = MaybeUninit::uninit(); +#[used] +#[link_section = ".transient_override"] +static mut TRANSIENT_OVERRIDE: MaybeUninit<[u8; 32]> = MaybeUninit::uninit(); + #[derive(Copy, Clone, PartialEq)] enum UpdateState { NoUpdate, @@ -503,6 +508,12 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { ringbuf_entry!(Trace::State(self.state)); self.next_block = None; self.fw_cache.fill(0); + // The sequence: [update, set transient preference, update] is legal. + // Clear any stale transient preference before update. + // Stage0 doesn't support transient override. + if component == RotComponent::Hubris { + set_hubris_transient_override(None); + } Ok(()) } @@ -907,8 +918,11 @@ impl ServerImpl<'_> { ) -> Result<(), RequestError> { match duration { SwitchDuration::Once => { - // TODO deposit command token into buffer - return Err(UpdateError::NotImplemented.into()); + // TODO check Rollback policy vs epoch before activating. + // TODO: prep-image-update should clear transient selection. + // e.g. update, activate, update, reboot should not have + // transient boot set. + set_hubris_transient_override(Some(slot)); } SwitchDuration::Forever => { // Locate and return the authoritative CFPA flash word number @@ -1337,6 +1351,35 @@ fn bootstate() -> Result { RotBootStateV2::load_from_addr(addr) } +fn set_transient_override(preference: [u8; 32]) { + // Safety: Data is consumed by Bootleby on next boot. + // There are no concurrent writers possible. + // Calling this function multiple times is ok. + // Bootleby is careful to vet contents before acting. + unsafe { + TRANSIENT_OVERRIDE.write(preference); + } +} + +pub fn set_hubris_transient_override(bank: Option) { + // Preference constants are taken from bootleby:src/lib.rs + const PREFER_SLOT_A: [u8; 32] = hex!( + "edb23f2e9b399c3d57695262f29615910ed10c8d9b261bfc2076b8c16c84f66d" + ); + const PREFER_SLOT_B: [u8; 32] = hex!( + "70ed2914e6fdeeebbb02763b96da9faa0160b7fc887425f4d45547071d0ce4ba" + ); + // Bootleby writes all zeros after reading. We write all ones to reset. + const PREFER_NOTHING: [u8; 32] = [0xffu8; 32]; + + match bank { + // Do we need a value that says we were here and cleared? + None => set_transient_override(PREFER_NOTHING), + Some(SlotId::A) => set_transient_override(PREFER_SLOT_A), + Some(SlotId::B) => set_transient_override(PREFER_SLOT_B), + } +} + fn round_up_to_flash_page(offset: u32) -> Option { offset.checked_next_multiple_of(BYTES_PER_FLASH_PAGE as u32) } From 0d393627662d03d8a773056d16eb10343ef70433 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Mon, 28 Apr 2025 12:28:25 -0700 Subject: [PATCH 03/14] update tasks.update_server in other LPC55 app.toml files --- app/lpc55xpresso/app.toml | 2 +- app/oxide-rot-1/app-dev.toml | 2 +- app/oxide-rot-1/app.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/lpc55xpresso/app.toml b/app/lpc55xpresso/app.toml index a3b9fa2b2..d7dacf550 100644 --- a/app/lpc55xpresso/app.toml +++ b/app/lpc55xpresso/app.toml @@ -50,7 +50,7 @@ priority = 3 max-sizes = {flash = 26720, ram = 16704} stacksize = 8192 start = true -sections = {bootstate = "usbsram"} +sections = {bootstate = "usbsram", transient_override = "override"} uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/app/oxide-rot-1/app-dev.toml b/app/oxide-rot-1/app-dev.toml index e1aaa9570..5d5448aef 100644 --- a/app/oxide-rot-1/app-dev.toml +++ b/app/oxide-rot-1/app-dev.toml @@ -54,7 +54,7 @@ name = "lpc55-update-server" priority = 3 stacksize = 8192 start = true -sections = {bootstate = "usbsram"} +sections = {bootstate = "usbsram", transient_override = "override"} uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/app/oxide-rot-1/app.toml b/app/oxide-rot-1/app.toml index c57eec859..056b170af 100644 --- a/app/oxide-rot-1/app.toml +++ b/app/oxide-rot-1/app.toml @@ -42,7 +42,7 @@ name = "lpc55-update-server" priority = 3 stacksize = 8192 start = true -sections = {bootstate = "usbsram"} +sections = {bootstate = "usbsram", transient_override = "override"} uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} From 81b02bda1264ecc8aa051bd5549ec51489708633 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Tue, 29 Apr 2025 14:00:20 -0700 Subject: [PATCH 04/14] Use non-priviledged transient boot preference token address --- chips/lpc55/memory.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chips/lpc55/memory.toml b/chips/lpc55/memory.toml index 844b85d2c..1b940867e 100644 --- a/chips/lpc55/memory.toml +++ b/chips/lpc55/memory.toml @@ -95,7 +95,7 @@ dma = true [[override]] name = "a" -address = 0x3003ffe0 +address = 0x2003ffe0 size = 32 read = true write = true From f764f83b880db20c274663499011a473a1c398e8 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Fri, 16 May 2025 18:14:13 -0700 Subject: [PATCH 05/14] include current state of transient override in RotBootInfo --- drv/lpc55-update-server/src/main.rs | 38 +++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index 6f19df549..845c62ff9 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -637,9 +637,7 @@ impl ServerImpl<'_> { None }; - // We only support persistent override at this point - // We need to read the magic ram value to fill this in. - let transient_boot_preference = None; + let transient_boot_preference = get_hubris_transient_override(); Ok(( persistent_boot_preference, @@ -1361,17 +1359,23 @@ fn set_transient_override(preference: [u8; 32]) { } } -pub fn set_hubris_transient_override(bank: Option) { - // Preference constants are taken from bootleby:src/lib.rs - const PREFER_SLOT_A: [u8; 32] = hex!( - "edb23f2e9b399c3d57695262f29615910ed10c8d9b261bfc2076b8c16c84f66d" - ); - const PREFER_SLOT_B: [u8; 32] = hex!( - "70ed2914e6fdeeebbb02763b96da9faa0160b7fc887425f4d45547071d0ce4ba" - ); - // Bootleby writes all zeros after reading. We write all ones to reset. - const PREFER_NOTHING: [u8; 32] = [0xffu8; 32]; +fn get_transient_override() -> [u8; 32] { + // Safety: Data is consumed by Bootleby on next boot. + // There are no concurrent writers possible. + // Bootleby consumes and resets TRANSIENT_OVERRIDE. + // The client may be verifying state set during update flows. + unsafe { TRANSIENT_OVERRIDE.assume_init() } +} + +// Preference constants are taken from bootleby:src/lib.rs +const PREFER_SLOT_A: [u8; 32] = + hex!("edb23f2e9b399c3d57695262f29615910ed10c8d9b261bfc2076b8c16c84f66d"); +const PREFER_SLOT_B: [u8; 32] = + hex!("70ed2914e6fdeeebbb02763b96da9faa0160b7fc887425f4d45547071d0ce4ba"); +// Bootleby writes all zeros after reading. We write all ones to reset. +const PREFER_NOTHING: [u8; 32] = [0xffu8; 32]; +pub fn set_hubris_transient_override(bank: Option) { match bank { // Do we need a value that says we were here and cleared? None => set_transient_override(PREFER_NOTHING), @@ -1380,6 +1384,14 @@ pub fn set_hubris_transient_override(bank: Option) { } } +pub fn get_hubris_transient_override() -> Option { + match get_transient_override() { + PREFER_SLOT_A => Some(SlotId::A), + PREFER_SLOT_B => Some(SlotId::B), + _ => None, + } +} + fn round_up_to_flash_page(offset: u32) -> Option { offset.checked_next_multiple_of(BYTES_PER_FLASH_PAGE as u32) } From ad0e16e07d88bf8748cc3338ed3ecd8603723567 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Wed, 21 May 2025 11:32:37 -0700 Subject: [PATCH 06/14] wip - TODO: remove patch. added InvalidPreferredSlotId --- Cargo.toml | 3 +++ drv/lpc55-update-server/src/main.rs | 42 ++++++++++++++++++++++------- drv/update-api/src/lib.rs | 3 +++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 06a616bc4..c67538952 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,9 @@ path = "sys/abi" [patch."https://github.com/oxidecomputer/hubris".counters] path = "lib/counters" +[patch."https://github.com/oxidecomputer/management-gateway-service".gateway-messages] +path = "/home/stoltz/Oxide/src/management-gateway-service/gateway-messages" + [workspace.dependencies] anyhow = { version = "1.0.31", default-features = false, features = ["std"] } array-init = { version = "2.1.0" } diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index 845c62ff9..2f9d78c93 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -498,22 +498,46 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { UpdateState::Finished | UpdateState::NoUpdate => (), } - self.image = match (component, slot) { + let image = match (component, slot) { (RotComponent::Hubris, SlotId::A) - | (RotComponent::Hubris, SlotId::B) - | (RotComponent::Stage0, SlotId::B) => Some((component, slot)), + | (RotComponent::Hubris, SlotId::B) => { + let active = match bootstate().map_err(|_| UpdateError::MissingHandoffData)?.active { + stage0_handoff::RotSlot::A => SlotId::A, + stage0_handoff::RotSlot::B => SlotId::B, + }; + if active == slot { + return Err(UpdateError::InvalidSlotIdForOperation.into()); + } + // Since we will be enforcing rollback protection at the time when the + // boot preference is set, we cannot yet have the alternate image as the + // preferred image. The full image needs to be in place in order to + // evaluate the policy. + let (persistent, pending_persistent, transient) = self.boot_preferences()?; + if let Some(pref) = transient { + if active != pref { + return Err(UpdateError::InvalidPreferredSlotId.into()); + } + } + if let Some(pref) = pending_persistent { + if active != pref { + return Err(UpdateError::InvalidPreferredSlotId.into()) + } + } + if active != persistent { + return Err(UpdateError::InvalidPreferredSlotId.into()) + } + Some((component, slot)) + } + (RotComponent::Stage0, SlotId::B) => Some((component, slot)), _ => return Err(UpdateError::InvalidSlotIdForOperation.into()), }; + + + self.image = image; self.state = UpdateState::InProgress; ringbuf_entry!(Trace::State(self.state)); self.next_block = None; self.fw_cache.fill(0); - // The sequence: [update, set transient preference, update] is legal. - // Clear any stale transient preference before update. - // Stage0 doesn't support transient override. - if component == RotComponent::Hubris { - set_hubris_transient_override(None); - } Ok(()) } diff --git a/drv/update-api/src/lib.rs b/drv/update-api/src/lib.rs index 4f77a7333..492fe9467 100644 --- a/drv/update-api/src/lib.rs +++ b/drv/update-api/src/lib.rs @@ -65,6 +65,8 @@ pub enum UpdateError { ImageMismatch, SignatureNotValidated, VersionNotSupported, + + InvalidPreferredSlotId, } impl From for GwUpdateError { @@ -103,6 +105,7 @@ impl From for GwUpdateError { UpdateError::ImageMismatch => Self::ImageMismatch, UpdateError::SignatureNotValidated => Self::SignatureNotValidated, UpdateError::VersionNotSupported => Self::VersionNotSupported, + UpdateError::InvalidPreferredSlotId => Self::InvalidPreferredSlotId, } } } From 0a18850f6379e26650e5a7fa27bbb69aae1edd4e Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Mon, 2 Jun 2025 12:12:33 -0700 Subject: [PATCH 07/14] update bitflags --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c67538952..81a1740c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ array-init = { version = "2.1.0" } arrayvec = { version = "0.7.4", default-features = false } atty = { version = "0.2", default-features = false } bitfield = { version = "0.13", default-features = false } -bitflags = { version = "2.5.0", default-features = false } +bitflags = { version = "2.9.1", default-features = false } bstringify = { version = "0.1.2", default-features = false } byteorder = { version = "1.3.4", default-features = false } bzip2-rs = { version = "0.1.2", default-features = false } From d587a66894d300052e38f1acc58314a5ca9e2d22 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Mon, 9 Jun 2025 12:12:01 -0700 Subject: [PATCH 08/14] Setting the transient pref. to current active slot clears it. Given the current API for setting the transient boot preference there is an implementation choice. While setting the transient selection to the alternate image (currently non-active) is the common use case, we also need to define what happens when the transient preference is specified to be the currently active RoT Hubris image. The simple case is that setting transient to active will clear the transient selection. That is the choice this PR makes. The other case, setting an actual transient preference to the active gives rise to some more complex behavior that is just annoying. Assume that A is active, B is the pending persistent preference, and A is also the transient preference. On the first reset, the ROM will promote the CFPA scratch page to active, thus making B the persistent preference. However, Bootleby will use the transient preference of A to select the active image. The RoT will then be running Hubris image A. Bootleby has cleared the transient selection. On the second reset, there is no transient selection or pending persistent. Bootleby will select Hubris image B. These scenarios have been tested and analyzed and there is no motivation found for enabling this sequence. If, after merging this PR, it is found that we do want to enable this sequence of two resets in a row running different images, we can change the API to an enum of `Select(SlotId)` or `ClearSelection`. --- Hubris issue 2093 was found in testing where setting the persistent preference to different values in succession leads to the inability to clear a pending persistent boot preference. This may be needed to recover from a previous failed/abandoned RoT Hubris update where one wants to avoid additional reset operations. This is a corner case with a workaround, but it is also against the intent of the API. --- Cargo.toml | 3 -- drv/lpc55-update-server/src/main.rs | 66 +++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 81a1740c0..fece03af1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,9 +44,6 @@ path = "sys/abi" [patch."https://github.com/oxidecomputer/hubris".counters] path = "lib/counters" -[patch."https://github.com/oxidecomputer/management-gateway-service".gateway-messages] -path = "/home/stoltz/Oxide/src/management-gateway-service/gateway-messages" - [workspace.dependencies] anyhow = { version = "1.0.31", default-features = false, features = ["std"] } array-init = { version = "2.1.0" } diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index 2f9d78c93..e6ba9c803 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -501,18 +501,25 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { let image = match (component, slot) { (RotComponent::Hubris, SlotId::A) | (RotComponent::Hubris, SlotId::B) => { - let active = match bootstate().map_err(|_| UpdateError::MissingHandoffData)?.active { + let active = match bootstate() + .map_err(|_| UpdateError::MissingHandoffData)? + .active + { stage0_handoff::RotSlot::A => SlotId::A, stage0_handoff::RotSlot::B => SlotId::B, }; if active == slot { return Err(UpdateError::InvalidSlotIdForOperation.into()); } - // Since we will be enforcing rollback protection at the time when the - // boot preference is set, we cannot yet have the alternate image as the - // preferred image. The full image needs to be in place in order to - // evaluate the policy. - let (persistent, pending_persistent, transient) = self.boot_preferences()?; + // Rollback protection will be implemented by refusing to set + // boot preference to an image that has a lower EPOC vale in the + // caboose. + // + // Setting the boot preference before updating would sidestep that + // protection. So, we will fail the prepare step if any + // preference settings are selecting the update target image. + let (persistent, pending_persistent, transient) = + self.boot_preferences()?; if let Some(pref) = transient { if active != pref { return Err(UpdateError::InvalidPreferredSlotId.into()); @@ -520,11 +527,11 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { } if let Some(pref) = pending_persistent { if active != pref { - return Err(UpdateError::InvalidPreferredSlotId.into()) + return Err(UpdateError::InvalidPreferredSlotId.into()); } } if active != persistent { - return Err(UpdateError::InvalidPreferredSlotId.into()) + return Err(UpdateError::InvalidPreferredSlotId.into()); } Some((component, slot)) } @@ -532,7 +539,6 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { _ => return Err(UpdateError::InvalidSlotIdForOperation.into()), }; - self.image = image; self.state = UpdateState::InProgress; ringbuf_entry!(Trace::State(self.state)); @@ -938,13 +944,32 @@ impl ServerImpl<'_> { slot: SlotId, duration: SwitchDuration, ) -> Result<(), RequestError> { + // Note: Rollback policy will be checking epoch values before activating. match duration { SwitchDuration::Once => { - // TODO check Rollback policy vs epoch before activating. - // TODO: prep-image-update should clear transient selection. - // e.g. update, activate, update, reboot should not have - // transient boot set. - set_hubris_transient_override(Some(slot)); + // Get the currently active slot. + let active_slot = match bootstate() + .map_err(|_| UpdateError::MissingHandoffData)? + .active + { + stage0_handoff::RotSlot::A => SlotId::A, + stage0_handoff::RotSlot::B => SlotId::B, + }; + + // If the requested slot is the same as the active slot, + // treat this as a request to CLEAR the transient override. + // + // If we did allow setting the active slot as the transient + // preference, then we get this confusing 2-boot scenario when + // pending persistent preference is also used: + // the next reset returns us to the original image and the 2nd + // reset has us running the new/alternate image. + if active_slot == slot { + set_hubris_transient_override(None); + } else { + // Otherwise, set the preference as requested. + set_hubris_transient_override(Some(slot)); + } } SwitchDuration::Forever => { // Locate and return the authoritative CFPA flash word number @@ -976,6 +1001,19 @@ impl ServerImpl<'_> { let (cfpa_word_number, _) = self.cfpa_word_number_and_version(CfpaPage::Active)?; + // TODO: Hubris issue #2093: If there is a pending update in the + // scratch page, it is not being considered. + // Consider: + // - A is active + // - persistent switch to B without reset + // - scratch page is updated + // - return Ok(()) + // - persistent switch to A without reset + // - A is already active, no work performed + // - return Ok(()) + // - reset + // - B is active + // Read current CFPA contents. let mut cfpa = [[0u32; 4]; 512 / 16]; indirect_flash_read_words( From bcdcbe90c49811af600c4fbf57ac0fb8d05b06a0 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Tue, 17 Jun 2025 12:17:49 -0700 Subject: [PATCH 09/14] Transient override address, component_prep_image_update. Fixes from review. Fix memory alias for RoT Hubris 'B' image's access to transient boot override setting. `component_update_prep_image` was using `bootstate` to determine active image. The `same_image` function is a more direct test and does not depend on `bootstate` being valid. --- Cargo.lock | 35 +++++++++++------------ chips/lpc55/memory.toml | 2 +- drv/lpc55-update-server/src/main.rs | 44 ++++++++++++++++------------- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6237e8767..641fdca06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,7 +6,7 @@ version = 4 name = "abi" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "byteorder", "phash", "serde", @@ -271,9 +271,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bitvec" @@ -337,7 +337,7 @@ dependencies = [ name = "build-kconfig" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "serde", ] @@ -1622,7 +1622,7 @@ version = "0.1.0" dependencies = [ "anyhow", "attest-api", - "bitflags 2.9.1", + "bitflags 2.9.4", "build-lpc55pins", "build-util", "call_rustfmt", @@ -1722,7 +1722,7 @@ dependencies = [ name = "drv-mb85rsxx-fram" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "counters", "drv-spi-api", ] @@ -2594,7 +2594,7 @@ dependencies = [ name = "drv-stm32xx-sys" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "build-stm32xx-sys", "build-util", "cfg-if", @@ -3017,9 +3017,9 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service#83fe1885c9916cebbee261c47a09d832d75b7df0" +source = "git+https://github.com/oxidecomputer/management-gateway-service#ef7ce28f349dca6774b931bb169690e908e3eecd" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "hubpack", "serde", "serde-big-array 0.5.1", @@ -3257,7 +3257,7 @@ dependencies = [ name = "host-sp-messages" version = "0.1.0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "counters", "drv-i2c-types", "fletcher", @@ -3503,7 +3503,7 @@ dependencies = [ "abi", "anyhow", "armv8-m-mpu", - "bitflags 2.9.1", + "bitflags 2.9.4", "build-kconfig", "build-util", "byteorder", @@ -5211,20 +5211,19 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" [[package]] name = "strum_macros" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "rustversion", "syn 2.0.98", ] @@ -6045,7 +6044,7 @@ name = "task-thermal" version = "0.1.0" dependencies = [ "anyhow", - "bitflags 2.9.1", + "bitflags 2.9.4", "build-i2c", "build-util", "cortex-m", @@ -6620,7 +6619,7 @@ name = "transceiver-messages" version = "0.1.1" source = "git+https://github.com/oxidecomputer/transceiver-control/#c5564eb96ddc7887a02596cc039662c87e906d0c" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.4", "hubpack", "serde", ] diff --git a/chips/lpc55/memory.toml b/chips/lpc55/memory.toml index 1b940867e..012577741 100644 --- a/chips/lpc55/memory.toml +++ b/chips/lpc55/memory.toml @@ -103,7 +103,7 @@ execute = false [[override]] name = "b" -address = 0x3003ffe0 +address = 0x2003ffe0 size = 32 read = true write = true diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index e6ba9c803..e2eedd545 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -498,39 +498,46 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { UpdateState::Finished | UpdateState::NoUpdate => (), } - let image = match (component, slot) { + self.image = match (component, slot) { (RotComponent::Hubris, SlotId::A) | (RotComponent::Hubris, SlotId::B) => { - let active = match bootstate() - .map_err(|_| UpdateError::MissingHandoffData)? - .active - { - stage0_handoff::RotSlot::A => SlotId::A, - stage0_handoff::RotSlot::B => SlotId::B, - }; - if active == slot { + // Fail early on attempt to update the running image. + if same_image(component, slot) { return Err(UpdateError::InvalidSlotIdForOperation.into()); } + // Rollback protection will be implemented by refusing to set - // boot preference to an image that has a lower EPOC vale in the - // caboose. - // + // boot preference to an image that has a lower EPOC value in + // its caboose. // Setting the boot preference before updating would sidestep that // protection. So, we will fail the prepare step if any // preference settings are selecting the update target image. + // + // After the update, the boot image selection will be based on: + // - there being only one properly signed image, or + // - transient boot selection (highest priority), or + // - pending persistent selection (altering the persistent + // selection) + // - persistent preference if neither of the above was used. + let (persistent, pending_persistent, transient) = self.boot_preferences()?; + + // The transient preference must not select the update target. if let Some(pref) = transient { - if active != pref { + if slot == pref { return Err(UpdateError::InvalidPreferredSlotId.into()); } } + // If there is a pending persistent preference, it must + // not select the update target. if let Some(pref) = pending_persistent { - if active != pref { + if slot == pref { return Err(UpdateError::InvalidPreferredSlotId.into()); } - } - if active != persistent { + } else if slot == persistent { + // If there is no pending persistent preference, then the + // persistent preference must select the currently active image. return Err(UpdateError::InvalidPreferredSlotId.into()); } Some((component, slot)) @@ -538,8 +545,6 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { (RotComponent::Stage0, SlotId::B) => Some((component, slot)), _ => return Err(UpdateError::InvalidSlotIdForOperation.into()), }; - - self.image = image; self.state = UpdateState::InProgress; ringbuf_entry!(Trace::State(self.state)); self.next_block = None; @@ -1430,16 +1435,15 @@ fn get_transient_override() -> [u8; 32] { } // Preference constants are taken from bootleby:src/lib.rs +// Note that Bootleby uses this same array to communicate the boot decision log to Hubris. const PREFER_SLOT_A: [u8; 32] = hex!("edb23f2e9b399c3d57695262f29615910ed10c8d9b261bfc2076b8c16c84f66d"); const PREFER_SLOT_B: [u8; 32] = hex!("70ed2914e6fdeeebbb02763b96da9faa0160b7fc887425f4d45547071d0ce4ba"); -// Bootleby writes all zeros after reading. We write all ones to reset. const PREFER_NOTHING: [u8; 32] = [0xffu8; 32]; pub fn set_hubris_transient_override(bank: Option) { match bank { - // Do we need a value that says we were here and cleared? None => set_transient_override(PREFER_NOTHING), Some(SlotId::A) => set_transient_override(PREFER_SLOT_A), Some(SlotId::B) => set_transient_override(PREFER_SLOT_B), From 064a511b30a5f635e891f530687513a13e23bd94 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Tue, 24 Jun 2025 09:26:30 -0700 Subject: [PATCH 10/14] Update drv/lpc55-update-server/src/main.rs Co-authored-by: Matt Keeter --- drv/lpc55-update-server/src/main.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index e2eedd545..971aae8d5 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -524,17 +524,13 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { self.boot_preferences()?; // The transient preference must not select the update target. - if let Some(pref) = transient { - if slot == pref { - return Err(UpdateError::InvalidPreferredSlotId.into()); - } + if transient == Some(slot) { + return Err(UpdateError::InvalidPreferredSlotId.into()); } // If there is a pending persistent preference, it must // not select the update target. - if let Some(pref) = pending_persistent { - if slot == pref { - return Err(UpdateError::InvalidPreferredSlotId.into()); - } + if pending_persistent == Some(slot) { + return Err(UpdateError::InvalidPreferredSlotId.into()); } else if slot == persistent { // If there is no pending persistent preference, then the // persistent preference must select the currently active image. From f31c89d615b8fb9d44616a93861e22fb7cabbaa1 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Fri, 11 Jul 2025 15:23:01 -0700 Subject: [PATCH 11/14] wip --- app/lpc55xpresso/app.toml | 1 - drv/lpc55-sprot-server/src/handler.rs | 10 ++ drv/lpc55-update-server/src/main.rs | 128 +++++++++++++----- drv/sprot-api/src/lib.rs | 5 + drv/stm32h7-sprot-server/src/main.rs | 22 +++ drv/update-api/src/lib.rs | 4 + idl/lpc55-update.idol | 14 ++ idl/sprot.idol | 14 ++ task/control-plane-agent/src/main.rs | 5 + task/control-plane-agent/src/mgs_common.rs | 46 +++++++ .../src/mgs_compute_sled.rs | 23 ++++ task/control-plane-agent/src/mgs_psc.rs | 23 ++++ task/control-plane-agent/src/mgs_sidecar.rs | 23 ++++ 13 files changed, 283 insertions(+), 35 deletions(-) diff --git a/app/lpc55xpresso/app.toml b/app/lpc55xpresso/app.toml index d7dacf550..c983eb2b8 100644 --- a/app/lpc55xpresso/app.toml +++ b/app/lpc55xpresso/app.toml @@ -47,7 +47,6 @@ start = true [tasks.update_server] name = "lpc55-update-server" priority = 3 -max-sizes = {flash = 26720, ram = 16704} stacksize = 8192 start = true sections = {bootstate = "usbsram", transient_override = "override"} diff --git a/drv/lpc55-sprot-server/src/handler.rs b/drv/lpc55-sprot-server/src/handler.rs index eab40b4c8..9ba41809d 100644 --- a/drv/lpc55-sprot-server/src/handler.rs +++ b/drv/lpc55-sprot-server/src/handler.rs @@ -679,6 +679,16 @@ impl<'a> Handler { Ok((RspBody::State(out.map(StateRsp::LifecycleState)), None)) } + ReqBody::Update(UpdateReq::ComponentSwitchCancelPending { + component, + slot, + duration, + }) => { + self.update.component_switch_cancel_pending( + component, slot, duration, + )?; + Ok((RspBody::Ok, None)) + } } } diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index 971aae8d5..52cbab71d 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -571,6 +571,23 @@ impl idl::InOrderUpdateImpl for ServerImpl<'_> { } } } + + fn component_switch_cancel_pending( + &mut self, + _: &userlib::RecvMessage, + component: RotComponent, + slot: SlotId, + duration: SwitchDuration, + ) -> Result<(), RequestError> { + match component { + RotComponent::Hubris => { + self.switch_default_hubris_image_cancel_pending(slot, duration) + } + RotComponent::Stage0 => { + Err(UpdateError::InvalidSlotIdForOperation.into()) + } + } + } } impl NotificationHandler for ServerImpl<'_> { @@ -615,7 +632,7 @@ impl ServerImpl<'_> { Ok(val) } - // Return the persistent and transient boot preferences + // Return the persistent, pending_persistent, and transient boot preferences fn boot_preferences( &mut self, ) -> Result<(SlotId, Option, Option), UpdateError> { @@ -946,33 +963,24 @@ impl ServerImpl<'_> { duration: SwitchDuration, ) -> Result<(), RequestError> { // Note: Rollback policy will be checking epoch values before activating. + match duration { SwitchDuration::Once => { - // Get the currently active slot. - let active_slot = match bootstate() - .map_err(|_| UpdateError::MissingHandoffData)? - .active - { - stage0_handoff::RotSlot::A => SlotId::A, - stage0_handoff::RotSlot::B => SlotId::B, - }; - - // If the requested slot is the same as the active slot, - // treat this as a request to CLEAR the transient override. - // - // If we did allow setting the active slot as the transient - // preference, then we get this confusing 2-boot scenario when - // pending persistent preference is also used: - // the next reset returns us to the original image and the 2nd - // reset has us running the new/alternate image. - if active_slot == slot { - set_hubris_transient_override(None); + if get_hubris_transient_override().is_some() { + // Maybe something is out-of-sync in the control plane? + // An error returned here can help narrow that down up there. + // The caller must clear the existing pending preference. + return Err(UpdateError::AlreadyPending.into()); } else { - // Otherwise, set the preference as requested. set_hubris_transient_override(Some(slot)); } } SwitchDuration::Forever => { + // Caller must first cancel pending persistent state if present. + if let (_, Some(_), _) = self.boot_preferences()? { + return Err(UpdateError::AlreadyPending.into()); + } + // Locate and return the authoritative CFPA flash word number // and the CFPA version for that flash number. // @@ -1002,19 +1010,6 @@ impl ServerImpl<'_> { let (cfpa_word_number, _) = self.cfpa_word_number_and_version(CfpaPage::Active)?; - // TODO: Hubris issue #2093: If there is a pending update in the - // scratch page, it is not being considered. - // Consider: - // - A is active - // - persistent switch to B without reset - // - scratch page is updated - // - return Ok(()) - // - persistent switch to A without reset - // - A is already active, no work performed - // - return Ok(()) - // - reset - // - B is active - // Read current CFPA contents. let mut cfpa = [[0u32; 4]; 512 / 16]; indirect_flash_read_words( @@ -1102,6 +1097,71 @@ impl ServerImpl<'_> { Ok(()) } + + /// Cancel pending transient or persistent Hubris image selection. + fn switch_default_hubris_image_cancel_pending( + &mut self, + slot: SlotId, + duration: SwitchDuration, + ) -> Result<(), RequestError> { + // Note: Rollback policy will be checking epoch values before activating. + match duration { + SwitchDuration::Once => { + // Is there a pending transient boot selection? + // If it matches the one being cancelled + if let Some(transient_selection) = + get_hubris_transient_override() + { + if transient_selection == slot { + set_hubris_transient_override(None); + Ok(()) + } else { + Err(UpdateError::InvalidPreferredSlotId.into()) + } + } else { + Err(UpdateError::NonePending.into()) + } + } + SwitchDuration::Forever => { + // Note: Scratch page data does not have to be preserved unless/until we have + // multiple fields with pending updates. Right now, we only implement the + // pending_persistent bit. IMAGE_KEY_REVOKE and RKTH_REVOKE + // fields are not yet managed. + + if let (_, Some(pending_persistent), _) = + self.boot_preferences()? + { + if slot == pending_persistent { + // Cancel the CFPA update by erase/writing zeros to the + // scratch page. + // As a result, the scratch page verison will never be + // higher than the active page version. + // Also, we won't fix the CRC so it won't be deemed + // valid by the boot ROM in any case. + let cfpa = [[0u32; 4]; 512 / 16]; + let cfpa_bytes: &[u8] = cfpa.as_bytes(); + let cfpa_bytes: &[u8; BLOCK_SIZE_BYTES] = + cfpa_bytes.try_into().unwrap_lite(); + self.flash + .write_page( + CFPA_SCRATCH_FLASH_ADDR, + cfpa_bytes, + wait_for_flash_interrupt, + ) + .map_err(|_| UpdateError::FlashError.into()) + } else { + // Slot mismatch. + // Fail assuming that the control plane was working with stale information. + Err(UpdateError::InvalidPreferredSlotId.into()) + } + } else { + // No pending persistent prefereice. + // Fail assuming that the control plane was working with stale information. + Err(UpdateError::NonePending.into()) + } + } + } + } } // Return the preferred slot to boot from for a given CFPA boot selection diff --git a/drv/sprot-api/src/lib.rs b/drv/sprot-api/src/lib.rs index 78fcd6fda..51aac25dc 100644 --- a/drv/sprot-api/src/lib.rs +++ b/drv/sprot-api/src/lib.rs @@ -413,6 +413,11 @@ pub enum UpdateReq { slot: SlotId, duration: SwitchDuration, }, + ComponentSwitchCancelPending { + component: RotComponent, + slot: SlotId, + duration: SwitchDuration, + }, } #[derive(Clone, Serialize, Deserialize, SerializedSize)] diff --git a/drv/stm32h7-sprot-server/src/main.rs b/drv/stm32h7-sprot-server/src/main.rs index 8bb9c3e1a..160cebae2 100644 --- a/drv/stm32h7-sprot-server/src/main.rs +++ b/drv/stm32h7-sprot-server/src/main.rs @@ -1345,6 +1345,28 @@ impl idl::InOrderSpRotImpl for ServerImpl { } } + fn component_switch_cancel_pending( + &mut self, + _msg: &userlib::RecvMessage, + component: RotComponent, + slot: SlotId, + duration: SwitchDuration, + ) -> Result<(), idol_runtime::RequestError> { + let body = ReqBody::Update(UpdateReq::ComponentSwitchCancelPending { + component, + slot, + duration, + }); + let tx_size = Request::pack(&body, self.tx_buf); + let rsp = + self.do_send_recv_retries(tx_size, TIMEOUT_LONG, DEFAULT_ATTEMPTS)?; + if let RspBody::Ok = rsp.body? { + Ok(()) + } else { + Err(SprotProtocolError::UnexpectedResponse)? + } + } + fn lifecycle_state( &mut self, _msg: &userlib::RecvMessage, diff --git a/drv/update-api/src/lib.rs b/drv/update-api/src/lib.rs index 492fe9467..e3a1c9fed 100644 --- a/drv/update-api/src/lib.rs +++ b/drv/update-api/src/lib.rs @@ -67,6 +67,8 @@ pub enum UpdateError { VersionNotSupported, InvalidPreferredSlotId, + // AlreadyPending, + // NonePending, } impl From for GwUpdateError { @@ -106,6 +108,8 @@ impl From for GwUpdateError { UpdateError::SignatureNotValidated => Self::SignatureNotValidated, UpdateError::VersionNotSupported => Self::VersionNotSupported, UpdateError::InvalidPreferredSlotId => Self::InvalidPreferredSlotId, + // UpdateError::AlreadyPending => Self::AlreadyPending, + // UpdateError::NonePending => Self::NonePending, } } } diff --git a/idl/lpc55-update.idol b/idl/lpc55-update.idol index cf2bec9b5..a7d803020 100644 --- a/idl/lpc55-update.idol +++ b/idl/lpc55-update.idol @@ -212,5 +212,19 @@ Interface( idempotent: true, encoding: Hubpack ), + "component_switch_cancel_pending": ( + doc: "Cancal a pending persistent or transient image switch", + args: { + "component": "RotComponent", + "slot": "SlotId", + "duration": "SwitchDuration", + }, + reply: Result( + ok: "()", + err: CLike("drv_update_api::UpdateError"), + ), + encoding: Hubpack, + idempotent: true, + ), }, ) diff --git a/idl/sprot.idol b/idl/sprot.idol index 0d22d2cf7..621c06288 100644 --- a/idl/sprot.idol +++ b/idl/sprot.idol @@ -443,5 +443,19 @@ Interface( encoding: Hubpack, idempotent: true, ), + "component_switch_cancel_pending": ( + doc: "Cancal a pending persistent or transient image switch", + args: { + "component": "RotComponent", + "slot": "SlotId", + "duration": "SwitchDuration", + }, + reply: Result( + ok: "()", + err: Complex("SprotError"), + ), + encoding: Hubpack, + idempotent: true, + ), } ) diff --git a/task/control-plane-agent/src/main.rs b/task/control-plane-agent/src/main.rs index 6e79a0554..dcd1468ed 100644 --- a/task/control-plane-agent/src/main.rs +++ b/task/control-plane-agent/src/main.rs @@ -179,6 +179,11 @@ enum MgsMessage { GetHostFlashHash { slot: u16, }, + ComponentCancelPendingActiveSlot { + component: SpComponent, + slot: u16, + persist: bool, + }, } // This enum does not define the actual IPC protocol - it is only used in the diff --git a/task/control-plane-agent/src/mgs_common.rs b/task/control-plane-agent/src/mgs_common.rs index 1ef23dc77..297152f44 100644 --- a/task/control-plane-agent/src/mgs_common.rs +++ b/task/control-plane-agent/src/mgs_common.rs @@ -429,6 +429,52 @@ impl MgsCommon { } } + pub(crate) fn component_cancel_pending_active_slot( + &mut self, + component: SpComponent, + slot: u16, + persist: bool, + ) -> Result<(), GwSpError> { + match component { + SpComponent::ROT | SpComponent::STAGE0 => { + let slot = slot + .try_into() + .map_err(|()| GwSpError::RequestUnsupportedForComponent)?; + let duration = if persist { + SwitchDuration::Forever + } else { + SwitchDuration::Once + }; + self.sprot.component_switch_cancel_pending( + if component == SpComponent::ROT { + SpRotComponent::Hubris + } else { + SpRotComponent::Stage0 + }, + slot, + duration, + )?; + Ok(()) + } + + SpComponent::SP_ITSELF => { + let slot = slot + .try_into() + .map_err(|()| GwSpError::RequestUnsupportedForComponent)?; + if !persist { + // We have no mechanism to temporarily swap the banks on the SP + return Err(GwSpError::RequestUnsupportedForComponent); + }; + self.update_sp + .set_pending_boot_slot(slot) + .map_err(|err| GwSpError::UpdateFailed(err as u32))?; + Ok(()) + } + // Other components might also be served someday. + _ => 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 25d59bf96..b02962047 100644 --- a/task/control-plane-agent/src/mgs_compute_sled.rs +++ b/task/control-plane-agent/src/mgs_compute_sled.rs @@ -956,6 +956,29 @@ impl SpHandler for MgsHandler { } } + fn component_cancel_pending_active_slot( + &mut self, + component: SpComponent, + slot: u16, + persist: bool, + ) -> Result<(), SpError> { + ringbuf_entry_root!(Log::MgsMessage( + MgsMessage::ComponentCancelPendingActiveSlot { + component, + slot, + persist, + } + )); + match component { + SpComponent::HOST_CPU_BOOT_FLASH => { + Err(SpError::RequestUnsupportedForComponent) + } + _ => self + .common + .component_cancel_pending_active_slot(component, slot, persist), + } + } + 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 fdf45de98..1e48cbaa7 100644 --- a/task/control-plane-agent/src/mgs_psc.rs +++ b/task/control-plane-agent/src/mgs_psc.rs @@ -484,6 +484,29 @@ impl SpHandler for MgsHandler { .component_set_active_slot(component, slot, persist) } + fn component_cancel_pending_active_slot( + &mut self, + component: SpComponent, + slot: u16, + persist: bool, + ) -> Result<(), SpError> { + ringbuf_entry_root!(Log::MgsMessage( + MgsMessage::ComponentCancelPendingActiveSlot { + component, + slot, + persist, + } + )); + match component { + SpComponent::HOST_CPU_BOOT_FLASH => { + Err(SpError::RequestUnsupportedForComponent) + } + _ => self + .common + .component_cancel_pending_active_slot(component, slot, persist), + } + } + 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 4a5e14ed6..a877378b1 100644 --- a/task/control-plane-agent/src/mgs_sidecar.rs +++ b/task/control-plane-agent/src/mgs_sidecar.rs @@ -961,6 +961,29 @@ impl SpHandler for MgsHandler { .component_set_active_slot(component, slot, persist) } + fn component_cancel_pending_active_slot( + &mut self, + component: SpComponent, + slot: u16, + persist: bool, + ) -> Result<(), SpError> { + ringbuf_entry_root!(Log::MgsMessage( + MgsMessage::ComponentCancelPendingActiveSlot { + component, + slot, + persist, + } + )); + match component { + SpComponent::HOST_CPU_BOOT_FLASH => { + Err(SpError::RequestUnsupportedForComponent) + } + _ => self + .common + .component_cancel_pending_active_slot(component, slot, persist), + } + } + fn component_clear_status( &mut self, component: SpComponent, From c568e7819400024dd03e950f8af94a0ce357f752 Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Wed, 13 Aug 2025 10:56:50 -0700 Subject: [PATCH 12/14] Satisfy updated compiler regarding write to static mut --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- drv/lpc55-update-server/src/main.rs | 9 ++++++++- drv/update-api/src/lib.rs | 8 ++++---- task/control-plane-agent/src/mgs_common.rs | 6 ++++++ 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 641fdca06..57ed72502 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3009,7 +3009,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "gateway-ereport-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service#57ffd1c24f3ad1919fb4a605d5a501f2c5deb54c" +source = "git+https://github.com/oxidecomputer/management-gateway-service#831d4be4d3a851853ee2c62451f63f2fcfb4a30b" dependencies = [ "zerocopy 0.8.26", ] @@ -3017,7 +3017,7 @@ dependencies = [ [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service#ef7ce28f349dca6774b931bb169690e908e3eecd" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=ef7ce28f349dca6774b931bb169690e908e3eecd#ef7ce28f349dca6774b931bb169690e908e3eecd" dependencies = [ "bitflags 2.9.4", "hubpack", diff --git a/Cargo.toml b/Cargo.toml index fece03af1..c1025d10e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,7 +146,7 @@ zip = { version = "0.6", default-features = false, features = ["bzip2", "deflate # Oxide forks and repos attest-data = { git = "https://github.com/oxidecomputer/dice-util", default-features = false, version = "0.4.0" } dice-mfg-msgs = { git = "https://github.com/oxidecomputer/dice-util", default-features = false, version = "0.2.1" } -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", default-features = false, features = ["smoltcp"] } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", default-features = false, features = ["smoltcp"], rev = "ef7ce28f349dca6774b931bb169690e908e3eecd" } gateway-ereport-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", default-features = false } gimlet-inspector-protocol = { git = "https://github.com/oxidecomputer/gimlet-inspector-protocol", version = "0.1.0" } hif = { git = "https://github.com/oxidecomputer/hif", default-features = false } diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index 52cbab71d..f56f2e825 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -12,6 +12,7 @@ use core::convert::Infallible; use core::mem::MaybeUninit; use core::ops::Range; +use core::ptr; use drv_lpc55_flash::{BYTES_PER_FLASH_PAGE, BYTES_PER_FLASH_WORD}; use drv_lpc55_update_api::{ Fwid, RawCabooseError, RotBootInfo, RotBootInfoV2, RotComponent, RotPage, @@ -41,6 +42,9 @@ const PAGE_SIZE: u32 = BYTES_PER_FLASH_PAGE as u32; #[link_section = ".bootstate"] static BOOTSTATE: MaybeUninit<[u8; 0x1000]> = MaybeUninit::uninit(); +// The TRANSIENT_OVERRIDE field is always initialized. +// It contains either the Bootleby BootDecisionLog or one of our +// settings/clearings of the transient override preference. #[used] #[link_section = ".transient_override"] static mut TRANSIENT_OVERRIDE: MaybeUninit<[u8; 32]> = MaybeUninit::uninit(); @@ -1478,7 +1482,10 @@ fn set_transient_override(preference: [u8; 32]) { // Calling this function multiple times is ok. // Bootleby is careful to vet contents before acting. unsafe { - TRANSIENT_OVERRIDE.write(preference); + ptr::write_volatile( + ptr::addr_of_mut!(TRANSIENT_OVERRIDE), + MaybeUninit::new(preference), + ); } } diff --git a/drv/update-api/src/lib.rs b/drv/update-api/src/lib.rs index e3a1c9fed..9d659da3a 100644 --- a/drv/update-api/src/lib.rs +++ b/drv/update-api/src/lib.rs @@ -67,8 +67,8 @@ pub enum UpdateError { VersionNotSupported, InvalidPreferredSlotId, - // AlreadyPending, - // NonePending, + AlreadyPending, + NonePending, } impl From for GwUpdateError { @@ -108,8 +108,8 @@ impl From for GwUpdateError { UpdateError::SignatureNotValidated => Self::SignatureNotValidated, UpdateError::VersionNotSupported => Self::VersionNotSupported, UpdateError::InvalidPreferredSlotId => Self::InvalidPreferredSlotId, - // UpdateError::AlreadyPending => Self::AlreadyPending, - // UpdateError::NonePending => Self::NonePending, + UpdateError::AlreadyPending => Self::AlreadyPending, + UpdateError::NonePending => Self::NonePending, } } } diff --git a/task/control-plane-agent/src/mgs_common.rs b/task/control-plane-agent/src/mgs_common.rs index 297152f44..97f8d4953 100644 --- a/task/control-plane-agent/src/mgs_common.rs +++ b/task/control-plane-agent/src/mgs_common.rs @@ -708,6 +708,12 @@ impl MgsCommon { HIGHEST_KNOWN_ROT_VERSION ); + // Force update if the MGS and ROT default mapping is not correct. + static_assertions::const_assert_eq!( + GwRotBootInfo::HIGHEST_KNOWN_VERSION - 1, + SpVersionedRotBootInfo::HIGHEST_KNOWN_VERSION, + ); + // Map the MGS RotBootInfo 1-based versions to RoT 0-based versions. let rot_version = match version { // There is no version -1 in the RoT version number scheme. From 504383480187555bd7ed4d49c0dfc2eec443f97a Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Wed, 3 Sep 2025 15:00:42 -0700 Subject: [PATCH 13/14] Improve access to static mut comms w Bootleby --- Cargo.lock | 39 ----------------------------- app/lpc55xpresso/app.toml | 3 ++- app/oxide-rot-1/app-dev.toml | 3 ++- app/oxide-rot-1/app.toml | 3 ++- app/rot-carrier/app.toml | 3 ++- chips/lpc55/memory.toml | 4 +-- drv/lpc55-update-server/src/main.rs | 35 +++++++++++++++----------- 7 files changed, 31 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 57ed72502..0bcfc15f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5288,22 +5288,6 @@ dependencies = [ "zerocopy-derive 0.8.26", ] -[[package]] -name = "task-caboose-reader" -version = "0.1.0" -dependencies = [ - "build-util", - "cfg-if", - "drv-caboose", - "drv-caboose-pos", - "idol", - "idol-runtime", - "num-traits", - "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", -] - [[package]] name = "task-config" version = "0.1.0" @@ -6009,29 +5993,6 @@ dependencies = [ "userlib", ] -[[package]] -name = "task-spd" -version = "0.1.0" -dependencies = [ - "anyhow", - "build-i2c", - "build-util", - "cfg-if", - "cortex-m", - "drv-cpu-seq-api", - "drv-i2c-api", - "drv-stm32xx-i2c", - "drv-stm32xx-sys-api", - "idol", - "num-traits", - "ringbuf", - "spd", - "stm32h7", - "task-jefe-api", - "task-packrat-api", - "userlib", -] - [[package]] name = "task-template" version = "0.1.0" diff --git a/app/lpc55xpresso/app.toml b/app/lpc55xpresso/app.toml index c983eb2b8..9f6f36043 100644 --- a/app/lpc55xpresso/app.toml +++ b/app/lpc55xpresso/app.toml @@ -49,7 +49,8 @@ name = "lpc55-update-server" priority = 3 stacksize = 8192 start = true -sections = {bootstate = "usbsram", transient_override = "override"} +sections = {bootstate = "usbsram"} +extern-regions = ["transient_override"] uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/app/oxide-rot-1/app-dev.toml b/app/oxide-rot-1/app-dev.toml index 5d5448aef..57d6ca0b0 100644 --- a/app/oxide-rot-1/app-dev.toml +++ b/app/oxide-rot-1/app-dev.toml @@ -54,7 +54,8 @@ name = "lpc55-update-server" priority = 3 stacksize = 8192 start = true -sections = {bootstate = "usbsram", transient_override = "override"} +sections = {bootstate = "usbsram"} +extern-regions = ["transient_override"] uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/app/oxide-rot-1/app.toml b/app/oxide-rot-1/app.toml index 056b170af..f6aa12cb9 100644 --- a/app/oxide-rot-1/app.toml +++ b/app/oxide-rot-1/app.toml @@ -42,7 +42,8 @@ name = "lpc55-update-server" priority = 3 stacksize = 8192 start = true -sections = {bootstate = "usbsram", transient_override = "override"} +sections = {bootstate = "usbsram"} +extern-regions = ["transient_override"] uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/app/rot-carrier/app.toml b/app/rot-carrier/app.toml index bf09cc836..925ac4630 100644 --- a/app/rot-carrier/app.toml +++ b/app/rot-carrier/app.toml @@ -42,7 +42,8 @@ priority = 3 # TODO size this appropriately stacksize = 8192 start = true -sections = {bootstate = "usbsram", transient_override = "override"} +sections = {bootstate = "usbsram"} +extern-regions = ["transient_override"] uses = ["flash_controller", "hash_crypt"] notifications = ["flash-irq", "hashcrypt-irq"] interrupts = {"flash_controller.irq" = "flash-irq", "hash_crypt.irq" = "hashcrypt-irq"} diff --git a/chips/lpc55/memory.toml b/chips/lpc55/memory.toml index 012577741..c6322ef47 100644 --- a/chips/lpc55/memory.toml +++ b/chips/lpc55/memory.toml @@ -93,7 +93,7 @@ write = true execute = false dma = true -[[override]] +[[transient_override]] name = "a" address = 0x2003ffe0 size = 32 @@ -101,7 +101,7 @@ read = true write = true execute = false -[[override]] +[[transient_override]] name = "b" address = 0x2003ffe0 size = 32 diff --git a/drv/lpc55-update-server/src/main.rs b/drv/lpc55-update-server/src/main.rs index f56f2e825..dc2d6899b 100644 --- a/drv/lpc55-update-server/src/main.rs +++ b/drv/lpc55-update-server/src/main.rs @@ -12,7 +12,6 @@ use core::convert::Infallible; use core::mem::MaybeUninit; use core::ops::Range; -use core::ptr; use drv_lpc55_flash::{BYTES_PER_FLASH_PAGE, BYTES_PER_FLASH_WORD}; use drv_lpc55_update_api::{ Fwid, RawCabooseError, RotBootInfo, RotBootInfoV2, RotComponent, RotPage, @@ -1476,25 +1475,33 @@ fn bootstate() -> Result { RotBootStateV2::load_from_addr(addr) } +extern "C" { + // Symbols injected by the linker. + // + // This requires adding `extern-regions = ["transient_override"]` to the task config. + pub static mut __REGION_TRANSIENT_OVERRIDE_BASE: [u32; 0]; +} + fn set_transient_override(preference: [u8; 32]) { - // Safety: Data is consumed by Bootleby on next boot. - // There are no concurrent writers possible. - // Calling this function multiple times is ok. - // Bootleby is careful to vet contents before acting. + // Safety: populated by the linker, getting the address is fine. + // SAFETY: this points to a valid region of RAM that is otherwise unused by Rust, so we can + // write to it. unsafe { - ptr::write_volatile( - ptr::addr_of_mut!(TRANSIENT_OVERRIDE), - MaybeUninit::new(preference), - ); + let override_addr = + core::ptr::addr_of_mut!(__REGION_TRANSIENT_OVERRIDE_BASE) + as *mut [u8; 32]; + core::ptr::write_volatile(override_addr, preference); } } fn get_transient_override() -> [u8; 32] { - // Safety: Data is consumed by Bootleby on next boot. - // There are no concurrent writers possible. - // Bootleby consumes and resets TRANSIENT_OVERRIDE. - // The client may be verifying state set during update flows. - unsafe { TRANSIENT_OVERRIDE.assume_init() } + // SAFETY: populated by the linker, getting the address is fine. + unsafe { + let override_addr = + core::ptr::addr_of_mut!(__REGION_TRANSIENT_OVERRIDE_BASE) + as *mut [u8; 32]; + core::ptr::read_volatile(override_addr) + } } // Preference constants are taken from bootleby:src/lib.rs From c574a2a8d8835bc4d5937487a811ea1bf31b856c Mon Sep 17 00:00:00 2001 From: Ben Stoltz Date: Mon, 22 Sep 2025 12:57:06 -0700 Subject: [PATCH 14/14] rebase --- Cargo.lock | 546 ++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 274 insertions(+), 274 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bcfc15f5..4e903e82a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ "byteorder", "phash", "serde", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -178,8 +178,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1007,8 +1007,8 @@ dependencies = [ "sha3", "tlvc", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1026,8 +1026,8 @@ dependencies = [ "stm32h7", "tlvc", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1069,8 +1069,8 @@ dependencies = [ "serde", "stm32h7", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1105,8 +1105,8 @@ dependencies = [ "task-jefe-api", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1116,8 +1116,8 @@ dependencies = [ "counters", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1131,8 +1131,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1147,8 +1147,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1164,8 +1164,8 @@ dependencies = [ "sha3", "tlvc", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1182,7 +1182,7 @@ dependencies = [ "num-traits", "ringbuf", "userlib", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -1205,8 +1205,8 @@ dependencies = [ "num-traits", "ringbuf", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1216,8 +1216,8 @@ dependencies = [ "drv-fpga-api", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1236,8 +1236,8 @@ dependencies = [ "serde", "stm32h7", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1277,8 +1277,8 @@ dependencies = [ "task-jefe-api", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1301,8 +1301,8 @@ dependencies = [ "task-jefe-api", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1315,8 +1315,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1334,8 +1334,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1346,8 +1346,8 @@ dependencies = [ "counters", "drv-i2c-types", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1365,8 +1365,8 @@ dependencies = [ "smbus-pec", "task-power-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1411,8 +1411,8 @@ dependencies = [ "serde", "static_assertions", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1430,8 +1430,8 @@ dependencies = [ "mutable-statics", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1449,8 +1449,8 @@ dependencies = [ "num-traits", "ringbuf", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1463,8 +1463,8 @@ dependencies = [ "drv-oxide-vpd", "idol", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1487,8 +1487,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1505,8 +1505,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1519,8 +1519,8 @@ dependencies = [ "lpc55-pac", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1537,8 +1537,8 @@ dependencies = [ "rand_chacha", "rand_core", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1558,8 +1558,8 @@ dependencies = [ "lpc55-pac", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1577,8 +1577,8 @@ dependencies = [ "ringbuf", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1612,8 +1612,8 @@ dependencies = [ "static_assertions", "task-jefe-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1646,8 +1646,8 @@ dependencies = [ "serde", "static_assertions", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1662,8 +1662,8 @@ dependencies = [ "num-traits", "task-jefe-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1675,8 +1675,8 @@ dependencies = [ "idol", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1695,8 +1695,8 @@ dependencies = [ "serde", "stage0-handoff", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1714,8 +1714,8 @@ dependencies = [ "nb 1.0.0", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1740,8 +1740,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1753,8 +1753,8 @@ dependencies = [ "idol", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1770,8 +1770,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1798,8 +1798,8 @@ dependencies = [ "ringbuf", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1816,8 +1816,8 @@ dependencies = [ "num-traits", "ringbuf", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1835,8 +1835,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1860,8 +1860,8 @@ dependencies = [ "serde", "serde_json", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1877,8 +1877,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1892,8 +1892,8 @@ dependencies = [ "num-traits", "task-jefe-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1910,8 +1910,8 @@ dependencies = [ "userlib", "vsc7448", "vsc85xx", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1920,8 +1920,8 @@ version = "0.1.0" dependencies = [ "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1931,8 +1931,8 @@ dependencies = [ "drv-onewire", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -1944,8 +1944,8 @@ dependencies = [ "idol", "ringbuf", "tlvc", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2021,8 +2021,8 @@ dependencies = [ "num-traits", "rand_core", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2041,8 +2041,8 @@ dependencies = [ "num-traits", "ringbuf", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2056,8 +2056,8 @@ dependencies = [ "idol", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2081,8 +2081,8 @@ dependencies = [ "userlib", "vsc7448-pac", "vsc85xx", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2105,8 +2105,8 @@ dependencies = [ "serde", "serde_json", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2133,8 +2133,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2162,8 +2162,8 @@ dependencies = [ "ringbuf", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2176,8 +2176,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2198,8 +2198,8 @@ dependencies = [ "ringbuf", "task-config", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2211,8 +2211,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2241,8 +2241,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2273,8 +2273,8 @@ dependencies = [ "tlvc", "unwrap-lite", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2285,8 +2285,8 @@ dependencies = [ "stm32f3", "stm32f4", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2298,8 +2298,8 @@ dependencies = [ "stm32f3", "stm32f4", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2313,8 +2313,8 @@ dependencies = [ "num-traits", "stm32g0", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2361,8 +2361,8 @@ dependencies = [ "stm32h7", "userlib", "vcell", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2380,8 +2380,8 @@ dependencies = [ "num-traits", "stm32h7", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2392,8 +2392,8 @@ dependencies = [ "stm32h7", "userlib", "vcell", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2410,8 +2410,8 @@ dependencies = [ "stm32h7", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2422,8 +2422,8 @@ dependencies = [ "ringbuf", "stm32h7", "vcell", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2438,8 +2438,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2469,7 +2469,7 @@ dependencies = [ "stm32h7", "syn 2.0.98", "userlib", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -2496,8 +2496,8 @@ dependencies = [ "ssmarshal", "static-cell", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2524,8 +2524,8 @@ dependencies = [ "serde", "stage0-handoff", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2546,8 +2546,8 @@ dependencies = [ "stm32g0", "stm32h7", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2565,8 +2565,8 @@ dependencies = [ "stm32g0", "stm32h7", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2610,8 +2610,8 @@ dependencies = [ "stm32h7", "task-jefe-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2628,8 +2628,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2653,8 +2653,8 @@ dependencies = [ "task-sensor-api", "transceiver-messages", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2687,8 +2687,8 @@ dependencies = [ "task-thermal-api", "transceiver-messages", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2705,8 +2705,8 @@ dependencies = [ "ringbuf", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2727,8 +2727,8 @@ dependencies = [ "stm32f4", "task-config", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2740,8 +2740,8 @@ dependencies = [ "idol", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2758,8 +2758,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2775,8 +2775,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -2864,7 +2864,7 @@ name = "endoscope-abi" version = "0.1.0" dependencies = [ "sha3", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -3011,13 +3011,13 @@ name = "gateway-ereport-messages" version = "0.1.0" source = "git+https://github.com/oxidecomputer/management-gateway-service#831d4be4d3a851853ee2c62451f63f2fcfb4a30b" dependencies = [ - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] name = "gateway-messages" version = "0.1.0" -source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=ef7ce28f349dca6774b931bb169690e908e3eecd#ef7ce28f349dca6774b931bb169690e908e3eecd" +source = "git+https://github.com/oxidecomputer/management-gateway-service?rev=50a438ad1e502135036ec8b88b208dd44d7df2c1#50a438ad1e502135036ec8b88b208dd44d7df2c1" dependencies = [ "bitflags 2.9.4", "hubpack", @@ -3029,7 +3029,7 @@ dependencies = [ "strum", "strum_macros", "uuid", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -3271,8 +3271,8 @@ dependencies = [ "serde_repr", "static_assertions", "unwrap-lite", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -3341,8 +3341,8 @@ dependencies = [ "serde", "serde-big-array 0.5.1", "static_assertions", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -3397,7 +3397,7 @@ source = "git+https://github.com/oxidecomputer/idolatry.git#f67fffe2bd917479a476 dependencies = [ "counters", "userlib", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -3521,8 +3521,8 @@ dependencies = [ "ssmarshal", "syn 2.0.98", "unwrap-lite", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -3576,8 +3576,8 @@ dependencies = [ "static_assertions", "unwrap-lite", "vcell", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", "zeroize", ] @@ -3641,8 +3641,8 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -3698,8 +3698,8 @@ dependencies = [ "static_assertions", "toml 0.9.6", "unwrap-lite", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", "zeroize", ] @@ -3731,8 +3731,8 @@ dependencies = [ "task-jefe-api", "tlvc", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -4152,7 +4152,7 @@ version = "0.1.0" dependencies = [ "hubpack", "serde", - "zerocopy 0.8.26", + "zerocopy 0.8.27", ] [[package]] @@ -5199,8 +5199,8 @@ dependencies = [ "serde", "stm32h7", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5284,8 +5284,8 @@ dependencies = [ "static-cell", "unwrap-lite", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5351,8 +5351,8 @@ dependencies = [ "task-vpd-api", "update-buffer", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5369,8 +5369,8 @@ dependencies = [ "serde", "ssmarshal", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5392,8 +5392,8 @@ dependencies = [ "task-packrat-api", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5419,8 +5419,8 @@ dependencies = [ "task-jefe-api", "task-net-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5439,8 +5439,8 @@ dependencies = [ "ringbuf", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5455,8 +5455,8 @@ dependencies = [ "ringbuf", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5539,8 +5539,8 @@ dependencies = [ "static-cell", "test-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5587,8 +5587,8 @@ dependencies = [ "task-sensor-api", "tlvc", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5603,8 +5603,8 @@ dependencies = [ "num-traits", "ssmarshal", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5636,8 +5636,8 @@ dependencies = [ "ssmarshal", "task-jefe-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5655,8 +5655,8 @@ dependencies = [ "serde", "ssmarshal", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5686,8 +5686,8 @@ dependencies = [ "vsc7448", "vsc7448-pac", "vsc85xx", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5734,8 +5734,8 @@ dependencies = [ "userlib", "vsc7448-pac", "vsc85xx", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5757,8 +5757,8 @@ dependencies = [ "smoltcp", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5801,8 +5801,8 @@ dependencies = [ "static_assertions", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5822,8 +5822,8 @@ dependencies = [ "oxide-barcode", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5875,8 +5875,8 @@ dependencies = [ "task-power-api", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5894,8 +5894,8 @@ dependencies = [ "static_assertions", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5918,8 +5918,8 @@ dependencies = [ "serde", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5939,8 +5939,8 @@ dependencies = [ "num-traits", "serde", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5957,8 +5957,8 @@ dependencies = [ "ringbuf", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -5974,8 +5974,8 @@ dependencies = [ "task-net-api", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6027,8 +6027,8 @@ dependencies = [ "task-sensor-api", "task-thermal-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6046,8 +6046,8 @@ dependencies = [ "serde", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6078,8 +6078,8 @@ dependencies = [ "task-net-api", "task-packrat-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6103,8 +6103,8 @@ dependencies = [ "idol", "task-net-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6126,8 +6126,8 @@ dependencies = [ "serde", "task-validate-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6147,8 +6147,8 @@ dependencies = [ "serde", "task-sensor-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6168,8 +6168,8 @@ dependencies = [ "ringbuf", "task-vpd-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6183,8 +6183,8 @@ dependencies = [ "idol-runtime", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6213,8 +6213,8 @@ dependencies = [ "build-util", "num-traits", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6227,8 +6227,8 @@ dependencies = [ "num-traits", "test-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6243,8 +6243,8 @@ dependencies = [ "serde", "ssmarshal", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6259,8 +6259,8 @@ dependencies = [ "ssmarshal", "test-idol-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6276,8 +6276,8 @@ dependencies = [ "ringbuf", "test-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6297,8 +6297,8 @@ dependencies = [ "test-api", "test-idol-api", "userlib", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6638,8 +6638,8 @@ dependencies = [ "ssmarshal", "unwrap-lite", "volatile-const", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -6650,9 +6650,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.16.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" [[package]] name = "vcell" @@ -6728,8 +6728,8 @@ dependencies = [ "userlib", "vsc-err", "vsc7448-pac", - "zerocopy 0.8.26", - "zerocopy-derive 0.8.26", + "zerocopy 0.8.27", + "zerocopy-derive 0.8.27", ] [[package]] @@ -7126,7 +7126,7 @@ dependencies = [ "toml-task", "toml_edit 0.23.5", "walkdir", - "zerocopy 0.8.26", + "zerocopy 0.8.27", "zip", ] @@ -7152,11 +7152,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "zerocopy-derive 0.8.26", + "zerocopy-derive 0.8.27", ] [[package]] @@ -7183,9 +7183,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index c1025d10e..c870978ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -146,7 +146,7 @@ zip = { version = "0.6", default-features = false, features = ["bzip2", "deflate # Oxide forks and repos attest-data = { git = "https://github.com/oxidecomputer/dice-util", default-features = false, version = "0.4.0" } dice-mfg-msgs = { git = "https://github.com/oxidecomputer/dice-util", default-features = false, version = "0.2.1" } -gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", default-features = false, features = ["smoltcp"], rev = "ef7ce28f349dca6774b931bb169690e908e3eecd" } +gateway-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", default-features = false, features = ["smoltcp"], rev = "50a438ad1e502135036ec8b88b208dd44d7df2c1" } gateway-ereport-messages = { git = "https://github.com/oxidecomputer/management-gateway-service", default-features = false } gimlet-inspector-protocol = { git = "https://github.com/oxidecomputer/gimlet-inspector-protocol", version = "0.1.0" } hif = { git = "https://github.com/oxidecomputer/hif", default-features = false }