diff --git a/chip/g/system.c b/chip/g/system.c index 323c258ea8..15640f46e3 100644 --- a/chip/g/system.c +++ b/chip/g/system.c @@ -13,6 +13,7 @@ #include "signed_header.h" #include "system.h" #include "task.h" +#include "upgrade_fw.h" #include "version.h" static void check_reset_cause(void) @@ -86,6 +87,14 @@ void system_pre_init(void) system_init_board_properties(); #endif } +#ifdef BOARD_CR50 +void clear_retry_counter(void) +{ + GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 1); + GREG32(PMU, LONG_LIFE_SCRATCH0) = 0; + GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 0); +} +#endif void system_reset(int flags) { @@ -96,6 +105,15 @@ void system_reset(int flags) interrupt_disable(); if (flags & SYSTEM_RESET_HARD) { +#if defined(BOARD_CR50) && !defined(SECTION_IS_RO) + /* + * If the system was updated during this boot clear the retry + * counter. + */ + if (fw_upgraded()) + clear_retry_counter(); +#endif + /* Reset the full microcontroller */ GR_PMU_GLOBAL_RESET = GC_PMU_GLOBAL_RESET_KEY; } else { @@ -333,9 +351,7 @@ int system_process_retry_counter(void) struct SignedHeader *me, *other; retry_counter = GREG32(PMU, LONG_LIFE_SCRATCH0); - GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 1); - GREG32(PMU, LONG_LIFE_SCRATCH0) = 0; - GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG0, 0); + clear_retry_counter(); ccprintf("%s:retry counter %d\n", __func__, retry_counter); diff --git a/chip/g/upgrade_fw.c b/chip/g/upgrade_fw.c index a419e3a229..b1da99d7a7 100644 --- a/chip/g/upgrade_fw.c +++ b/chip/g/upgrade_fw.c @@ -32,6 +32,8 @@ struct { uint32_t rw_top_offset; } valid_sections; +static int upgrade_done; + /* Pick sections where updates can go to based on current code addresses. */ static void set_valid_sections(void) { @@ -263,3 +265,13 @@ void fw_upgrade_command_handler(void *body, *error_code = UPGRADE_SUCCESS; } + +void fw_upgrade_complete(void) +{ + upgrade_done = 1; +} + +int fw_upgraded(void) +{ + return upgrade_done; +} diff --git a/chip/g/upgrade_fw.h b/chip/g/upgrade_fw.h index 8eca3761b6..cbddd5bdb8 100644 --- a/chip/g/upgrade_fw.h +++ b/chip/g/upgrade_fw.h @@ -115,6 +115,11 @@ void fw_upgrade_command_handler(void *body, size_t cmd_size, size_t *response_size); +/* Returns 1 if an upgrade was done during this run 0 if there was no upgrade */ +int fw_upgraded(void); + +/* Used to tell fw upgrade the update ran successfully and is finished */ +void fw_upgrade_complete(void); /* Various upgrade command return values. */ enum return_value { diff --git a/chip/g/usb_upgrade.c b/chip/g/usb_upgrade.c index 5c213668d1..7f58f57fc8 100644 --- a/chip/g/usb_upgrade.c +++ b/chip/g/usb_upgrade.c @@ -206,6 +206,7 @@ static void upgrade_out_handler(struct consumer const *consumer, size_t count) if (command == UPGRADE_DONE) { CPRINTS("FW update: done"); + fw_upgrade_complete(); resp_value = 0; QUEUE_ADD_UNITS(&upgrade_to_usb, &resp_value, 1);