Skip to content
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e757dd7
Add ereports for host panic/boot failure.
jamesmunns May 8, 2026
d77c642
Also increase flash size for gimlet base
jamesmunns May 8, 2026
6b3c1fb
Underscore not-yet-used field
jamesmunns May 8, 2026
ff34068
Apply suggestions from code review
jamesmunns May 14, 2026
f8a3945
Address review comments
jamesmunns May 14, 2026
5e68f88
Add flash index field as requested
jamesmunns May 14, 2026
20879b0
Working on packrat
jamesmunns May 15, 2026
bc62fe9
Implement bootfail APIs in packrat
jamesmunns May 18, 2026
3e2b655
Plumb panic handling from the host-sp-comms side
jamesmunns May 18, 2026
42e0965
Implement suggestions from @hawkw
jamesmunns May 19, 2026
b2deca6
Add missing argument
jamesmunns May 19, 2026
1f75e17
Plumb MGS requests to packrat IPC calls
jamesmunns May 19, 2026
bf691dd
Merge remote-tracking branch 'origin/master' into james/packrattin
jamesmunns Jun 26, 2026
c074d30
Ensure this builds for more targets
jamesmunns Jun 26, 2026
13a2641
More stack for packrat on grapefruit
jamesmunns Jun 26, 2026
c4ba201
Undo silly test limit
jamesmunns Jun 26, 2026
0032879
Fix clippy warnings
jamesmunns Jun 26, 2026
56e7860
Update for index -> seqno changes
jamesmunns Jul 2, 2026
e83762f
Merge remote-tracking branch 'origin/master' into james/packrattin
jamesmunns Jul 2, 2026
0af5cda
Simplify packrat API using hubpack
jamesmunns Jul 2, 2026
7b31722
Fix missing `Option`
jamesmunns Jul 2, 2026
8766d7c
Remove stale cast
jamesmunns Jul 2, 2026
325c707
More serde, more flash
jamesmunns Jul 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ apob = { git = "https://github.com/oxidecomputer/apob", default-features = false
# for the migration.
attest-data = { git = "https://github.com/oxidecomputer/dice-util", default-features = false, version = "0.4.0", rev = "a0811d06c75c757a6e12c91ed6ea81fde137ba43" }
dice-mfg-msgs = { git = "https://github.com/oxidecomputer/dice-util", default-features = false, version = "0.2.1", rev = "a0811d06c75c757a6e12c91ed6ea81fde137ba43" }
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"], branch = "james/host-fails" }
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 }
Expand Down
4 changes: 2 additions & 2 deletions app/cosmo/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ notifications = ["i2c1-irq", "i2c2-irq", "i2c3-irq", "i2c4-irq"]
[tasks.packrat]
name = "task-packrat"
priority = 1
stacksize = 1400
stacksize = 1600
start = true
task-slots = ["jefe"]
features = ["cosmo", "ereport"]
Expand Down Expand Up @@ -258,7 +258,7 @@ features = ["stm32h753", "usart6", "baud_rate_3M", "hardware_flow_control", "vla
uses = ["usart6", "dbgmcu"]
interrupts = {"usart6.irq" = "usart-irq"}
priority = 9
max-sizes = {flash = 70000, ram = 65536}
max-sizes = {flash = 74000, ram = 65536}
stacksize = 5400
start = true
task-slots = ["sys", { cpu_seq = "cosmo_seq" }, "hf", "control_plane_agent", "net", "packrat", "i2c_driver", { spi_driver = "spi2_driver" }, "sprot", "auxflash"]
Expand Down
2 changes: 1 addition & 1 deletion app/gimlet/base.toml
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ features = ["stm32h753", "uart7", "baud_rate_3M", "hardware_flow_control", "vlan
uses = ["uart7", "dbgmcu"]
interrupts = {"uart7.irq" = "usart-irq"}
priority = 8
max-sizes = {flash = 70000, ram = 65536}
max-sizes = {flash = 74000, ram = 65536}
stacksize = 5376
start = true
task-slots = ["sys", { cpu_seq = "gimlet_seq" }, "hf", "control_plane_agent", "net", "packrat", "i2c_driver", { spi_driver = "spi2_driver" }, "sprot"]
Expand Down
79 changes: 79 additions & 0 deletions idl/packrat.idol
Original file line number Diff line number Diff line change
Expand Up @@ -144,5 +144,84 @@ Interface(
),
idempotent: true,
),
"write_host_bootfail": (
doc: "Write a host's boot failure message and return the index of this failure",
args: {
"reason": "u8",
},
leases: {
"data": (type: "[u8]", read: true),
},
reply: Result(
ok: "HostInfoWriteOutput",
err: ServerDeath,
),
),
"read_first_host_bootfail_fragment": (
doc: "Read a portion of the host's boot failure message",
args: {
},
leases: {
"data": (type: "[u8]", write: true),
},
reply: Result(
ok: "HostBootfailReadOutput",
err: CLike("HostInfoReadError"),
),
idempotent: true,
),
"read_host_bootfail_fragment": (
doc: "Read a portion of the host's boot failure message",
args: {
"request": "HostInfoRequest",
},
leases: {
"data": (type: "[u8]", write: true),
},
reply: Result(
ok: "HostBootfailReadOutput",
err: CLike("HostInfoReadError"),
),
idempotent: true,
),
"write_host_panic": (
doc: "Write a host's panic message and return the index of this panic",
args: {
},
leases: {
"data": (type: "[u8]", read: true),
},
reply: Result(
ok: "HostInfoWriteOutput",
err: ServerDeath,
),
),
"read_first_host_panic_fragment": (
doc: "Read a portion of the host's panic message",
args: {
},
leases: {
"data": (type: "[u8]", write: true),
},
reply: Result(
ok: "HostPanicReadOutput",
err: CLike("HostInfoReadError"),
),
idempotent: true,
),
"read_host_panic_fragment": (
doc: "Read a portion of the host's panic message",
args: {
"request": "HostInfoRequest",
},
leases: {
"data": (type: "[u8]", write: true),
},
reply: Result(
ok: "HostPanicReadOutput",
err: CLike("HostInfoReadError"),
),
idempotent: true,
),
},
)
98 changes: 97 additions & 1 deletion task/control-plane-agent/src/mgs_compute_sled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use gateway_messages::sp_impl::{
use gateway_messages::{
ApobComponentAction, ComponentAction, ComponentActionResponse,
ComponentDetails, ComponentUpdatePrepare, DiscoverResponse, DumpSegment,
DumpTask, GpioToggleCount, Header, IgnitionCommand, IgnitionState,
DumpTask, GpioToggleCount, Header, HostBootfailPayloadData,
HostInfoRequest, HostPanicPayloadData, IgnitionCommand, IgnitionState,
LastPostCode, Message, MessageKind, MgsError, MgsRequest, MgsResponse,
PostCode, PowerState, PowerStateTransition, RotBootInfo, RotRequest,
RotResponse, SERIAL_CONSOLE_IDLE_TIMEOUT, SensorRequest, SensorResponse,
Expand Down Expand Up @@ -1259,6 +1260,101 @@ impl SpHandler for MgsHandler {
}));
self.host_flash_update.get_hash(slot)
}

fn get_host_panic_payload(
&mut self,
request: Option<HostInfoRequest>,
len: u32,
trailing_tx_buf: &mut [u8],
) -> Result<HostPanicPayloadData, SpError> {
let max_len_usize = len as usize;
let max_len_usize = max_len_usize.min(trailing_tx_buf.len());
let dest = &mut trailing_tx_buf[..max_len_usize];

let res = if let Some(req) = request {
self.common.packrat().read_host_panic_fragment(
task_packrat_api::HostInfoRequest {
offset: req.offset,
index: req.index,
},
dest,
)
} else {
self.common.packrat().read_first_host_panic_fragment(dest)
};
Comment thread
jamesmunns marked this conversation as resolved.
Outdated

let info = res.map_err(|e| {
SpError::HostPanic(match e {
task_packrat_api::HostInfoReadError::NoHostInfo => {
gateway_messages::HostPanicError::NoHostInfo
}
task_packrat_api::HostInfoReadError::InvalidOffset => {
gateway_messages::HostPanicError::InvalidOffset
}
task_packrat_api::HostInfoReadError::InvalidIndex => {
gateway_messages::HostPanicError::InvalidIndex
}
task_packrat_api::HostInfoReadError::ServerRestarted => {
gateway_messages::HostPanicError::ServerRestarted
}
})
})?;

Ok(HostPanicPayloadData {
index: info.index,
len: info.read,
total_len: info.total_len as u32,
})
}

fn get_host_bootfail_payload(
&mut self,
request: Option<HostInfoRequest>,
len: u32,
trailing_tx_buf: &mut [u8],
) -> Result<HostBootfailPayloadData, SpError> {
let max_len_usize = len as usize;
let max_len_usize = max_len_usize.min(trailing_tx_buf.len());
let dest = &mut trailing_tx_buf[..max_len_usize];

let res = if let Some(req) = request {
self.common.packrat().read_host_bootfail_fragment(
task_packrat_api::HostInfoRequest {
offset: req.offset,
index: req.index,
},
dest,
)
} else {
self.common
.packrat()
.read_first_host_bootfail_fragment(dest)
};

let info = res.map_err(|e| {
SpError::HostBootfail(match e {
task_packrat_api::HostInfoReadError::NoHostInfo => {
gateway_messages::HostBootfailError::NoHostInfo
}
task_packrat_api::HostInfoReadError::InvalidOffset => {
gateway_messages::HostBootfailError::InvalidOffset
}
task_packrat_api::HostInfoReadError::InvalidIndex => {
gateway_messages::HostBootfailError::InvalidIndex
}
task_packrat_api::HostInfoReadError::ServerRestarted => {
gateway_messages::HostBootfailError::ServerRestarted
}
})
})?;

Ok(HostBootfailPayloadData {
index: info.index,
len: info.read,
total_len: info.total_len as u32,
reason: info.reason,
})
}
}

struct UsartHandler {
Expand Down
4 changes: 4 additions & 0 deletions task/host-sp-comms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ task-sensor-api = { path = "../../task/sensor-api", optional = true, features =
ksz8463 = { path = "../../drv/ksz8463", optional = true }
drv-sprot-api = { path = "../../drv/sprot-api"}

# ereports deps
ereports = { path = "../../lib/ereports", features = ["ereporter-macro"] }
microcbor = { path = "../../lib/microcbor" }

[build-dependencies]
build-util.path = "../../build/util"
build-i2c = { path = "../../build/i2c", optional = true }
Expand Down
Loading
Loading