Infineon: Add cyw20829 platform, shared slot feature, json memory map, psoc6 xip
Based in 1.8.0 release of MCUBoot library
This commit adds CYW20829 Infineon platform support with following capabilities:
1. Overwrite and swap upgrade mode support
2. Multi-image with up to 4 images
3. Hardware security counter is supported for CYW20829 platform
Add XIP support for PSOC6 platform - place BOOT slot in external memory and execute it in place using SMIF in XIP mode
and some new features for Infineon devices.
1. Shared upgrade slot feature - use one shared area for upgrade slots of multiple images
2. Memory map defined using JSON file - define memory regions for bootloader and user app in conventional way using JSON file
diff --git a/boot/cypress/MCUBootApp/main.c b/boot/cypress/MCUBootApp/main.c
index dee1e1a..6097173 100644
--- a/boot/cypress/MCUBootApp/main.c
+++ b/boot/cypress/MCUBootApp/main.c
@@ -17,16 +17,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
+#include <inttypes.h>
+#include <stdbool.h>
+
/* Cypress pdl headers */
#include "cy_pdl.h"
-#include "cy_retarget_io_pdl.h"
-#include "cy_result.h"
+#ifdef CYW20829
+#include "cy_retarget_io.h"
+#include "cybsp.h"
+#include "cyhal_wdt.h"
+#include "cyw_20829_utils.h"
+#include "cy_service_app.h"
+#else
+#include "cy_retarget_io_pdl.h"
#include "cycfg_clocks.h"
#include "cycfg_peripherals.h"
-#include "cycfg_pins.h"
+#endif /* CYW20829 */
#include "flash_qspi.h"
+
+#include "cycfg_pins.h"
+#include "cy_result.h"
#include "sysflash/sysflash.h"
#include "flash_map_backend/flash_map_backend.h"
@@ -40,137 +52,261 @@
#include "watchdog.h"
+#define CY_RSLT_MODULE_MCUBOOTAPP 0x500U
+#define CY_RSLT_MODULE_MCUBOOTAPP_MAIN 0x51U
+
+/** General module error */
+#define MCUBOOTAPP_RSLT_ERR \
+ (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_MCUBOOTAPP, CY_RSLT_MODULE_MCUBOOTAPP_MAIN, 0))
+
/* WDT time out for reset mode, in milliseconds. */
#define WDT_TIME_OUT_MS 4000
-/* Define pins for UART debug output */
-#define CYBSP_UART_ENABLED 1U
-#define CYBSP_UART_HW SCB5
-#define CYBSP_UART_IRQ scb_5_interrupt_IRQn
-
#ifdef CY_BOOT_USE_EXTERNAL_FLASH
/* Choose SMIF slot number (slave select).
* Acceptable values are:
* 0 - SMIF disabled (no external memory);
* 1, 2, 3 or 4 - slave select line memory module is connected to.
*/
-uint32_t smif_id = 1; /* Assume SlaveSelect_0 is used for External Memory */
-#endif
+#define SMIF_ID (1U) /* Assume SlaveSelect_0 is used for External Memory */
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+#define BOOT_MSG_FINISH "MCUBoot Bootloader finished.\n" \
+ "Deinitializing hardware..."
-void hw_deinit(void);
+static void hw_deinit(void);
-static void do_boot(struct boot_rsp *rsp)
+static inline __attribute__((always_inline))
+fih_uint calc_app_addr(uintptr_t flash_base, const struct boot_rsp *rsp)
{
- uint32_t app_addr = 0;
+ return fih_uint_encode(flash_base +
+ rsp->br_image_off +
+ rsp->br_hdr->ih_hdr_size);
+}
- app_addr = (rsp->br_image_off + rsp->br_hdr->ih_hdr_size);
+#ifdef CYW20829
- BOOT_LOG_INF("Starting User Application on CM4 (wait)...");
- BOOT_LOG_INF("Start Address: 0x%08lx", app_addr);
- BOOT_LOG_INF("Deinitializing hardware...");
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_BEGIN /* SMIF will be deinitialized in this case! */
+#else
+inline __attribute__((always_inline))
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+__NO_RETURN
+static void cyw20829_launch_app(fih_uint app_addr, uint32_t *key, uint32_t *iv)
+{
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+ qspi_deinit(SMIF_ID);
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+ cyw20829_RunApp(app_addr, key, iv);
+}
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP)
+CY_RAMFUNC_END /* SMIF will be deinitialized in this case! */
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
- cy_retarget_io_wait_tx_complete(CYBSP_UART_HW, 10);
+#endif /* CYW20829 */
- hw_deinit();
+static bool do_boot(struct boot_rsp *rsp)
+{
+ uintptr_t flash_base = 0;
- Cy_SysEnableCM4(app_addr);
+#ifdef CYW20829
+ uint32_t *key = NULL;
+ uint32_t *iv = NULL;
+#endif /* CYW20829 */
+
+ if (rsp != NULL) {
+ int rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
+
+ if (0 == rc) {
+ fih_uint app_addr = calc_app_addr(flash_base, rsp);
+
+ BOOT_LOG_INF("Starting User Application (wait)...");
+ if (IS_ENCRYPTED(rsp->br_hdr)) {
+ BOOT_LOG_DBG(" * User application is encrypted");
+ }
+ BOOT_LOG_INF("Start slot Address: 0x%08" PRIx32, (uint32_t)fih_uint_decode(app_addr));
+
+ rc = flash_device_base(rsp->br_flash_dev_id, &flash_base);
+ if ((rc != 0) || fih_uint_not_eq(calc_app_addr(flash_base, rsp), app_addr)) {
+ return false;
+ }
+
+#ifdef CYW20829
+#ifdef MCUBOOT_ENC_IMAGES_XIP
+ if (IS_ENCRYPTED(rsp->br_hdr)) {
+ key = rsp->xip_key;
+ iv = rsp->xip_iv;
+ } else {
+ BOOT_LOG_ERR("User image is not encrypted, while MCUBootApp is compiled with encryption support.");
+ return false;
+ }
+#endif /* MCUBOOT_ENC_IMAGES_XIP */
+ /* This function does not return */
+ BOOT_LOG_INF(BOOT_MSG_FINISH);
+ hw_deinit();
+ cyw20829_launch_app(app_addr, key, iv);
+#else
+ /* This function turns on CM4 and returns */
+ BOOT_LOG_INF(BOOT_MSG_FINISH);
+
+ hw_deinit();
+#ifdef USE_XIP
+ BOOT_LOG_DBG("XIP: Switch to SMIF XIP mode");
+ qspi_set_mode(CY_SMIF_MEMORY);
+#endif
+ Cy_SysEnableCM4(fih_uint_decode(app_addr));
+ return true;
+#endif /* CYW20829 */
+ } else {
+ BOOT_LOG_ERR("Flash device ID not found");
+ return false;
+ }
+ }
+
+ return false;
}
int main(void)
{
struct boot_rsp rsp;
- cy_rslt_t rc = CY_RSLT_TYPE_ERROR;
+ cy_rslt_t rc = MCUBOOTAPP_RSLT_ERR;
bool boot_succeeded = false;
fih_int fih_rc = FIH_FAILURE;
+#ifdef CYW20829
+ rc = cybsp_init();
+ if (rc != CY_RSLT_SUCCESS) {
+ CY_ASSERT((bool)0);
+ /* Loop forever... */
+ while (true) {
+ __WFI();
+ }
+ }
+#else
SystemInit();
- //init_cycfg_clocks();
init_cycfg_peripherals();
init_cycfg_pins();
+#endif /* CYW20829 */
+ /* enable interrupts */
+ __enable_irq();
- /* Certain PSoC 6 devices enable CM4 by default at startup. It must be
+ /* Certain PSoC 6 devices enable CM4 by default at startup. It must be
* either disabled or enabled & running a valid application for flash write
* to work from CM0+. Since flash write may happen in boot_go() for updating
* the image before this bootloader app can enable CM4 in do_boot(), we need
* to keep CM4 disabled. Note that debugging of CM4 is not supported when it
* is disabled.
*/
- #if defined(CY_DEVICE_PSOC6ABLE2)
- if (CY_SYS_CM4_STATUS_ENABLED == Cy_SysGetCM4Status())
- {
+#ifndef CYW20829
+#if defined(CY_DEVICE_PSOC6ABLE2)
+ if (CY_SYS_CM4_STATUS_ENABLED == Cy_SysGetCM4Status()) {
Cy_SysDisableCM4();
}
- #endif /* #if defined(CY_DEVICE_PSOC6ABLE2) */
-
- /* enable interrupts */
- __enable_irq();
+#endif /* defined(CY_DEVICE_PSOC6ABLE2) */
/* Initialize retarget-io to use the debug UART port (CYBSP_UART_HW) */
- rc = cy_retarget_io_pdl_init(115200u);
-
- if (rc != CY_RSLT_SUCCESS)
- {
- CY_ASSERT(0);
+ rc = cy_retarget_io_pdl_init(CY_RETARGET_IO_BAUDRATE);
+#else
+ /* Initialize retarget-io to use the debug UART port */
+ rc = cy_retarget_io_init(CYBSP_DEBUG_UART_TX,
+ CYBSP_DEBUG_UART_RX,
+ CY_RETARGET_IO_BAUDRATE);
+#endif /* CYW20829 */
+ if (rc != CY_RSLT_SUCCESS) {
+ CY_ASSERT((bool)0);
+ /* Loop forever... */
+ while (true) {
+ __WFI();
+ }
}
BOOT_LOG_INF("MCUBoot Bootloader Started");
#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- rc = CY_SMIF_CMD_NOT_FOUND;
+ {
+ cy_en_smif_status_t qspi_status = qspi_init_sfdp(SMIF_ID);
- rc = qspi_init_sfdp(smif_id);
- if (rc == CY_SMIF_SUCCESS)
- {
- BOOT_LOG_INF("External Memory initialized w/ SFDP.");
+ if (CY_SMIF_SUCCESS == qspi_status) {
+ rc = CY_RSLT_SUCCESS;
+ BOOT_LOG_INF("External Memory initialized w/ SFDP.");
+ } else {
+ rc = MCUBOOTAPP_RSLT_ERR;
+ BOOT_LOG_ERR("External Memory initialization w/ SFDP FAILED: 0x%08" PRIx32, (uint32_t)qspi_status);
+ }
}
- else
- {
- BOOT_LOG_ERR("External Memory initialization w/ SFDP FAILED: 0x%02x", (int)rc);
- }
- if (CY_SMIF_SUCCESS == rc)
-#endif
- {
+ if (CY_RSLT_SUCCESS == rc)
+#endif /* CY_BOOT_USE_EXTERNAL_FLASH */
+ {
+#if defined(CYW20829) && defined(MCUBOOT_HW_ROLLBACK_PROT)
+ /* Check service application completion status */
+ if (check_service_app_status() != 0) {
+ BOOT_LOG_ERR("Service application failed");
+ CY_ASSERT((bool)0);
+ /* Loop forever... */
+ while (true) {
+ __WFI();
+ }
+ }
+#endif /* CYW20829 && MCUBOOT_HW_ROLLBACK_PROT */
+
+ (void)memset(&rsp, 0, sizeof(rsp));
FIH_CALL(boot_go, fih_rc, &rsp);
- if (fih_eq(fih_rc, FIH_SUCCESS))
- {
+ if (true == fih_eq(fih_rc, FIH_SUCCESS)) {
BOOT_LOG_INF("User Application validated successfully");
/* initialize watchdog timer. it should be updated from user app
* to mark successful start up of this app. if the watchdog is not updated,
* reset will be initiated by watchdog timer and swap revert operation started
* to roll back to operable image.
*/
- cy_wdg_init(WDT_TIME_OUT_MS);
- do_boot(&rsp);
- boot_succeeded = true;
- }
- else
- {
- BOOT_LOG_INF("MCUBoot Bootloader found none of bootable images");
+#ifdef CYW20829
+ cyhal_wdt_t *cyw20829_wdt = NULL;
+
+ rc = cyhal_wdt_init(cyw20829_wdt, WDT_TIME_OUT_MS);
+#else
+ rc = cy_wdg_init(WDT_TIME_OUT_MS);
+#endif /* CYW20829 */
+ if (CY_RSLT_SUCCESS == rc) {
+
+ boot_succeeded = do_boot(&rsp);
+
+ if (!boot_succeeded) {
+ BOOT_LOG_ERR("Boot of next app failed");
+ }
+ } else {
+ BOOT_LOG_ERR("Failed to init WDT");
+ }
+ } else {
+ BOOT_LOG_ERR("MCUBoot Bootloader found none of bootable images");
}
}
- while (1)
- {
+ while (true) {
if (boot_succeeded) {
- Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
- }
- else {
+ (void)Cy_SysPm_CpuEnterDeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
+ } else {
__WFI();
}
}
-
- return 0;
}
-void hw_deinit(void)
+static void hw_deinit(void)
{
+#ifdef CYW20829
+ /* Flush the TX buffer, need to be fixed in retarget_io */
+ Cy_SysLib_Delay(50);
+
+ cy_retarget_io_deinit();
+ cy_wdg_stop();
+ cy_wdg_free();
+ /* Note: qspi_deinit() is called (if needed) in cyw20829_launch_app() above */
+#else
+ cy_retarget_io_wait_tx_complete(CYBSP_UART_HW, 10);
cy_retarget_io_pdl_deinit();
Cy_GPIO_Port_Deinit(CYBSP_UART_RX_PORT);
Cy_GPIO_Port_Deinit(CYBSP_UART_TX_PORT);
-
-#ifdef CY_BOOT_USE_EXTERNAL_FLASH
- qspi_deinit(smif_id);
-#endif
+#if defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) && !defined(USE_XIP)
+ qspi_deinit(SMIF_ID);
+#endif /* defined(CY_BOOT_USE_EXTERNAL_FLASH) && !defined(MCUBOOT_ENC_IMAGES_XIP) */
+#endif /* CYW20829 */
}