From 720edaf8918fab8ae6e3ffd26c712ab680b1800a Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Thu, 30 Mar 2023 14:57:57 +0300 Subject: [PATCH 1/2] RP2040: Improve bootloader robustness The SD-card bootloader occassionally crashed due to either: - USB packets during flash writing (arduino/ArduinoCore-mbed#409) - Some flash XIP issues when function is not in RAM. --- lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp | 10 ++++++++++ lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp b/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp index c71938fa..fe25b71c 100644 --- a/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp +++ b/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -383,6 +384,7 @@ extern uint32_t __real_vectors_start; extern uint32_t __StackTop; static volatile void *g_bootloader_exit_req; +__attribute__((section(".time_critical.platform_rewrite_flash_page"))) bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_PAGE_SIZE]) { if (offset == PLATFORM_BOOTLOADER_SIZE) @@ -394,6 +396,13 @@ bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_ } } + if (NVIC_GetEnableIRQ(USBCTRL_IRQn)) + { + logmsg("Disabling USB during firmware flashing"); + NVIC_DisableIRQ(USBCTRL_IRQn); + usb_hw->main_ctrl = 0; + } + dbgmsg("Writing flash at offset ", offset, " data ", bytearray(buffer, 4)); assert(offset % PLATFORM_FLASH_PAGE_SIZE == 0); assert(offset >= PLATFORM_BOOTLOADER_SIZE); @@ -422,6 +431,7 @@ bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_ if (actual != expected) { logmsg("Flash verify failed at offset ", offset + i * 4, " got ", actual, " expected ", expected); + __enable_irq(); return false; } } diff --git a/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp b/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp index 9901ae28..dba67515 100644 --- a/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp +++ b/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -464,6 +465,7 @@ extern uint32_t __real_vectors_start; extern uint32_t __StackTop; static volatile void *g_bootloader_exit_req; +__attribute__((section(".time_critical.platform_rewrite_flash_page"))) bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_PAGE_SIZE]) { if (offset == PLATFORM_BOOTLOADER_SIZE) @@ -475,6 +477,13 @@ bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_ } } + if (NVIC_GetEnableIRQ(USBCTRL_IRQn)) + { + logmsg("Disabling USB during firmware flashing"); + NVIC_DisableIRQ(USBCTRL_IRQn); + usb_hw->main_ctrl = 0; + } + dbgmsg("Writing flash at offset ", offset, " data ", bytearray(buffer, 4)); assert(offset % PLATFORM_FLASH_PAGE_SIZE == 0); assert(offset >= PLATFORM_BOOTLOADER_SIZE); @@ -503,6 +512,7 @@ bool platform_rewrite_flash_page(uint32_t offset, uint8_t buffer[PLATFORM_FLASH_ if (actual != expected) { logmsg("Flash verify failed at offset ", offset + i * 4, " got ", actual, " expected ", expected); + __enable_irq(); return false; } } From 4f50677054ada1848fa9a94cd24c3bdd9491555a Mon Sep 17 00:00:00 2001 From: Petteri Aimonen Date: Thu, 30 Mar 2023 15:04:38 +0300 Subject: [PATCH 2/2] RP2040: Fix random boot hangs Sometimes flash_do_cmd() call would coincide with SysTick interrupt. Interrupts should be disabled when running it. --- lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp | 2 ++ lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp b/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp index fe25b71c..8a19fd57 100644 --- a/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp +++ b/lib/ZuluSCSI_platform_BS2/ZuluSCSI_platform.cpp @@ -95,7 +95,9 @@ void platform_init() // Get flash chip size uint8_t cmd_read_jedec_id[4] = {0x9f, 0, 0, 0}; uint8_t response_jedec[4] = {0}; + __disable_irq(); flash_do_cmd(cmd_read_jedec_id, response_jedec, 4); + __enable_irq(); g_flash_chip_size = (1 << response_jedec[3]); logmsg("Flash chip size: ", (int)(g_flash_chip_size / 1024), " kB"); diff --git a/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp b/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp index dba67515..a3bfb515 100644 --- a/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp +++ b/lib/ZuluSCSI_platform_RP2040/ZuluSCSI_platform.cpp @@ -111,7 +111,9 @@ void platform_init() // Get flash chip size uint8_t cmd_read_jedec_id[4] = {0x9f, 0, 0, 0}; uint8_t response_jedec[4] = {0}; + __disable_irq(); flash_do_cmd(cmd_read_jedec_id, response_jedec, 4); + __enable_irq(); g_flash_chip_size = (1 << response_jedec[3]); logmsg("Flash chip size: ", (int)(g_flash_chip_size / 1024), " kB");