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 */
 }