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/boot_serial/src/boot_serial.c b/boot/boot_serial/src/boot_serial.c
index d0f0eb0..914167e 100644
--- a/boot/boot_serial/src/boot_serial.c
+++ b/boot/boot_serial/src/boot_serial.c
@@ -25,6 +25,7 @@
#include "sysflash/sysflash.h"
#include "bootutil/bootutil_log.h"
+#include "cbor_encode.h"
#ifdef __ZEPHYR__
#include <power/reboot.h>
@@ -33,8 +34,6 @@
#include <drivers/flash.h>
#include <sys/crc.h>
#include <sys/base64.h>
-#include <tinycbor/cbor.h>
-#include <tinycbor/cbor_buf_reader.h>
#else
#include <bsp/bsp.h>
#include <hal/hal_system.h>
@@ -42,7 +41,6 @@
#include <os/os_cputime.h>
#include <crc/crc16.h>
#include <base64/base64.h>
-#include <tinycbor/cbor.h>
#endif /* __ZEPHYR__ */
#include <flash_map_backend/flash_map_backend.h>
@@ -56,16 +54,21 @@
#include "boot_serial/boot_serial.h"
#include "boot_serial_priv.h"
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
#include "bootutil_priv.h"
#endif
#include "serial_recovery_cbor.h"
+#include "bootutil/boot_hooks.h"
-MCUBOOT_LOG_MODULE_DECLARE(mcuboot);
+BOOT_LOG_MODULE_DECLARE(mcuboot);
+
+#ifndef BOOT_IMAGE_NUMBER
+#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
+#endif
#define BOOT_SERIAL_INPUT_MAX 512
-#define BOOT_SERIAL_OUT_MAX 128
+#define BOOT_SERIAL_OUT_MAX (128 * MCUBOOT_IMAGE_NUMBER)
#ifdef __ZEPHYR__
/* base64 lib encodes data to null-terminated string */
@@ -78,10 +81,6 @@
#define htons(x) sys_cpu_to_be16(x)
#endif
-#ifndef BOOT_IMAGE_NUMBER
-#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
-#endif
-
#if (BOOT_IMAGE_NUMBER > 1)
#define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x))
#else
@@ -97,28 +96,28 @@
static char bs_obuf[BOOT_SERIAL_OUT_MAX];
-static int bs_cbor_writer(struct cbor_encoder_writer *, const char *data,
- int len);
static void boot_serial_output(void);
-static struct cbor_encoder_writer bs_writer = {
- .write = bs_cbor_writer
+static cbor_state_backups_t dummy_backups;
+static cbor_state_t cbor_state = {
+ .backups = &dummy_backups
};
-static CborEncoder bs_root;
-static CborEncoder bs_rsp;
-int
-bs_cbor_writer(struct cbor_encoder_writer *cew, const char *data, int len)
-{
- if (cew->bytes_written + len > sizeof(bs_obuf)) {
- return CborErrorOutOfMemory;
- }
-
- memcpy(&bs_obuf[cew->bytes_written], data, len);
- cew->bytes_written += len;
-
- return 0;
-}
+/**
+ * Function that processes MGMT_GROUP_ID_PERUSER mcumgr group and may be
+ * used to process any groups that have not been processed by generic boot
+ * serial implementation.
+ *
+ * @param[in] hdr -- the decoded header of mcumgr message;
+ * @param[in] buffer -- buffer with first mcumgr message;
+ * @param[in] len -- length of of data in buffer;
+ * @param[out] *cs -- object with encoded response.
+ *
+ * @return 0 on success; non-0 error code otherwise.
+ */
+extern int bs_peruser_system_specific(const struct nmgr_hdr *hdr,
+ const char *buffer,
+ int len, cbor_state_t *cs);
/*
* Convert version into string without use of snprintf().
@@ -172,17 +171,15 @@
static void
bs_list(char *buf, int len)
{
- CborEncoder images;
- CborEncoder image;
struct image_header hdr;
uint8_t tmpbuf[64];
- int slot, area_id;
+ uint32_t slot, area_id;
const struct flash_area *fap;
uint8_t image_index;
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "images");
- cbor_encoder_create_array(&bs_rsp, &images, CborIndefiniteLength);
+ map_start_encode(&cbor_state, 1);
+ tstrx_put(&cbor_state, "images");
+ list_start_encode(&cbor_state, 5);
image_index = 0;
IMAGES_ITER(image_index) {
for (slot = 0; slot < 2; slot++) {
@@ -191,34 +188,51 @@
continue;
}
- flash_area_read(fap, 0, &hdr, sizeof(hdr));
-
- if (hdr.ih_magic != IMAGE_MAGIC ||
- bootutil_img_validate(NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
- NULL, 0, NULL)) {
- flash_area_close(fap);
- continue;
+ int rc = BOOT_HOOK_CALL(boot_read_image_header_hook,
+ BOOT_HOOK_REGULAR, image_index, slot, &hdr);
+ if (rc == BOOT_HOOK_REGULAR)
+ {
+ flash_area_read(fap, 0, &hdr, sizeof(hdr));
}
+
+ fih_int fih_rc = FIH_FAILURE;
+
+ if (hdr.ih_magic == IMAGE_MAGIC)
+ {
+ BOOT_HOOK_CALL_FIH(boot_image_check_hook,
+ fih_int_encode(BOOT_HOOK_REGULAR),
+ fih_rc, image_index, slot);
+ if (fih_eq(fih_rc, BOOT_HOOK_REGULAR))
+ {
+ FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
+ NULL, 0, NULL);
+ }
+ }
+
flash_area_close(fap);
- cbor_encoder_create_map(&images, &image, CborIndefiniteLength);
+ if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ continue;
+ }
+
+ map_start_encode(&cbor_state, 20);
#if (BOOT_IMAGE_NUMBER > 1)
- cbor_encode_text_stringz(&image, "image");
- cbor_encode_int(&image, image_index);
+ tstrx_put(&cbor_state, "image");
+ uintx32_put(&cbor_state, image_index);
#endif
- cbor_encode_text_stringz(&image, "slot");
- cbor_encode_int(&image, slot);
- cbor_encode_text_stringz(&image, "version");
+ tstrx_put(&cbor_state, "slot");
+ uintx32_put(&cbor_state, slot);
+ tstrx_put(&cbor_state, "version");
bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
- cbor_encode_text_stringz(&image, (char *)tmpbuf);
- cbor_encoder_close_container(&images, &image);
+ tstrx_put_term(&cbor_state, (char *)tmpbuf);
+ map_end_encode(&cbor_state, 20);
}
}
- cbor_encoder_close_container(&bs_rsp, &images);
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ list_end_encode(&cbor_state, 5);
+ map_end_encode(&cbor_state, 1);
boot_serial_output();
}
@@ -229,15 +243,15 @@
bs_upload(char *buf, int len)
{
const uint8_t *img_data = NULL;
- long long int off = UINT_MAX;
+ long long int off = UINT64_MAX;
size_t img_blen = 0;
uint8_t rem_bytes;
- long long int data_len = UINT_MAX;
+ long long int data_len = UINT64_MAX;
int img_num;
size_t slen;
const struct flash_area *fap = NULL;
int rc;
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
static off_t off_last = -1;
struct flash_sector sector;
#endif
@@ -254,13 +268,16 @@
* }
*/
- Upload_t upload;
- if (!cbor_decode_Upload((const uint8_t *)buf, len, &upload)) {
+ struct Upload upload;
+ uint32_t decoded_len;
+ bool result = cbor_decode_Upload((const uint8_t *)buf, len, &upload, &decoded_len);
+
+ if (!result || (len != decoded_len)) {
goto out_invalid_data;
}
for (int i = 0; i < upload._Upload_members_count; i++) {
- _Member_t *member = &upload._Upload_members[i];
+ struct Member_ *member = &upload._Upload_members[i];
switch(member->_Member_choice) {
case _Member_image:
img_num = member->_Member_image;
@@ -283,14 +300,18 @@
}
}
- if (off == UINT_MAX || img_data == NULL) {
+ if (off == UINT64_MAX || img_data == NULL) {
/*
* Offset must be set in every block.
*/
goto out_invalid_data;
}
+#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
rc = flash_area_open(flash_area_id_from_multi_image_slot(img_num, 0), &fap);
+#else
+ rc = flash_area_open(flash_area_id_from_direct_image(img_num), &fap);
+#endif
if (rc) {
rc = MGMT_ERR_EINVAL;
goto out;
@@ -298,11 +319,11 @@
if (off == 0) {
curr_off = 0;
- if (data_len > fap->fa_size) {
+ if (data_len > flash_area_get_size(fap)) {
goto out_invalid_data;
}
-#ifndef CONFIG_BOOT_ERASE_PROGRESSIVELY
- rc = flash_area_erase(fap, 0, fap->fa_size);
+#ifndef MCUBOOT_ERASE_PROGRESSIVELY
+ rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
if (rc) {
goto out_invalid_data;
}
@@ -326,16 +347,17 @@
rem_bytes = 0;
}
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
rc = flash_area_sector_from_off(curr_off + img_blen, §or);
if (rc) {
BOOT_LOG_ERR("Unable to determine flash sector size");
goto out;
}
- if (off_last != sector.fs_off) {
- off_last = sector.fs_off;
- BOOT_LOG_INF("Erasing sector at offset 0x%x", sector.fs_off);
- rc = flash_area_erase(fap, sector.fs_off, sector.fs_size);
+ if (off_last != flash_sector_get_off(§or)) {
+ off_last = flash_sector_get_off(§or);
+ BOOT_LOG_INF("Erasing sector at offset 0x%x", flash_sector_get_off(§or));
+ rc = flash_area_erase(fap, flash_sector_get_off(§or),
+ flash_sector_get_size(§or));
if (rc) {
BOOT_LOG_ERR("Error %d while erasing sector", rc);
goto out;
@@ -372,8 +394,8 @@
if (rc == 0) {
curr_off += img_blen;
-#ifdef CONFIG_BOOT_ERASE_PROGRESSIVELY
if (curr_off == img_size) {
+#ifdef MCUBOOT_ERASE_PROGRESSIVELY
/* get the last sector offset */
rc = flash_area_sector_from_off(boot_status_off(fap), §or);
if (rc) {
@@ -383,16 +405,24 @@
}
/* Assure that sector for image trailer was erased. */
/* Check whether it was erased during previous upload. */
- if (off_last < sector.fs_off) {
- BOOT_LOG_INF("Erasing sector at offset 0x%x", sector.fs_off);
- rc = flash_area_erase(fap, sector.fs_off, sector.fs_size);
+ if (off_last < flash_sector_get_off(§or)) {
+ BOOT_LOG_INF("Erasing sector at offset 0x%x",
+ flash_sector_get_off(§or));
+ rc = flash_area_erase(fap, flash_sector_get_off(§or),
+ flash_sector_get_size(§or));
if (rc) {
BOOT_LOG_ERR("Error %d while erasing sector", rc);
goto out;
}
}
- }
#endif
+ rc = BOOT_HOOK_CALL(boot_serial_uploaded_hook, 0, img_num, fap,
+ img_size);
+ if (rc) {
+ BOOT_LOG_ERR("Error %d post upload hook", rc);
+ goto out;
+ }
+ }
} else {
out_invalid_data:
rc = MGMT_ERR_EINVAL;
@@ -400,14 +430,14 @@
out:
BOOT_LOG_INF("RX: 0x%x", rc);
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "rc");
- cbor_encode_int(&bs_rsp, rc);
+ map_start_encode(&cbor_state, 10);
+ tstrx_put(&cbor_state, "rc");
+ uintx32_put(&cbor_state, rc);
if (rc == 0) {
- cbor_encode_text_stringz(&bs_rsp, "off");
- cbor_encode_uint(&bs_rsp, curr_off);
+ tstrx_put(&cbor_state, "off");
+ uintx32_put(&cbor_state, curr_off);
}
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ map_end_encode(&cbor_state, 10);
boot_serial_output();
flash_area_close(fap);
@@ -419,10 +449,10 @@
static void
bs_empty_rsp(char *buf, int len)
{
- cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
- cbor_encode_text_stringz(&bs_rsp, "rc");
- cbor_encode_int(&bs_rsp, 0);
- cbor_encoder_close_container(&bs_root, &bs_rsp);
+ map_start_encode(&cbor_state, 10);
+ tstrx_put(&cbor_state, "rc");
+ uintx32_put(&cbor_state, 0);
+ map_end_encode(&cbor_state, 10);
boot_serial_output();
}
@@ -436,7 +466,11 @@
bs_empty_rsp(buf, len);
#ifdef __ZEPHYR__
+#ifdef CONFIG_MULTITHREADING
k_sleep(K_MSEC(250));
+#else
+ k_busy_wait(250000);
+#endif
sys_reboot(SYS_REBOOT_COLD);
#else
os_cputime_delay_usecs(250000);
@@ -465,8 +499,9 @@
buf += sizeof(*hdr);
len -= sizeof(*hdr);
- bs_writer.bytes_written = 0;
- cbor_encoder_init(&bs_root, &bs_writer, 0);
+ cbor_state.payload_mut = (uint8_t *)bs_obuf;
+ cbor_state.payload_end = (const uint8_t *)bs_obuf
+ + sizeof(bs_obuf);
/*
* Limited support for commands.
@@ -494,6 +529,10 @@
default:
break;
}
+ } else if (MCUBOOT_PERUSER_MGMT_GROUP_ENABLED == 1) {
+ if (bs_peruser_system_specific(hdr, buf, len, &cbor_state) == 0) {
+ boot_serial_output();
+ }
}
}
@@ -509,7 +548,7 @@
char encoded_buf[BASE64_ENCODE_SIZE(BOOT_SERIAL_OUT_MAX)];
data = bs_obuf;
- len = bs_writer.bytes_written;
+ len = (uint32_t)cbor_state.payload_mut - (uint32_t)bs_obuf;
bs_hdr->nh_op++;
bs_hdr->nh_flags = 0;
@@ -624,6 +663,7 @@
off = 0;
while (1) {
+ MCUBOOT_CPU_IDLE();
rc = f->read(in_buf + off, sizeof(in_buf) - off, &full_line);
if (rc <= 0 && !full_line) {
continue;