Skip to content

Commit

Permalink
[opentitantool] Improve rescue CLI
Browse files Browse the repository at this point in the history
1. Enhance the boot-svc commands to retrieve and display the response.
2. Emit any boot-svc response `status` as hex.

Signed-off-by: Chris Frantz <cfrantz@google.com>
(cherry picked from commit 4c593f5)
(cherry picked from commit fea62b3)
  • Loading branch information
cfrantz committed Dec 19, 2024
1 parent 1518dc8 commit 8e82dd1
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 15 deletions.
2 changes: 1 addition & 1 deletion sw/device/silicon_creator/rom_ext/e2e/rescue/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ opentitan_test(
--exec="fpga load-bitstream {bitstream}"
--exec="bootstrap --clear-uart=true {firmware}"
# Set next slot via the rescue protocol
--exec="rescue boot-svc set-next-bl0-slot --next=SlotB"
--exec="rescue boot-svc set-next-bl0-slot --next=SlotB --get-response=false"
# Check for firmware execution in slot B
--exec="console --non-interactive --exit-success='bl0_slot = __BB\r\n' --exit-failure='{exit_failure}'"
# Reset and observe return to slot A.
Expand Down
4 changes: 4 additions & 0 deletions sw/host/opentitanlib/src/chip/boot_svc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ pub struct MinBl0SecVerResponse {
/// The current minimum BL0 version.
pub ver: u32,
/// The status response to the request.
#[annotate(format = hex)]
pub status: u32,
}

Expand All @@ -102,6 +103,7 @@ pub struct NextBl0SlotRequest {
#[derive(Debug, Default, Serialize, Annotate)]
pub struct NextBl0SlotResponse {
/// The status response to the request.
#[annotate(format = hex)]
pub status: u32,
/// The current primary slot.
pub primary_bl0_slot: BootSlot,
Expand Down Expand Up @@ -129,6 +131,7 @@ pub struct OwnershipUnlockRequest {
#[derive(Debug, Default, Serialize, Annotate)]
pub struct OwnershipUnlockResponse {
/// The status response to the request.
#[annotate(format = hex)]
pub status: u32,
}

Expand All @@ -154,6 +157,7 @@ pub struct OwnershipActivateRequest {
#[derive(Debug, Default, Serialize, Annotate)]
pub struct OwnershipActivateResponse {
/// The status response to the request.
#[annotate(format = hex)]
pub status: u32,
}

Expand Down
6 changes: 4 additions & 2 deletions sw/host/opentitanlib/src/rescue/serial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ impl RescueSerial {
}
}

pub fn enter(&self, transport: &TransportWrapper) -> Result<()> {
pub fn enter(&self, transport: &TransportWrapper, reset_target: bool) -> Result<()> {
log::info!("Setting serial break to trigger rescue mode.");
self.uart.set_break(true)?;
transport.reset_target(self.reset_delay, /*clear_uart*=*/ true)?;
if reset_target {
transport.reset_target(self.reset_delay, /*clear_uart=*/ true)?;
}
UartConsole::wait_for(&*self.uart, r"rescue:.*\r\n", self.enter_delay)?;
log::info!("Rescue triggered. clearing serial break.");
self.uart.set_break(false)?;
Expand Down
115 changes: 103 additions & 12 deletions sw/host/opentitantool/src/command/rescue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ pub struct Firmware {
help = "Wait after upload (no automatic reboot)"
)]
wait: bool,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(value_name = "FILE")]
filename: PathBuf,
}
Expand Down Expand Up @@ -77,7 +84,7 @@ impl CommandDispatch for Firmware {
let uart = self.params.create(transport)?;
let mut prev_baudrate = 0u32;
let rescue = RescueSerial::new(Rc::clone(&uart));
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
if let Some(rate) = self.rate {
prev_baudrate = uart.get_baudrate()?;
rescue.set_baud(rate)?;
Expand All @@ -101,6 +108,13 @@ impl CommandDispatch for Firmware {
pub struct GetBootLog {
#[command(flatten)]
params: UartParams,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(long, short, default_value = "false")]
raw: bool,
}
Expand All @@ -113,7 +127,7 @@ impl CommandDispatch for GetBootLog {
) -> Result<Option<Box<dyn Annotate>>> {
let uart = self.params.create(transport)?;
let rescue = RescueSerial::new(uart);
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
if self.raw {
let data = rescue.get_boot_log_raw()?;
Ok(Some(Box::new(RawBytes(data))))
Expand All @@ -128,6 +142,13 @@ impl CommandDispatch for GetBootLog {
pub struct GetBootSvc {
#[command(flatten)]
params: UartParams,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(long, short, default_value = "false")]
raw: bool,
}
Expand All @@ -140,7 +161,7 @@ impl CommandDispatch for GetBootSvc {
) -> Result<Option<Box<dyn Annotate>>> {
let uart = self.params.create(transport)?;
let rescue = RescueSerial::new(uart);
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
if self.raw {
let data = rescue.get_boot_svc_raw()?;
Ok(Some(Box::new(RawBytes(data))))
Expand Down Expand Up @@ -169,6 +190,20 @@ pub struct SetNextBl0Slot {
help = "Set the one-time next boot slot"
)]
next: BootSlot,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Get the response from the target"
)]
get_response: bool,
}

impl CommandDispatch for SetNextBl0Slot {
Expand All @@ -179,16 +214,37 @@ impl CommandDispatch for SetNextBl0Slot {
) -> Result<Option<Box<dyn Annotate>>> {
let uart = self.params.create(transport)?;
let rescue = RescueSerial::new(uart);
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
rescue.set_next_bl0_slot(self.primary, self.next)?;
Ok(None)
if self.get_response {
rescue.enter(transport, false)?;
let response = rescue.get_boot_svc()?;
rescue.reboot()?;
Ok(Some(Box::new(response)))
} else {
Ok(None)
}
}
}

#[derive(Debug, Args)]
pub struct OwnershipUnlock {
#[command(flatten)]
params: UartParams,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Get the response from the target"
)]
get_response: bool,
#[command(flatten)]
unlock: OwnershipUnlockParams,
#[arg(short, long, help = "A file containing a binary unlock request")]
Expand All @@ -207,16 +263,37 @@ impl CommandDispatch for OwnershipUnlock {

let uart = self.params.create(transport)?;
let rescue = RescueSerial::new(uart);
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
rescue.ownership_unlock(unlock)?;
Ok(None)
if self.get_response {
rescue.enter(transport, false)?;
let response = rescue.get_boot_svc()?;
rescue.reboot()?;
Ok(Some(Box::new(response)))
} else {
Ok(None)
}
}
}

#[derive(Debug, Args)]
pub struct OwnershipActivate {
#[command(flatten)]
params: UartParams,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Get the response from the target"
)]
get_response: bool,
#[command(flatten)]
activate: OwnershipActivateParams,
#[arg(short, long, help = "A file containing a binary activate request")]
Expand All @@ -235,16 +312,30 @@ impl CommandDispatch for OwnershipActivate {

let uart = self.params.create(transport)?;
let rescue = RescueSerial::new(uart);
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
rescue.ownership_activate(activate)?;
Ok(None)
if self.get_response {
rescue.enter(transport, false)?;
let response = rescue.get_boot_svc()?;
rescue.reboot()?;
Ok(Some(Box::new(response)))
} else {
Ok(None)
}
}
}

#[derive(Debug, Args)]
pub struct SetOwnerConfig {
#[command(flatten)]
params: UartParams,
#[arg(
long,
default_value_t = true,
action = clap::ArgAction::Set,
help = "Reset the target to enter rescue mode"
)]
reset_target: bool,
#[arg(help = "A signed owner configuration block")]
input: PathBuf,
}
Expand All @@ -258,14 +349,14 @@ impl CommandDispatch for SetOwnerConfig {
let data = std::fs::read(&self.input)?;
let uart = self.params.create(transport)?;
let rescue = RescueSerial::new(uart);
rescue.enter(transport)?;
rescue.enter(transport, self.reset_target)?;
rescue.set_owner_config(&data)?;
Ok(None)
}
}

#[derive(Debug, Subcommand, CommandDispatch)]
pub enum BootSvc {
pub enum BootSvcCommand {
Get(GetBootSvc),
SetNextBl0Slot(SetNextBl0Slot),
OwnershipUnlock(OwnershipUnlock),
Expand All @@ -275,7 +366,7 @@ pub enum BootSvc {
#[derive(Debug, Subcommand, CommandDispatch)]
pub enum RescueCommand {
#[command(subcommand)]
BootSvc(BootSvc),
BootSvc(BootSvcCommand),
GetBootLog(GetBootLog),
Firmware(Firmware),
SetOwnerConfig(SetOwnerConfig),
Expand Down

0 comments on commit 8e82dd1

Please sign in to comment.