Skip to content

Commit 4f38f55

Browse files
authored
Use measurement token in humility reset (#580)
This is a little tricky, because we need a `ProbeCore` and Hubris archive to do the reset-with-handoff logic. If we don't have a valid archive, then we fall back to the previous behavior of a plain reset - unless the user specifically demands that we use the handoff token, in which case we return an error.
1 parent 73ccbf2 commit 4f38f55

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

cmd/reset/src/lib.rs

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,67 @@ struct ResetArgs {
2121
/// Reset and halt instead of continuing
2222
#[clap(long, conflicts_with_all = &["soft-reset"])]
2323
halt: bool,
24+
/// Use measurement token handoff (usually decided automatically)
25+
#[clap(long, conflicts_with_all = &["soft-reset", "halt"])]
26+
use_token: Option<bool>,
2427
}
2528

2629
fn reset(context: &mut ExecutionContext) -> Result<()> {
2730
let Subcommand::Other(subargs) = context.cli.cmd.as_ref().unwrap();
2831
let subargs = ResetArgs::try_parse_from(subargs)?;
2932

30-
let hubris = context.archive.as_mut().unwrap();
33+
// `context.archive` is always `Some(..)` even if we have not specified
34+
// anything on the command line or through environment flags. However, if no
35+
// archive is specified, then the actual data in the archive is default
36+
// constructed (??!).
37+
let chip = context.archive.as_mut().unwrap().chip();
3138

3239
let probe = match &context.cli.probe {
3340
Some(p) => p,
3441
None => "auto",
3542
};
3643

37-
let mut c = if subargs.soft_reset || subargs.halt {
38-
let chip = hubris.chip().ok_or_else(|| {
44+
enum Behavior<'a> {
45+
Halt,
46+
ResetWithHandoff(&'a humility::hubris::HubrisArchive),
47+
Reset,
48+
}
49+
50+
let behavior = if subargs.halt {
51+
Behavior::Halt
52+
} else {
53+
match subargs.use_token {
54+
None => {
55+
// Detect bogus archives by looking at the chip member
56+
if let Some(archive) = &context.archive
57+
&& chip.is_some()
58+
{
59+
Behavior::ResetWithHandoff(archive)
60+
} else {
61+
Behavior::Reset
62+
}
63+
}
64+
Some(false) => Behavior::Reset,
65+
Some(true) => {
66+
if let Some(archive) = &context.archive
67+
&& chip.is_some()
68+
{
69+
Behavior::ResetWithHandoff(archive)
70+
} else {
71+
anyhow::bail!(
72+
"Need a Hubris archive to use measurement token handoff"
73+
)
74+
}
75+
}
76+
}
77+
};
78+
79+
let mut c = if subargs.soft_reset
80+
|| matches!(behavior, Behavior::Halt | Behavior::ResetWithHandoff(..))
81+
{
82+
let chip = chip.ok_or_else(|| {
3983
anyhow::anyhow!(
40-
"Need a chip to do a soft reset or halt after reset"
84+
"Need a chip to do a soft reset, halt after reset, or handoff"
4185
)
4286
})?;
4387
humility_probes_core::attach_to_chip(
@@ -49,10 +93,10 @@ fn reset(context: &mut ExecutionContext) -> Result<()> {
4993
humility_probes_core::attach_to_probe(probe, context.cli.speed)?
5094
};
5195

52-
let r = if subargs.halt {
53-
c.reset_and_halt(std::time::Duration::from_secs(2))
54-
} else {
55-
c.reset()
96+
let r = match behavior {
97+
Behavior::Halt => c.reset_and_halt(std::time::Duration::from_secs(2)),
98+
Behavior::ResetWithHandoff(archive) => c.reset_with_handoff(archive),
99+
Behavior::Reset => c.reset(),
56100
};
57101

58102
if r.is_err() {

0 commit comments

Comments
 (0)