summaryrefslogtreecommitdiff
path: root/extra/usb_updater/gsctool.c
diff options
context:
space:
mode:
Diffstat (limited to 'extra/usb_updater/gsctool.c')
-rw-r--r--extra/usb_updater/gsctool.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c
index 2f10998682..493cd4da67 100644
--- a/extra/usb_updater/gsctool.c
+++ b/extra/usb_updater/gsctool.c
@@ -272,6 +272,8 @@ static const struct option_container cmd_line_options[] = {
"Get the system boot mode"},
{{"help", no_argument, NULL, 'h'},
"Show this message"},
+ {{"erase_ap_ro_hash", no_argument, NULL, 'H'},
+ "Erase AP RO hash (possible only if Board ID is not set)"},
{{"ccd_info", no_argument, NULL, 'I'},
"Get information about CCD state"},
{{"board_id", optional_argument, NULL, 'i'},
@@ -1334,6 +1336,49 @@ static void invalidate_inactive_rw(struct transfer_descriptor *td)
exit(update_error);
}
+static void process_erase_ap_ro_hash(struct transfer_descriptor *td)
+{
+ /* Try erasing AP RO hash, could fail if board ID is programmed. */
+ uint32_t rv;
+ uint8_t response;
+ size_t response_size;
+ char error_details[30];
+
+ response_size = sizeof(response);
+ rv = send_vendor_command(td, VENDOR_CC_SEED_AP_RO_CHECK,
+ NULL, 0, &response, &response_size);
+ if (!rv) {
+ printf("AP RO hash erased\n");
+ exit(0);
+ }
+
+ if (response_size == sizeof(response)) {
+ switch (response) {
+ case ARCVE_FLASH_ERASE_FAILED:
+ snprintf(error_details, sizeof(error_details),
+ "erase failure");
+ break;
+ case ARCVE_BID_PROGRAMMED:
+ snprintf(error_details, sizeof(error_details),
+ "BID already programmed");
+ break;
+ default:
+ snprintf(error_details, sizeof(error_details),
+ "Unexpected error rc %d, response %d",
+ rv, response);
+ break;
+ }
+ } else {
+ snprintf(error_details, sizeof(error_details),
+ "misconfigured response, rc=%d, size %zd",
+ rv, response_size);
+ }
+
+ fprintf(stderr, "Error: %s\n", error_details);
+
+ exit(update_error);
+}
+
static struct signed_header_version ver19 = {
.epoch = 0,
.major = 0,
@@ -2731,6 +2776,7 @@ int main(int argc, char *argv[])
uint8_t sn_bits_arg[SN_BITS_SIZE];
int sn_inc_rma = 0;
uint8_t sn_inc_rma_arg;
+ int erase_ap_ro_hash = 0;
/*
* All options which result in setting a Boolean flag to True, along
@@ -2742,6 +2788,7 @@ int main(int argc, char *argv[])
{ 'c', &corrupt_inactive_rw },
{ 'f', &show_fw_ver },
{ 'g', &get_boot_mode},
+ { 'H', &erase_ap_ro_hash},
{ 'I', &ccd_info },
{ 'k', &ccd_lock },
{ 'o', &ccd_open },
@@ -2941,6 +2988,7 @@ int main(int argc, char *argv[])
!get_flog &&
!get_endorsement_seed &&
!factory_mode &&
+ !erase_ap_ro_hash &&
!password &&
!rma &&
!show_fw_ver &&
@@ -2978,11 +3026,12 @@ int main(int argc, char *argv[])
if (((bid_action != bid_none) + !!rma + !!password + !!ccd_open +
!!ccd_unlock + !!ccd_lock + !!ccd_info + !!get_flog +
!!get_boot_mode + !!openbox_desc_file + !!factory_mode +
- (wp != WP_NONE) + !!get_endorsement_seed) > 1) {
+ (wp != WP_NONE) + !!get_endorsement_seed +
+ !!erase_ap_ro_hash) > 1) {
fprintf(stderr,
"ERROR: options"
- "-e, -F, -g, -I, -i, -k, -L, -O, -o, -P, -r, -U and -w "
- "are mutually exclusive\n");
+ "-e, -F, -g, -H, -I, -i, -k, -L, -O, -o, -P, -r, -U"
+ " and -w are mutually exclusive\n");
exit(update_error);
}
@@ -3050,6 +3099,9 @@ int main(int argc, char *argv[])
if (get_flog)
process_get_flog(&td, prev_log_entry);
+ if (erase_ap_ro_hash)
+ process_erase_ap_ro_hash(&td);
+
if (data || show_fw_ver) {
setup_connection(&td);