Skip to content

Commit

Permalink
M2354: Support PSA Firmware Update
Browse files Browse the repository at this point in the history
1.  Change from single image boot to multiple image boot
2.  SDH is configured to Secure for placing update firmware. It becomes inaccessible to Mbed.
3.  Post-build script supports both multiple image boot and single image boot
4.  Update readme to reflect above change
5.  Increase forced_reset_timeout due to longer booting time for Greentea test
  • Loading branch information
ccli8 committed Aug 2, 2021
1 parent 3318720 commit e37d471
Show file tree
Hide file tree
Showing 20 changed files with 674 additions and 200 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,35 @@ target_link_libraries(mbed-m2354-tfm
${CMAKE_CURRENT_SOURCE_DIR}/s_veneers.o
)

mbed_post_build_nuvoton_tfm_sign_image_tgt(
NU_M2354
${CMAKE_CURRENT_SOURCE_DIR}
nuvoton_m2354-root-rsa-3072.pem
)

# Must align with TF-M import assets
set(bl2 true)
set(mcuboot_image_number 1)
set(mcuboot_image_number 2)
set(region_defs_h_path "${CMAKE_CURRENT_SOURCE_DIR}/partition/region_defs.h")
set(update_stage_sdh true)
set(update_stage_flash false)

if(mcuboot_image_number EQUAL 2)
mbed_post_build_nuvoton_tfm_sign_image(
NU_M2354
${CMAKE_CURRENT_SOURCE_DIR}
nuvoton_m2354-root-rsa-3072.pem
nuvoton_m2354-root-rsa-3072_1.pem
)
else()
mbed_post_build_nuvoton_tfm_sign_image(
NU_M2354
${CMAKE_CURRENT_SOURCE_DIR}
nuvoton_m2354-root-rsa-3072.pem
NOTFOUND
)
endif()

target_compile_definitions(mbed-m2354-tfm
INTERFACE
NU_TFM_S_BL2=$<IF:$<BOOL:${bl2}>,1,0>
NU_TFM_S_MCUBOOT_IMAGE_NUMBER=${mcuboot_image_number}
# TODO: Fix escape sequence in NU_TFM_S_REGION_DEFS_H_PATH
#NU_TFM_S_REGION_DEFS_H_PATH=\"${region_defs_h_path}\"
NU_TFM_S_UPDATE_STAGE_SDH=$<IF:$<BOOL:${update_stage_sdh}>,1,0>
NU_TFM_S_UPDATE_STAGE_FLASH=$<IF:$<BOOL:${update_stage_flash}>,1,0>
)
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# Rebuild TF-M and integrate with Mbed on M2354
# Rebuild TF-M and integrate with Mbed for M2354

This document guides how to rebuild TF-M and integrate with Mbed on M2354.
This document guides how to rebuild TF-M and integrate with Mbed for M2354.

### Downloading TF-M source

The M2354 port in TF-M must patch to enable TF-M integration with Mbed.
For TF-M 1.3/Mbed integration on M2354, the [mainstream TF-M](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git) is patched as follows:
For TF-M 1.3/Mbed integration for M2354, the [mainstream TF-M](https://git.trustedfirmware.org/TF-M/trusted-firmware-m.git) is patched as follows:
- Apply Mbed-enabled patch to `nuvoton/m2354` TF-M target.

Run the following command to fetch and switch to the intended version:
```sh
git clone https://github.com/OpenNuvoton/trusted-firmware-m -b nuvoton_mbed_m2354_tfm-1.3
```
$ git clone https://github.com/OpenNuvoton/trusted-firmware-m -b nuvoton_mbed_m2354_tfm-1.3
```

## Customizing TF-M
Expand All @@ -36,6 +36,7 @@ In TF-M, by default, the M2354 hardware is partitioned as follows:
- **PDMA1**: Configured to nonsecure for Mbed asynchronous transfer.
- **CRYPTO**: Configured to secure. Inaccessible to Mbed.
- **TRNG**: Hardwired to secure. Accessible to Mbed indirectly through PSA Cryptography API.
- **SDH**: Configured to secure to enable PSA Firmware Update. Inaccessible to Mbed.

### Defining Flash for TF-M/Mbed

Expand Down Expand Up @@ -77,12 +78,18 @@ Then go through **DOCS** → **Getting Started Guides** → **Software requireme

**NOTE**: **GNU Arm Embedded Toolchain 10-2020-q4-major** built code **FAILS** to run. Avoid this toolchain version. Check [its bug report](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99157).

### Compile
### Default relevant build configurations

- Enabled BL2 (MCUboot)
- Enabled multiple image boot
- Enabled SDH (SD card) as update staging area for PSA Firmware Update

To compile TF-M on M2354, run:
### Compiling

```sh
cmake -S . \
To compile TF-M for M2354, run:

```
$ cmake -S . \
-B cmake_build \
-DTFM_PLATFORM=nuvoton/m2354 \
-DTFM_TOOLCHAIN_FILE=toolchain_GNUARM.cmake \
Expand All @@ -93,8 +100,8 @@ cmake -S . \

Then:

```sh
cmake --build cmake_build -- install
```
$ cmake --build cmake_build -- install
```

## Integrating with Mbed
Expand All @@ -111,21 +118,41 @@ The following TF-M exported stuffs must update into Mbed:

- partition/: Flash layout for image signing and concatenating in post-build process

**NOTE**: On import, `signing_layout_s_ns.o` is renamed to `signing_layout_preprocessed.h` for the following reasons:
- Post-build script checks file name with `_s`/`_ns` to resolve `sw_type` as `SPE`/`NSPE` respectively.
To recognize as `NSPE_SPE`, don't use `_s_ns`/`_ns_s` file name to avoid mis-recognized.
- Use `.h` instead of `.c` as file extension name.
This is to enable custom TF-M build where the locatioin of this directory can change elsewhere.
In Greentea build process, `.c` file isn't but`.h` file is copied into `BUILD` directory, so that post-build script can still access the file.
**NOTE**: On import, `signing_layout_*.o` are renamed to `signing_layout_*.h`.
This is to use `.h` instead of `.c`/`.o` as file extension name and avoid adding into compile/link list.

**NOTE**: On import for single image boot, `signing_layout_s_ns.o` is renamed to `signing_layout_preprocessed.h`.
Post-build script checks file name with `_s`/`_ns` to resolve `sw_type` as `SPE`/`NSPE` respectively.
To recognize as `NSPE_SPE`, don't use `_s_ns`/`_ns_s` file name to avoid mis-recognized.

- [signing_key/](signing_key/nuvoton_m2354-root-rsa-3072.md)

Below summarizes the copy paths from TF-M into Mbed:
Below summarize the copy paths from TF-M into Mbed:

- trusted-firmware-m/cmake_build/bin/bl2.bin → bl2.bin
- trusted-firmware-m/cmake_build/install/export/tfm/lib/s_veneers.os_veneers.o
- trusted-firmware-m/cmake_build/bin/tfm_s.bintfm_s.bin
- trusted-firmware-m/cmake_build/install/outputs/NUVOTON/M2354/bl2.bin → bl2.bin
- trusted-firmware-m/cmake_build/install/outputs/NUVOTON/M2354/tfm_s.bintfm_s.bin
- trusted-firmware-m/cmake_build/install/interface/lib/s_veneers.os_veneers.o
- trusted-firmware-m/platform/ext/target/nuvoton/m2354/partition/flash_layout.h → partition/flash_layout.h
- trusted-firmware-m/platform/ext/target/nuvoton/m2354/partition/region_defs.h → partition/region_defs.h
- trusted-firmware-m/cmake_build/bl2/ext/mcuboot/CMakeFiles/signing_layout_s.dir/signing_layout_s_ns.o → partition/signing_layout_preprocessed.h
- trusted-firmware-m/bl2/ext/mcuboot/root-RSA-3072.pem → signing_key/nuvoton_m2354-root-rsa-3072.pem
- trusted-firmware-m/cmake_build/install/image_signing/layout_files/signing_layout_s.o → partition/signing_layout_s_preprocessed.h
- trusted-firmware-m/cmake_build/install/image_signing/layout_files/signing_layout_ns.o → partition/signing_layout_ns_preprocessed.h
- trusted-firmware-m/cmake_build/install/image_signing/keys/root-RSA-3072.pem → signing_key/nuvoton_m2354-root-rsa-3072.pem
- trusted-firmware-m/cmake_build/install/image_signing/keys/root-RSA-3072_1.pem → signing_key/nuvoton_m2354-root-rsa-3072_1.pem

**NOTE**: `trusted-firmware-m/cmake_build/install/image_signing/keys/root-RSA-3072.pem` can be missing due to TF-M build tool issue.
Try to get it from `trusted-firmware-m/bl2/ext/mcuboot/root-RSA-3072.pem` instead if it is just the original source.

## PSA Firmware Update

### Requirement

- SD card: Used for update staging area according to above TF-M build configurations.

### Update binary files

After finishing Mbed build, you will find the following files under build directory.
They are to write to update staging area through PSA Firmware Update API for firmware upgrade.

- `tfm_s_update.bin`: TF-M secure binary file for update separately when multiple image boot is enabled
- `<application>_update.bin`: Mbed non-secure binary file for update separately when multiple image boot is enabled or
combined TF-M secure+Mbed non-secure binary file for update together when single image boot is enabled
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
* @copyright SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
* Copyright (c) 2020 Nuvoton Technology Corp. All rights reserved.
*
Expand All @@ -21,15 +20,42 @@

/* Flash layout on M2354 with BL2 (single image boot):
*
* 0x0000_0000 BL2 - MCUBoot (64KB)
* 0x0001_0000 Protected Storage Area (32 KB)
* 0x0000_8000 Internal Trusted Storage Area (28 KB)
* 0x0000_F000 NV counters area (4 KB)
* 0x0002_0000 Primary image area (320KB):
* 0x0002_0000 Secure image primary
* 0x0007_0000 Non-secure image primary
* 0x0010_0000 Scratch area (4KB)
* Internal Flash:
* 0x0000_0000 BL2 - MCUBoot (48KB)
* 0x0000_C000 Protected Storage Area (56 KB)
* 0x0001_A000 Internal Trusted Storage Area (20 KB)
* 0x0001_F000 NV counters area (4 KB)
* 0x0002_0000 Primary image area (896KB):
* 0x0002_0000 Secure image primary (320KB)
* 0x0007_0000 Non-secure image primary (576KB)
* 0x0010_0000 Secondary image area (2KB):
* 0x0010_0000 Secure image secondary (320KB) (Dummy)
* 0x0015_0000 Non-secure image secondary (576KB) (Dummy)
* 0x001E_0000 Scratch area (4KB) (Dummy)
*
* SDH Flash:
* 0x0000_0000 Secondary image area (896KB)
* 0x0000_0000 Secure image secondary (320KB)
* 0x0005_0000 Non-secure image secondary (576KB)
* 0x0020_0000 Scratch area (4 KB)
*
* Flash layout on M2354 with BL2 (multiple image boot):
*
* Internal Flash:
* 0x0000_0000 BL2 - MCUBoot (48KB)
* 0x0000_C000 Protected Storage Area (56 KB)
* 0x0001_A000 Internal Trusted Storage Area (20 KB)
* 0x0001_F000 NV counters area (4 KB)
* 0x0002_0000 Secure image primary slot (320KB)
* 0x0007_0000 Non-secure image primary slot (576KB)
* 0x0010_0000 Secure image secondary slot (320KB) (Dummy)
* 0x0015_0000 Non-secure image secondary slot (576KB) (Dummy)
* 0x001E_0000 Scratch area (4KB) (Dummy)
*
* SDH Flash:
* 0x0000_0000 Secure image secondary slot (320KB)
* 0x0010_0000 Non-secure image secondary slot (576KB)
* 0x0020_0000 Scratch area (2 KB)
*/

/* This header file is included from linker scatter file as well, where only a
Expand All @@ -40,8 +66,13 @@
*/

/* Size of a Secure and of a Non-secure image */
#define FLASH_S_PARTITION_SIZE (0x50000) /* S partition : 192+64+64 KB */
#define FLASH_NS_PARTITION_SIZE (0x90000) /* NS partition: 768-64-64 KB */
#if !NU_UPDATE_STAGE_FLASH
#define FLASH_S_PARTITION_SIZE (0x50000) /* S partition : 320 KB */
#define FLASH_NS_PARTITION_SIZE (0x90000) /* NS partition: 576 KB */
#else
#define FLASH_S_PARTITION_SIZE (0x46000) /* S partition : 280 KB */
#define FLASH_NS_PARTITION_SIZE (0x28000) /* NS partition: 160 KB */
#endif
#define FLASH_MAX_PARTITION_SIZE ((FLASH_S_PARTITION_SIZE > \
FLASH_NS_PARTITION_SIZE) ? \
FLASH_S_PARTITION_SIZE : \
Expand All @@ -50,34 +81,56 @@
/* Sector size of the flash hardware; same as FLASH0_SECTOR_SIZE */
#define FLASH_AREA_IMAGE_SECTOR_SIZE (0x800) /* 2 KB */
/* Same as FLASH0_SIZE */
#define FLASH_TOTAL_SIZE (0x00100000) /* 512 KB */
#define FLASH_TOTAL_SIZE (0x00100000) /* 1024 KB */

/* Flash layout info for BL2 bootloader */
/* Same as FLASH0_BASE_S */
#define FLASH_BASE_ADDRESS (0x00000000)

#if NU_UPDATE_STAGE_SDH
#define SDH_FLASH_DEVICE_ID (FLASH_DEVICE_ID + 1)
#define SDH_FLASH_DEV_NAME Driver_SDH_FLASH0
#define SDH_FLASH_BASE_ADDRESS (0x00000000)
#endif

/* Offset and size definitions of the flash partitions that are handled by the
* bootloader. The image swapping is done between IMAGE_PRIMARY and
* IMAGE_SECONDARY, SCRATCH is used as a temporary storage during image
* swapping.
*/
#define FLASH_AREA_BL2_OFFSET (0x0)
#define FLASH_AREA_BL2_SIZE (0x10000) /* 64 KB */
#define FLASH_AREA_BL2_SIZE (0xC000) /* 48 KB */

#if !defined(MCUBOOT_IMAGE_NUMBER) || (MCUBOOT_IMAGE_NUMBER == 1)
/* Secure + Non-secure image primary slot */
#define FLASH_AREA_0_ID (1)
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE + 0x10000) /* 0x10000 */
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE) /* 480 KB */
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE + 0x14000) /* Reserved for storage */
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE)
/* Secure + Non-secure secondary slot */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_2_OFFSET (0x100000)
#define FLASH_AREA_2_SIZE (0x800)
#define FLASH_AREA_2_OFFSET (0x0)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE)
#define FLASH_DEVICE_ID_2 SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_2 SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_2_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_2_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE + FLASH_NS_PARTITION_SIZE)
#endif

/* Scratch area */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (0x200000)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#define FLASH_DEVICE_ID_SCRATCH SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_SCRATCH SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (0x100800)
#define FLASH_AREA_SCRATCH_SIZE (0x800)
#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#endif

/* The maximum number of status entries supported by the bootloader. */
#define MCUBOOT_STATUS_MAX_ENTRIES ((FLASH_S_PARTITION_SIZE + \
Expand All @@ -88,24 +141,79 @@
#define MCUBOOT_MAX_IMG_SECTORS ((FLASH_S_PARTITION_SIZE + \
FLASH_NS_PARTITION_SIZE) / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
#elif (MCUBOOT_IMAGE_NUMBER == 2)
/* Secure image primary slot */
#define FLASH_AREA_0_ID (1)
#define FLASH_AREA_0_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE + 0x14000) /* Reserved for storage */
#define FLASH_AREA_0_SIZE (FLASH_S_PARTITION_SIZE)
/* Non-secure image primary slot */
#define FLASH_AREA_1_ID (FLASH_AREA_0_ID + 1)
#define FLASH_AREA_1_OFFSET (FLASH_AREA_0_OFFSET + FLASH_AREA_0_SIZE)
#define FLASH_AREA_1_SIZE (FLASH_NS_PARTITION_SIZE)

/* Secure image secondary slot */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
#define FLASH_AREA_2_OFFSET (0x0)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
#define FLASH_DEVICE_ID_2 SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_2 SDH_FLASH_DEV_NAME
#else
#error "Only MCUBOOT_IMAGE_NUMBER 1 are supported!"
#define FLASH_AREA_2_ID (FLASH_AREA_1_ID + 1)
#define FLASH_AREA_2_OFFSET (FLASH_AREA_1_OFFSET + FLASH_AREA_1_SIZE)
#define FLASH_AREA_2_SIZE (FLASH_S_PARTITION_SIZE)
#endif

/* Non-secure image secondary slot */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_3_OFFSET (0x100000)
#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
#define FLASH_DEVICE_ID_3 SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_3 SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_3_ID (FLASH_AREA_2_ID + 1)
#define FLASH_AREA_3_OFFSET (FLASH_AREA_2_OFFSET + FLASH_AREA_2_SIZE)
#define FLASH_AREA_3_SIZE (FLASH_NS_PARTITION_SIZE)
#endif

/* Scratch area */
#if NU_UPDATE_STAGE_SDH
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (0x200000)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#define FLASH_DEVICE_ID_SCRATCH SDH_FLASH_DEVICE_ID
#define FLASH_DEV_NAME_SCRATCH SDH_FLASH_DEV_NAME
#else
#define FLASH_AREA_SCRATCH_ID (FLASH_AREA_3_ID + 1)
#define FLASH_AREA_SCRATCH_OFFSET (FLASH_AREA_3_OFFSET + FLASH_AREA_3_SIZE)
#define FLASH_AREA_SCRATCH_SIZE (0x1000)
#endif

/* The maximum number of status entries supported by the bootloader. */
#define MCUBOOT_STATUS_MAX_ENTRIES (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_SCRATCH_SIZE)

/* Maximum number of image sectors supported by the bootloader. */
#define MCUBOOT_MAX_IMG_SECTORS (FLASH_MAX_PARTITION_SIZE / \
FLASH_AREA_IMAGE_SECTOR_SIZE)
#else /* MCUBOOT_IMAGE_NUMBER > 2 */
#error "Only MCUBOOT_IMAGE_NUMBER 1 and 2 are supported!"
#endif /* MCUBOOT_IMAGE_NUMBER */

/* Protected Storage (PS) Service definitions */
#define FLASH_PS_AREA_OFFSET (0x10000)
#define FLASH_PS_AREA_SIZE (0x8000)
#define FLASH_PS_AREA_OFFSET (FLASH_AREA_BL2_OFFSET + FLASH_AREA_BL2_SIZE)
#define FLASH_PS_AREA_SIZE (0xE000)

/* Internal Trusted Storage (ITS) Service definitions */
#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + \
FLASH_PS_AREA_SIZE)
#define FLASH_ITS_AREA_SIZE (0x7000)
#define FLASH_ITS_AREA_SIZE (0x5000)

/* NV Counters definitions */
#define FLASH_NV_COUNTERS_AREA_OFFSET (FLASH_ITS_AREA_OFFSET + \
FLASH_ITS_AREA_SIZE)
#define FLASH_NV_COUNTERS_AREA_SIZE (FLASH_AREA_IMAGE_SECTOR_SIZE)
#define FLASH_NV_COUNTERS_AREA_SIZE (0x1000)

/* Offset and size definition in flash area used by assemble.py */
#define SECURE_IMAGE_OFFSET (0x0)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
* @copyright SPDX-License-Identifier: Apache-2.0
* Copyright (c) 2017-2020 Arm Limited. All rights reserved.
* Copyright (c) 2020 Nuvoton Technology Corp. All rights reserved.
*
Expand Down Expand Up @@ -98,7 +97,7 @@
#define S_CODE_LIMIT (S_CODE_START + S_CODE_SIZE - 1)

#define S_DATA_START (S_RAM_ALIAS(0x0))
#define S_DATA_SIZE (80 * 1024)
#define S_DATA_SIZE (96 * 1024)
#define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1)

/* CMSE Veneers region */
Expand Down
Loading

0 comments on commit e37d471

Please sign in to comment.