samples: tfm_integration: Remove psa_firmware
Removes the `psa_firmware` sample, which is based on an older version (0.7) of the FWU service from TF-M 1.6.0. This sample needs to be refactored to use FWU 1.0, included in TF-M 1.7.0 and future releases. Signed-off-by: Kevin Townsend <kevin.townsend@linaro.org> Signed-off-by: David Brown <david.brown@linaro.org>
This commit is contained in:
parent
2ba39d8bf1
commit
a50aafd938
|
@ -1,105 +0,0 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
|
||||
project(tfm_psa_firmware)
|
||||
|
||||
|
||||
if (NOT CONFIG_APP_FIRMWARE_UPDATE_IMAGE)
|
||||
message(FATAL_ERROR "CONFIG_APP_FIRMWARE_UPDATE_IMAGE required")
|
||||
endif()
|
||||
|
||||
# NOTE: These must not include ${CMAKE_BINARY_DIR} otherwise you get an
|
||||
# absolute path as part of the C symbols in the generated object file.
|
||||
# This is difficult to use in a correct and portable way. Instead, we will
|
||||
# take advantage of running everything from within the build directory.
|
||||
set(UPDATE_SIGNED_HEX update-signed.hex)
|
||||
set(UPDATE_BIN update-image.bin)
|
||||
set(UPDATE_OBJ update-image.o)
|
||||
set(UPDATE_HEADER_BIN update-header.bin)
|
||||
set(UPDATE_HEADER_OBJ update-header.o)
|
||||
|
||||
# The following sequence of add_custom_command calls builds a dependency
|
||||
# graph of all the bits we need to sign# an image. The process looks
|
||||
# something like:
|
||||
#
|
||||
# [(1) sample.hex ]
|
||||
# |
|
||||
# v
|
||||
# [(2) sign with imgtool ]
|
||||
# |
|
||||
# v
|
||||
# [(3) split-header.py ]
|
||||
# | |
|
||||
# app | | header
|
||||
# v v
|
||||
# [(4,5) objdump bin to obj ]
|
||||
# | |
|
||||
# app obj | | header obj
|
||||
# v v
|
||||
# [(6) target_sources(..) ]
|
||||
#
|
||||
# Note that node (1) is an input.
|
||||
|
||||
# This is duplicated from the trusted-firmware-m CMakeLists.txt, as this
|
||||
# needs it and CMAKE does not allow us to import the varibales from that
|
||||
# directory.
|
||||
set(TFM_MCUBOOT_DIR "${ZEPHYR_TRUSTED_FIRMWARE_M_MODULE_DIR}/bl2/ext/mcuboot")
|
||||
# Node (2) in the above graphic
|
||||
add_custom_command(
|
||||
DEPENDS ${CONFIG_APP_FIRMWARE_UPDATE_IMAGE}
|
||||
OUTPUT ${UPDATE_SIGNED_HEX}
|
||||
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_MCUBOOT_MODULE_DIR}/scripts
|
||||
${PYTHON_EXECUTABLE}
|
||||
${TFM_MCUBOOT_DIR}/scripts/wrapper/wrapper.py
|
||||
--layout "${CMAKE_BINARY_DIR}/tfm/bl2/ext/mcuboot/CMakeFiles/signing_layout_ns.dir/signing_layout_ns.o"
|
||||
-k ${CONFIG_TFM_KEY_FILE_NS}
|
||||
--public-key-format "full"
|
||||
--align 1
|
||||
-v ${CONFIG_APP_FIRMWARE_UPDATE_IMAGE_VERSION}
|
||||
--pad
|
||||
-s auto
|
||||
-H ${CONFIG_ROM_START_OFFSET}
|
||||
${CONFIG_APP_FIRMWARE_UPDATE_IMAGE}
|
||||
${UPDATE_SIGNED_HEX}
|
||||
)
|
||||
|
||||
# Node (3) in the above graphic
|
||||
add_custom_command(
|
||||
OUTPUT ${UPDATE_HEADER_BIN}
|
||||
OUTPUT ${UPDATE_BIN}
|
||||
DEPENDS ${UPDATE_SIGNED_HEX}
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
${CMAKE_CURRENT_LIST_DIR}/split-header.py
|
||||
${UPDATE_SIGNED_HEX}
|
||||
${UPDATE_BIN}
|
||||
${UPDATE_HEADER_BIN}
|
||||
)
|
||||
|
||||
# Node (4) in the above graphic
|
||||
add_custom_command(
|
||||
OUTPUT ${UPDATE_HEADER_OBJ}
|
||||
DEPENDS ${UPDATE_HEADER_BIN}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I binary -O elf32-littlearm -B arm
|
||||
${UPDATE_HEADER_BIN}
|
||||
${UPDATE_HEADER_OBJ}
|
||||
)
|
||||
|
||||
# Node (5) in the above graphic
|
||||
add_custom_command(
|
||||
OUTPUT ${UPDATE_OBJ}
|
||||
DEPENDS ${UPDATE_BIN}
|
||||
COMMAND ${CMAKE_OBJCOPY} -I binary -O elf32-littlearm -B arm
|
||||
${UPDATE_BIN}
|
||||
${UPDATE_OBJ}
|
||||
)
|
||||
|
||||
# Source files in this sample
|
||||
# Node (6) in the above graphic
|
||||
target_sources(app PRIVATE src/main.c ${UPDATE_OBJ} ${UPDATE_HEADER_OBJ})
|
||||
|
||||
target_include_directories(app PRIVATE
|
||||
$<TARGET_PROPERTY:tfm,TFM_BINARY_DIR>/install/interface/include
|
||||
)
|
|
@ -1,27 +0,0 @@
|
|||
# Private config options for PSA firmware application
|
||||
|
||||
# Copyright (c) 2021 Linaro
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
mainmenu "PSA firmware sample application"
|
||||
|
||||
menu "Application configuration"
|
||||
|
||||
module = APP
|
||||
module-str = app
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
endmenu
|
||||
|
||||
config APP_FIRMWARE_UPDATE_IMAGE
|
||||
string "Firmware update image to update to"
|
||||
help
|
||||
This required option specifies the path to an image that this
|
||||
exapmle will update to.
|
||||
default "$(shell, dirname $(filename))/boards/hello-an547.hex" if BOARD_MPS3_AN547
|
||||
|
||||
config APP_FIRMWARE_UPDATE_IMAGE_VERSION
|
||||
string "Version of the new image to update to"
|
||||
default "0.0.2+0"
|
||||
|
||||
source "Kconfig.zephyr"
|
|
@ -1,197 +0,0 @@
|
|||
.. _tfm_psa_firmware:
|
||||
|
||||
TF-M PSA Firmware
|
||||
#################
|
||||
|
||||
Overview
|
||||
********
|
||||
This TF-M integration example demonstrates how to use the PSA Firmware API
|
||||
to retrieve information about the current firmware, or implement a custom
|
||||
firmware update process.
|
||||
|
||||
Trusted Firmware (TF-M) Platform Security Architecture (PSA) APIs
|
||||
are used for the secure processing environment, with Zephyr running in the
|
||||
non-secure processing environment.
|
||||
|
||||
It uses **IPC Mode** for communication, where an IPC mechanism is inserted to
|
||||
handle secure TF-M API calls and responses. The OS-specific code to handle
|
||||
the IPC calls is in ``tfm_ipc.c``.
|
||||
|
||||
TF-M supports three types of firmware upgrade mechanisms:
|
||||
``https://tf-m-user-guide.trustedfirmware.org/docs/technical_references/design_docs/tfm_secure_boot.html#firmware-upgrade-operation``
|
||||
|
||||
This example uses the overwrite firmware upgrade mechanism, in particular, it showcases
|
||||
upgrading the non-secure image which can be built from any other sample in the
|
||||
``zephyr/samples`` directory.
|
||||
|
||||
The sample prints test info to the console either as a single-thread or
|
||||
multi-thread application.
|
||||
|
||||
|
||||
Building and Running
|
||||
********************
|
||||
|
||||
This project needs another firmware as the update payload. It must use another
|
||||
example's hex file, and should be specified on the command line
|
||||
as ``CONFIG_APP_FIRMWARE_UPDATE_IMAGE``.
|
||||
|
||||
To use the ``tfm_integration/tfm_ipc`` sample as the NS firmware update
|
||||
payload, follow the instructions below:
|
||||
|
||||
This sample will only build on a Linux or macOS development system
|
||||
(not Windows), and has been tested on the following setups:
|
||||
|
||||
- macOS Big Sur using QEMU 6.0.0 with gcc-arm-none-eabi-9-2020-q2-update
|
||||
- Linux (NixOS) using QEMU 6.2.0 with gcc from Zephyr SDK 0.14.1
|
||||
- Targets ``MPS3 AN547`` and ``NXP LPCXPRESSO55S69``
|
||||
|
||||
On MPS3 AN547:
|
||||
===============
|
||||
|
||||
Build:
|
||||
======
|
||||
|
||||
1. Build the ``tfm_ipc`` sample with the non-secure board configuration, which will
|
||||
generate the firmware image we'll use in ``psa_firmware`` during the update:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/tfm_integration/tfm_ipc
|
||||
:host-os: unix
|
||||
:board: mps3_an547_ns
|
||||
:goals: build
|
||||
:build-dir: build/tfm_ipc
|
||||
:compact:
|
||||
|
||||
2. Build psa_firmware
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/tfm_integration/psa_firmware
|
||||
:host-os: unix
|
||||
:board: mps3_an547_ns
|
||||
:goals: build
|
||||
:build-dir: build/psa_firmware
|
||||
:gen-args: -DCONFIG_APP_FIRMWARE_UPDATE_IMAGE=\"full/path/to/zephyr/build/tfm_ipc/zephyr/zephyr.hex\"
|
||||
:compact:
|
||||
|
||||
Note:
|
||||
This sample includes a pre-built firmware image (``hello-an547.hex``) in the ``boards``
|
||||
directory. If you don't pass the ``CONFIG_APP_FIRMWARE_UPDATE_IMAGE`` command
|
||||
line argument during step 2 (``-- -DCONFIG_APP_FIRMWARE_UPDATE_IMAGE=...``),
|
||||
this sample will automatically uses the pre-built hex file.
|
||||
|
||||
Run in real target:
|
||||
===================
|
||||
|
||||
1. Copy application binary files (mcuboot.bin and tfm_sign.bin) to
|
||||
``<MPS3 device name>/SOFTWARE/``.
|
||||
|
||||
2. Edit (e.g., with vim) the ``<MPS3 device name>/MB/HBI0263C/AN547/images.txt``
|
||||
file, and update it as shown below:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
TITLE: Versatile Express Images Configuration File
|
||||
|
||||
[IMAGES]
|
||||
TOTALIMAGES: 2 ;Number of Images (Max: 32)
|
||||
|
||||
IMAGE0ADDRESS: 0x10000000
|
||||
IMAGE0FILE: \SOFTWARE\mcuboot.bin ; BL2 bootloader
|
||||
|
||||
IMAGE1ADDRESS: 0x10080000
|
||||
IMAGE1FILE: \SOFTWARE\tfm_sign.bin ; TF-M with application binary blob
|
||||
|
||||
3. Save the file, exit the editor, and reset the MPS3 board.
|
||||
|
||||
Run in QEMU:
|
||||
============
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/tfm_integration/psa_firmware
|
||||
:host-os: unix
|
||||
:board: mps3_an547_ns
|
||||
:goals: run
|
||||
:build-dir: build/psa_firmware
|
||||
:gen-args: -DCONFIG_APP_FIRMWARE_UPDATE_IMAGE=\"full/path/to/zephyr/build/tfm_ipc/zephyr/zephyr.hex\"
|
||||
:compact:
|
||||
|
||||
On LPCxpresso55S69:
|
||||
===================
|
||||
|
||||
1. Build the ``tfm_ipc`` sample with the non-secure board configuration, which will
|
||||
generate the firmware image we'll use in ``psa_firmware`` during the update:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/tfm_integration/tfm_ipc
|
||||
:host-os: unix
|
||||
:board: lpcxpresso55s69_ns
|
||||
:goals: build
|
||||
:build-dir: build/tfm_ipc
|
||||
:compact:
|
||||
|
||||
2. Build psa_firmware:
|
||||
|
||||
.. zephyr-app-commands::
|
||||
:zephyr-app: samples/tfm_integration/psa_firmware
|
||||
:host-os: unix
|
||||
:board: lpcxpresso55s69_ns
|
||||
:goals: build
|
||||
:build-dir: build/psa_firmware
|
||||
:gen-args: -DCONFIG_APP_FIRMWARE_UPDATE_IMAGE=\"full/path/to/zephyr/build/tfm_ipc/zephyr/zephyr.hex\"
|
||||
:compact:
|
||||
|
||||
Make sure your board is set up with :ref:`lpclink2-jlink-onboard-debug-probe`,
|
||||
since this isn't the debug interface boards ship with from the factory;
|
||||
|
||||
Next we need to manually flash the resulting image (``tfm_merged.bin``) with a
|
||||
J-Link as follows:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
JLinkExe -device lpc55s69 -if swd -speed 2000 -autoconnect 1
|
||||
J-Link>r
|
||||
J-Link>erase
|
||||
J-Link>loadfile build/tfm_merged.bin
|
||||
|
||||
Resetting the board and erasing it will unlock the board, this is useful in case
|
||||
it's in an unknown state and can't be flashed.
|
||||
|
||||
We need to reset the board manually after flashing the image to run this code.
|
||||
|
||||
Sample Output
|
||||
=============
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
[INF] Beginning TF-M provisioning
|
||||
[WRN] TFM_DUMMY_PROVISIONING is not suitable for production! This device is NOT SECURE
|
||||
[Sec Thread] Secure image initializing!
|
||||
Booting TF-M v1.6.0+8cffe127
|
||||
Creating an empty ITS flash layout.
|
||||
Creating an empty PS flash layout.
|
||||
*** Booting Zephyr OS build zephyr-v3.1.0-3851-g2bef8051b2fc ***
|
||||
PSA Firmware API test
|
||||
Active S image version: 0.0.3-0
|
||||
Active NS image version: 0.0.1-0
|
||||
Starting FWU; Writing Firmware from 21000000 size 17802 bytes
|
||||
Wrote Firmware; Writing Header from 2100458a size 16 bytes
|
||||
Wrote Header; Installing Image
|
||||
Installed New Firmware; Reboot Needed; Rebooting
|
||||
[WRN] This device was provisioned with dummy keys. This device is NOT SECURE
|
||||
[Sec Thread] Secure image initializing!
|
||||
Booting TF-M v1.6.0+8cffe127
|
||||
*** Booting Zephyr OS build zephyr-v3.1.0-3851-g2bef8051b2fc ***
|
||||
The version of the PSA Framework API is 257.
|
||||
The minor version is 1.
|
||||
Connect success!
|
||||
TF-M IPC on mps3_an547
|
||||
|
||||
Common Problems
|
||||
***************
|
||||
|
||||
Compilation fails with ``Error: Header padding was not requested...``
|
||||
=====================================================================
|
||||
|
||||
This error occurs when passing a signed image to ``CONFIG_APP_FIRMWARE_UPDATE_IMAGE``
|
||||
on the command line, ex: ``zephyr_ns_signed.hex``.
|
||||
Make sure you pass an unsigned, non-secure image (ex. ``zephyr.hex``) to ``CONFIG_APP_FIRMWARE_UPDATE_IMAGE``.
|
File diff suppressed because it is too large
Load diff
|
@ -1,19 +0,0 @@
|
|||
CONFIG_LOG=y
|
||||
CONFIG_LOG_RUNTIME_FILTERING=y
|
||||
CONFIG_LOG_BUFFER_SIZE=2048
|
||||
CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=0
|
||||
CONFIG_LOG_DEFAULT_LEVEL=4
|
||||
|
||||
CONFIG_BUILD_WITH_TFM=y
|
||||
CONFIG_TFM_PROFILE_TYPE_NOT_SET=y
|
||||
CONFIG_TFM_BL2=y
|
||||
CONFIG_TFM_IPC=y
|
||||
CONFIG_TFM_PARTITION_FIRMWARE_UPDATE=y
|
||||
CONFIG_TFM_IMAGE_VERSION_S="0.0.3"
|
||||
CONFIG_TFM_IMAGE_VERSION_NS="0.0.1"
|
||||
|
||||
# The Zephyr CMSIS emulation assumes that ticks are ms, currently
|
||||
CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000
|
||||
|
||||
CONFIG_MAIN_STACK_SIZE=4096
|
||||
CONFIG_HEAP_MEM_POOL_SIZE=4096
|
|
@ -1,35 +0,0 @@
|
|||
sample:
|
||||
description: This app provides an example of using the PSA Firmware calls
|
||||
to update to a new firmware using TF-M and MCUBoot.
|
||||
name: TF-M PSA firmware update example
|
||||
tests:
|
||||
sample.update-success:
|
||||
tags: introduction tfm
|
||||
platform_allow: mps3_an547_ns
|
||||
integration_platforms:
|
||||
- mps3_an547_ns
|
||||
harness: console
|
||||
timeout: 300
|
||||
extra_configs:
|
||||
- CONFIG_APP_FIRMWARE_UPDATE_IMAGE_VERSION="0.0.2+0"
|
||||
harness_config:
|
||||
type: multi_line
|
||||
regex:
|
||||
- "Active NS image version: 0.0.1-0"
|
||||
- "Wrote Header; Installing Image"
|
||||
- "Hello World from UserSpace!"
|
||||
sample.fail-rollback:
|
||||
tags: introduction tfm
|
||||
platform_allow: mps3_an547_ns
|
||||
integration_platforms:
|
||||
- mps3_an547_ns
|
||||
harness: console
|
||||
timeout: 300
|
||||
extra_configs:
|
||||
- CONFIG_APP_FIRMWARE_UPDATE_IMAGE_VERSION="0.0.0+0"
|
||||
harness_config:
|
||||
type: multi_line
|
||||
regex:
|
||||
- "Active NS image version: 0.0.1-0"
|
||||
- "Wrote Header; Installing Image"
|
||||
- "Active NS image version: 0.0.1-0"
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2022, Linaro
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
"""
|
||||
Split a hex file signed by imagetool into its binary/image and
|
||||
its header. This is needed to be able to pack these two parts
|
||||
into the sample separately, saving flash space.
|
||||
"""
|
||||
import argparse
|
||||
|
||||
from intelhex import IntelHex
|
||||
|
||||
def dump_header(infile, image, header):
|
||||
inhex = IntelHex(infile)
|
||||
(start, end) = inhex.segments()[0]
|
||||
inhex.tobinfile(image, start=start, end=end-1)
|
||||
(start, end) = inhex.segments()[-1]
|
||||
inhex.tobinfile(header, start=start, end=end-1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False)
|
||||
parser.add_argument('input')
|
||||
parser.add_argument('image')
|
||||
parser.add_argument('header')
|
||||
args = parser.parse_args()
|
||||
dump_header(args.input, args.image, args.header)
|
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2021 Linaro Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/logging/log_ctrl.h>
|
||||
#include <zephyr/logging/log.h>
|
||||
#include <psa/update.h>
|
||||
|
||||
#include "tfm_ns_interface.h"
|
||||
|
||||
extern uint8_t _binary_update_image_bin_start[];
|
||||
extern uint8_t _binary_update_image_bin_end;
|
||||
extern uint8_t _binary_update_image_bin_size;
|
||||
|
||||
extern uint8_t _binary_update_header_bin_start[];
|
||||
extern uint8_t _binary_update_header_bin_end;
|
||||
extern uint8_t _binary_update_header_bin_size;
|
||||
/*
|
||||
* The _size symbol is particularly bizarre, since it's a length exposed as
|
||||
* a symbol's address, not a variable
|
||||
*/
|
||||
const size_t update_image_size = (size_t) &_binary_update_image_bin_size;
|
||||
const size_t update_header_size = (size_t) &_binary_update_header_bin_size;
|
||||
|
||||
/* Turns out you can't flash blocks that are not a multiple of this */
|
||||
const size_t min_block_size = 512;
|
||||
|
||||
/** Declare a reference to the application logging interface. */
|
||||
LOG_MODULE_DECLARE(app, CONFIG_LOG_DEFAULT_LEVEL);
|
||||
|
||||
bool fwu_query_ver_active(psa_image_id_t image_id, psa_image_info_t *info)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
/* Query the active image. */
|
||||
status = psa_fwu_query(image_id, info);
|
||||
|
||||
/* Get the active image version. State can be one of: */
|
||||
/* PSA_IMAGE_UNDEFINED */
|
||||
/* PSA_IMAGE_CANDIDATE */
|
||||
/* PSA_IMAGE_INSTALLED */
|
||||
/* PSA_IMAGE_REJECTED */
|
||||
/* PSA_IMAGE_PENDING_INSTALL */
|
||||
/* PSA_IMAGE_REBOOT_NEEDED */
|
||||
return info->state == PSA_IMAGE_INSTALLED && status == PSA_SUCCESS;
|
||||
}
|
||||
|
||||
void fwu_disp_ver_active(void)
|
||||
{
|
||||
/* Image type can be one of: */
|
||||
/* FWU_IMAGE_TYPE_NONSECURE */
|
||||
/* FWU_IMAGE_TYPE_SECURE */
|
||||
/* FWU_IMAGE_TYPE_FULL */
|
||||
/* Making the call with FWU_IMAGE_TYPE_FULL will return the information */
|
||||
/* for the full image, which is a combination of the secure and nonsecure */
|
||||
/* images. This is related to the way images are managed in the */
|
||||
/* bootloader. For example, if the secure image and the nonsecure image */
|
||||
/* are combined together and then the combined image is signed and padded */
|
||||
/* with some metadata to generate the final image, then the final */
|
||||
/* generated image is a “full image”. This image management mode is */
|
||||
/* enabled via: */
|
||||
/* -DMCUBOOT_IMAGE_NUMBER=1 */
|
||||
/* If this mode is enabled when building TF-M, then the application */
|
||||
/* should use the “FWU_IMAGE_TYPE_FULL” type when calling the Firmware */
|
||||
/* Update service. */
|
||||
/* If this mode is not enabled, then the application should use the */
|
||||
/* “FWU_IMAGE_TYPE_NONSECURE” or “FWU_IMAGE_TYPE_SECURE” type. */
|
||||
psa_image_id_t image_id = FWU_CALCULATE_IMAGE_ID(FWU_IMAGE_ID_SLOT_ACTIVE,
|
||||
FWU_IMAGE_TYPE_SECURE,
|
||||
0);
|
||||
psa_image_info_t info = { 0 };
|
||||
bool status = fwu_query_ver_active(image_id, &info);
|
||||
|
||||
if (status) {
|
||||
printk("Active S image version: %d.%d.%d-%d\n",
|
||||
info.version.iv_major,
|
||||
info.version.iv_minor,
|
||||
info.version.iv_revision,
|
||||
info.version.iv_build_num);
|
||||
} else {
|
||||
printk("\nUnable to query active secure image version!\n");
|
||||
}
|
||||
|
||||
image_id = FWU_CALCULATE_IMAGE_ID(FWU_IMAGE_ID_SLOT_ACTIVE,
|
||||
FWU_IMAGE_TYPE_NONSECURE,
|
||||
0);
|
||||
status = fwu_query_ver_active(image_id, &info);
|
||||
|
||||
if (status) {
|
||||
printk("Active NS image version: %d.%d.%d-%d\n",
|
||||
info.version.iv_major,
|
||||
info.version.iv_minor,
|
||||
info.version.iv_revision,
|
||||
info.version.iv_build_num);
|
||||
} else {
|
||||
printk("\nUnable to query active nonsecure image version!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a part of a firmware update from the memory pointed to by `cur_block`,
|
||||
* with `size` size, into the `image_id` partition, * at offset `offset`.
|
||||
*/
|
||||
void write_update_part(psa_image_id_t image_id, size_t size, size_t offset, void *cur_block)
|
||||
{
|
||||
size_t coppied = 0;
|
||||
|
||||
while (coppied < size) {
|
||||
size_t next_block_size = PSA_FWU_MAX_BLOCK_SIZE;
|
||||
size_t remainder = size - coppied;
|
||||
|
||||
if (remainder < next_block_size) {
|
||||
next_block_size = remainder;
|
||||
}
|
||||
psa_status_t write_status = psa_fwu_write(
|
||||
image_id,
|
||||
coppied + offset,
|
||||
&((uint8_t *)cur_block)[coppied],
|
||||
next_block_size
|
||||
);
|
||||
|
||||
switch (write_status) {
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
printk("FW Update failed: Invalid Argument\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_INSUFFICIENT_MEMORY:
|
||||
printk("FW Update failed: Insufficient Memory\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_INSUFFICIENT_STORAGE:
|
||||
printk("FW Update failed: Insufficient Storage\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_GENERIC_ERROR:
|
||||
printk("FW Update failed: Generic Error\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_CURRENTLY_INSTALLING:
|
||||
printk("FW Update failed: Currently Installing\n");
|
||||
k_oops();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (write_status != PSA_SUCCESS) {
|
||||
k_oops();
|
||||
}
|
||||
coppied += next_block_size;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a test firmware update
|
||||
*/
|
||||
void update_firmware(void)
|
||||
{
|
||||
uintptr_t size = ((update_image_size + (min_block_size - 1)) / min_block_size)
|
||||
* min_block_size;
|
||||
void *cur_block = &_binary_update_image_bin_start[0];
|
||||
|
||||
printk("Starting FWU; Writing Firmware from %lx size %5ld bytes\n",
|
||||
(uintptr_t) cur_block,
|
||||
(uintptr_t) update_image_size
|
||||
);
|
||||
|
||||
psa_image_id_t image_id = FWU_CALCULATE_IMAGE_ID(FWU_IMAGE_ID_SLOT_STAGE,
|
||||
FWU_IMAGE_TYPE_NONSECURE,
|
||||
0);
|
||||
write_update_part(image_id, size, 0, cur_block);
|
||||
|
||||
size_t header_offset = 0x18000 - update_header_size;
|
||||
|
||||
cur_block = &_binary_update_header_bin_start[0];
|
||||
printk("Wrote Firmware; Writing Header from %lx size %5ld bytes\n",
|
||||
(uintptr_t) cur_block,
|
||||
(uintptr_t) update_header_size
|
||||
);
|
||||
write_update_part(image_id, update_header_size, header_offset, cur_block);
|
||||
|
||||
printk("Wrote Header; Installing Image\n");
|
||||
|
||||
psa_image_id_t uuid;
|
||||
psa_image_version_t version;
|
||||
psa_status_t install_stat = psa_fwu_install(image_id, &uuid, &version);
|
||||
|
||||
switch (install_stat) {
|
||||
case PSA_SUCCESS:
|
||||
case PSA_SUCCESS_REBOOT:
|
||||
break;
|
||||
case PSA_ERROR_INVALID_ARGUMENT:
|
||||
printk("FW Update failed: Invalid Argument\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_INVALID_SIGNATURE:
|
||||
printk("FW Update failed: Invalid Signature\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_GENERIC_ERROR:
|
||||
printk("FW Update failed: Generic Error\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_STORAGE_FAILURE:
|
||||
printk("FW Update failed: Storage Failure\n");
|
||||
k_oops();
|
||||
break;
|
||||
case PSA_ERROR_DEPENDENCY_NEEDED:
|
||||
printk(
|
||||
"FW Update failed: Dependency Needed: uuid: %x version: %d.%d.%d-%d\n",
|
||||
uuid,
|
||||
version.iv_major,
|
||||
version.iv_minor,
|
||||
version.iv_revision,
|
||||
version.iv_build_num
|
||||
);
|
||||
k_oops();
|
||||
break;
|
||||
}
|
||||
|
||||
psa_image_info_t info = { 0 };
|
||||
|
||||
psa_fwu_query(image_id, &info);
|
||||
|
||||
switch (info.state) {
|
||||
case PSA_IMAGE_UNDEFINED:
|
||||
printk("Installed New Firmware; Error: State UNDEFINED\n");
|
||||
break;
|
||||
case PSA_IMAGE_CANDIDATE:
|
||||
printk("Installed New Firmware as Candidate; Rebooting\n");
|
||||
break;
|
||||
case PSA_IMAGE_INSTALLED:
|
||||
printk("Installed New Firmware; Rebooting\n");
|
||||
break;
|
||||
case PSA_IMAGE_REJECTED:
|
||||
printk("Installed New Firmware; Error: Rejected\n");
|
||||
break;
|
||||
case PSA_IMAGE_PENDING_INSTALL:
|
||||
printk("Installed New Firmware pending install; Rebooting\n");
|
||||
break;
|
||||
case PSA_IMAGE_REBOOT_NEEDED:
|
||||
printk("Installed New Firmware; Reboot Needed; Rebooting\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Flush all logs in the deferred mode. */
|
||||
while (IS_ENABLED(CONFIG_LOG_MODE_DEFERRED) && log_data_pending()) {
|
||||
k_msleep(100);
|
||||
}
|
||||
|
||||
psa_fwu_request_reboot();
|
||||
}
|
||||
|
||||
void tfm_ns_interface_init(void);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
/* Initialize the TFM NS interface */
|
||||
tfm_ns_interface_init();
|
||||
|
||||
printk("PSA Firmware API test\n");
|
||||
|
||||
/* Display current firmware version. */
|
||||
fwu_disp_ver_active();
|
||||
|
||||
update_firmware();
|
||||
}
|
Loading…
Reference in a new issue