Skip to content

Commit

Permalink
Support updating the RoT bootloader (stage0)
Browse files Browse the repository at this point in the history
  • Loading branch information
labbott committed Jun 18, 2024
1 parent 754fcd0 commit 7c8fffb
Show file tree
Hide file tree
Showing 23 changed files with 1,060 additions and 82 deletions.
13 changes: 7 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions clients/sled-agent-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,15 @@ impl From<omicron_common::api::internal::nexus::KnownArtifactKind>
use omicron_common::api::internal::nexus::KnownArtifactKind;

match s {
KnownArtifactKind::GimletRotBootloader => {
types::KnownArtifactKind::GimletRotBootloader
}
KnownArtifactKind::PscRotBootloader => {
types::KnownArtifactKind::PscRotBootloader
}
KnownArtifactKind::SwitchRotBootloader => {
types::KnownArtifactKind::SwitchRotBootloader
}
KnownArtifactKind::GimletSp => types::KnownArtifactKind::GimletSp,
KnownArtifactKind::GimletRot => types::KnownArtifactKind::GimletRot,
KnownArtifactKind::Host => types::KnownArtifactKind::Host,
Expand Down
10 changes: 4 additions & 6 deletions common/src/api/internal/nexus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,11 @@ pub struct UpdateArtifactId {
//
// 1. Add it here.
//
// 2. Add the new kind to <repo root>/{nexus-client,sled-agent-client}/lib.rs.
// 2. Add the new kind to <repo root>/clients/src/lib.rs.
// The mapping from `UpdateArtifactKind::*` to `types::UpdateArtifactKind::*`
// must be left as a `todo!()` for now; `types::UpdateArtifactKind` will not
// be updated with the new variant until step 5 below.
//
// 3. Add it to the sql database schema under (CREATE TYPE
// omicron.public.update_artifact_kind).
//
// TODO: After omicron ships this would likely involve a DB migration.
//
// 4. Add the new kind and the mapping to its `update_artifact_kind` to
// <repo root>/nexus/db-model/src/update_artifact.rs
//
Expand Down Expand Up @@ -324,17 +319,20 @@ pub enum KnownArtifactKind {
// Sled Artifacts
GimletSp,
GimletRot,
GimletRotBootloader,
Host,
Trampoline,
ControlPlane,

// PSC Artifacts
PscSp,
PscRot,
PscRotBootloader,

// Switch Artifacts
SwitchSp,
SwitchRot,
SwitchRotBootloader,
}

impl KnownArtifactKind {
Expand Down
17 changes: 17 additions & 0 deletions common/src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ impl ArtifactKind {
/// These artifact kinds are not stored anywhere, but are derived from stored
/// kinds and used as internal identifiers.
impl ArtifactKind {
/// Gimlet root of trust bootloader slot image identifier.
///
/// Derived from [`KnownArtifactKind::GimletRotBootloader`].
pub const GIMLET_ROT_STAGE0: Self =
Self::from_static("gimlet_rot_bootloader");

/// Gimlet root of trust A slot image identifier.
///
/// Derived from [`KnownArtifactKind::GimletRot`].
Expand All @@ -189,6 +195,11 @@ impl ArtifactKind {
pub const GIMLET_ROT_IMAGE_B: Self =
Self::from_static("gimlet_rot_image_b");

/// PSC root of trust stage0 image identifier.
///
/// Derived from [`KnownArtifactKind::PscRotBootloader`].
pub const PSC_ROT_STAGE0: Self = Self::from_static("psc_rot_bootloader");

/// PSC root of trust A slot image identifier.
///
/// Derived from [`KnownArtifactKind::PscRot`].
Expand All @@ -199,6 +210,12 @@ impl ArtifactKind {
/// Derived from [`KnownArtifactKind::PscRot`].
pub const PSC_ROT_IMAGE_B: Self = Self::from_static("psc_rot_image_b");

/// Switch root of trust A slot image identifier.
///
/// Derived from [`KnownArtifactKind::SwitchRotBootloader`].
pub const SWITCH_ROT_STAGE0: Self =
Self::from_static("switch_rot_bootloader");

/// Switch root of trust A slot image identifier.
///
/// Derived from [`KnownArtifactKind::SwitchRot`].
Expand Down
5 changes: 4 additions & 1 deletion openapi/sled-agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -3380,13 +3380,16 @@
"enum": [
"gimlet_sp",
"gimlet_rot",
"gimlet_rot_bootloader",
"host",
"trampoline",
"control_plane",
"psc_sp",
"psc_rot",
"psc_rot_bootloader",
"switch_sp",
"switch_rot"
"switch_rot",
"switch_rot_bootloader"
]
},
"L4PortRange": {
Expand Down
42 changes: 42 additions & 0 deletions openapi/wicketd.json
Original file line number Diff line number Diff line change
Expand Up @@ -3274,6 +3274,10 @@
"StartUpdateOptions": {
"type": "object",
"properties": {
"skip_rot_bootloader_version_check": {
"description": "If true, skip the check on the current RoT version and always update it regardless of whether the update appears to be neeeded.",
"type": "boolean"
},
"skip_rot_version_check": {
"description": "If true, skip the check on the current RoT version and always update it regardless of whether the update appears to be neeeded.",
"type": "boolean"
Expand All @@ -3291,6 +3295,15 @@
}
]
},
"test_simulate_rot_bootloader_result": {
"nullable": true,
"description": "If passed in, simulates a result for the RoT Bootloader update.\n\nThis is used for testing.",
"allOf": [
{
"$ref": "#/components/schemas/UpdateSimulatedResult"
}
]
},
"test_simulate_rot_result": {
"nullable": true,
"description": "If passed in, simulates a result for the RoT update.\n\nThis is used for testing.",
Expand Down Expand Up @@ -3318,6 +3331,7 @@
}
},
"required": [
"skip_rot_bootloader_version_check",
"skip_rot_version_check",
"skip_sp_version_check"
]
Expand Down Expand Up @@ -4734,6 +4748,20 @@
},
"UpdateComponent": {
"oneOf": [
{
"type": "object",
"properties": {
"component": {
"type": "string",
"enum": [
"rot_bootloader"
]
}
},
"required": [
"component"
]
},
{
"type": "object",
"properties": {
Expand Down Expand Up @@ -4822,6 +4850,20 @@
"state"
]
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
"enum": [
"interrogate_rot_bootloader"
]
}
},
"required": [
"id"
]
},
{
"type": "object",
"properties": {
Expand Down
4 changes: 2 additions & 2 deletions oximeter/collector/tests/output/self-stat-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
}
],
"datum_type": "cumulative_u64",
"created": "2024-06-04T20:49:05.675711686Z"
"created": "2024-06-11T21:04:40.129429782Z"
},
"oximeter_collector:failed_collections": {
"timeseries_name": "oximeter_collector:failed_collections",
Expand Down Expand Up @@ -86,6 +86,6 @@
}
],
"datum_type": "cumulative_u64",
"created": "2024-06-04T20:49:05.676050088Z"
"created": "2024-06-11T21:04:40.130239084Z"
}
}
40 changes: 26 additions & 14 deletions sp-sim/src/gimlet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,12 +1275,13 @@ impl SpHandler for Handler {
"port" => ?port,
"component" => ?component,
);
if component == SpComponent::ROT {
Ok(rot_slot_id_to_u16(self.rot_active_slot))
} else {
match component {
SpComponent::ROT => Ok(rot_slot_id_to_u16(self.rot_active_slot)),
// The only active component is stage0
SpComponent::STAGE0 => Ok(0),
// The real SP returns `RequestUnsupportedForComponent` for anything
// other than the RoT, including SP_ITSELF.
Err(SpError::RequestUnsupportedForComponent)
_ => Err(SpError::RequestUnsupportedForComponent),
}
}

Expand All @@ -1300,16 +1301,27 @@ impl SpHandler for Handler {
"slot" => slot,
"persist" => persist,
);
if component == SpComponent::ROT {
self.rot_active_slot = rot_slot_id_from_u16(slot)?;
Ok(())
} else if component == SpComponent::HOST_CPU_BOOT_FLASH {
self.update_state.set_active_host_slot(slot);
Ok(())
} else {
// The real SP returns `RequestUnsupportedForComponent` for anything
// other than the RoT and host boot flash, including SP_ITSELF.
Err(SpError::RequestUnsupportedForComponent)
match component {
SpComponent::ROT => {
self.rot_active_slot = rot_slot_id_from_u16(slot)?;
Ok(())
}
SpComponent::STAGE0 => {
if slot == 1 {
return Ok(());
} else {
Err(SpError::RequestUnsupportedForComponent)
}
}
SpComponent::HOST_CPU_BOOT_FLASH => {
self.update_state.set_active_host_slot(slot);
Ok(())
}
_ => {
// The real SP returns `RequestUnsupportedForComponent` for anything
// other than the RoT and host boot flash, including SP_ITSELF.
Err(SpError::RequestUnsupportedForComponent)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions tools/permslip_staging
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
b973cc9feb20f7bba447e7f5291c4070387fa9992deab81301f67f0a3844cd0c manifest-oxide-rot-1-v1.0.11.toml
ca14a77639db3b71c60234e4edebd01ff31ba5a93a842100a991dbf3ad6e94fb manifest-psc-v1.0.20.toml
af0f6c7d0723db33a2972343cc42e4c2ee2ab8884c49808c9c3d8289c193f97b manifest-sidecar-v1.0.21.toml
e4de7819d5a36ad7f6a396617690359f57b6a60ab3435c202142fcf7e1bc4ec4 manifest-bootleby.toml
9 changes: 6 additions & 3 deletions tufaceous-lib/src/assemble/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ impl<'a> FakeDataAttributes<'a> {
use hubtools::{CabooseBuilder, HubrisArchiveBuilder};

let board = match self.kind {
KnownArtifactKind::GimletRotBootloader
| KnownArtifactKind::PscRotBootloader
| KnownArtifactKind::SwitchRotBootloader => "SimRotStage0",
// non-Hubris artifacts: just make fake data
KnownArtifactKind::Host
| KnownArtifactKind::Trampoline
Expand All @@ -287,11 +290,11 @@ impl<'a> FakeDataAttributes<'a> {
// hubris artifacts: build a fake archive (SimGimletSp and
// SimGimletRot are used by sp-sim)
KnownArtifactKind::GimletSp => "SimGimletSp",
KnownArtifactKind::GimletRot => "SimGimletRot",
KnownArtifactKind::GimletRot => "SimRot",
KnownArtifactKind::PscSp => "fake-psc-sp",
KnownArtifactKind::PscRot => "fake-psc-rot",
KnownArtifactKind::SwitchSp => "fake-sidecar-sp",
KnownArtifactKind::SwitchRot => "fake-sidecar-rot",
KnownArtifactKind::SwitchSp => "SimSidecarSp",
KnownArtifactKind::SwitchRot => "SimRot",
};

let caboose = CabooseBuilder::default()
Expand Down
17 changes: 17 additions & 0 deletions tufaceous/manifests/fake.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,20 @@ version = "1.0.0"
kind = "composite-rot"
archive_a = { kind = "fake", size = "512KiB" }
archive_b = { kind = "fake", size = "512KiB" }

[[artifact.gimlet_rot_bootloader]]
name = "fake-gimlet-rot-bootloader"
version = "1.0.0"
source = { kind = "fake", size = "1MiB" }

[[artifact.psc_rot_bootloader]]
name = "fake-psc-rot-bootloader"
version = "1.0.0"
source = { kind = "fake", size = "1MiB" }

[[artifact.switch_rot_bootloader]]
name = "fake-switch-rot-bootloader"
version = "1.0.0"
source = { kind = "fake", size = "1MiB" }


Loading

0 comments on commit 7c8fffb

Please sign in to comment.