diff options
author | Eric Callahan <arksine.code@gmail.com> | 2022-05-31 06:51:25 -0400 |
---|---|---|
committer | KevinOConnor <kevin@koconnor.net> | 2022-06-03 14:51:01 -0400 |
commit | 8b1e3c3fb25e3d3fbec49158ba9dba9b07c9be00 (patch) | |
tree | 7989188853a7272a43ccb2176c3921b95d8d70bd | |
parent | 04eb72dcd5c0a1a3f223cfb47cb9dcf897ff0747 (diff) | |
download | kutter-8b1e3c3fb25e3d3fbec49158ba9dba9b07c9be00.tar.gz kutter-8b1e3c3fb25e3d3fbec49158ba9dba9b07c9be00.tar.xz kutter-8b1e3c3fb25e3d3fbec49158ba9dba9b07c9be00.zip |
armcm_reset: support canboot detection
When CanBoot is detected set its bypass signature when a
reset is requested.
Add a "try_request_canboot()" method that may be called
from from USB and Canbus bootloader requests.
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
-rw-r--r-- | src/generic/armcm_reset.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/generic/armcm_reset.c b/src/generic/armcm_reset.c index 19c2096d..b7aea955 100644 --- a/src/generic/armcm_reset.c +++ b/src/generic/armcm_reset.c @@ -6,10 +6,42 @@ #include "board/internal.h" // NVIC_SystemReset #include "command.h" // DECL_COMMAND_FLAGS +#include "autoconf.h" // CONFIG_FLASH_START +#include "irq.h" // irq_disable + +#define CANBOOT_SIGNATURE 0x21746f6f426e6143 +#define CANBOOT_REQUEST 0x5984E3FA6CA1589B +#define CANBOOT_BYPASS 0x7b06ec45a9a8243d + +static void +canboot_reset(uint64_t req_signature) +{ + if (!(CONFIG_FLASH_START & 0x00FFFFFF)) + // No bootloader + return; + uint32_t *bl_vectors = (uint32_t *)(CONFIG_FLASH_START & 0xFF000000); + uint64_t *boot_sig = (uint64_t *)(bl_vectors[1] - 9); + uint64_t *req_sig = (uint64_t *)bl_vectors[0]; + if (boot_sig == (void *)ALIGN((size_t)boot_sig, 8) && + *boot_sig == CANBOOT_SIGNATURE && + req_sig == (void *)ALIGN((size_t)req_sig, 8)) + { + irq_disable(); + *req_sig = req_signature; + NVIC_SystemReset(); + } +} + +void +try_request_canboot(void) +{ + canboot_reset(CANBOOT_REQUEST); +} void command_reset(uint32_t *args) { + canboot_reset(CANBOOT_BYPASS); NVIC_SystemReset(); } DECL_COMMAND_FLAGS(command_reset, HF_IN_SHUTDOWN, "reset"); |