diff --git a/drivers/firmware/nrf_ironside/CMakeLists.txt b/drivers/firmware/nrf_ironside/CMakeLists.txt index 8f31acfef00..d21a132d67d 100644 --- a/drivers/firmware/nrf_ironside/CMakeLists.txt +++ b/drivers/firmware/nrf_ironside/CMakeLists.txt @@ -6,3 +6,4 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CALL call.c) zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CPUCONF_SERVICE cpuconf.c) +zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_UPDATE_SERVICE update.c) diff --git a/drivers/firmware/nrf_ironside/Kconfig b/drivers/firmware/nrf_ironside/Kconfig index 86c94d3a2ad..97e3604bf72 100644 --- a/drivers/firmware/nrf_ironside/Kconfig +++ b/drivers/firmware/nrf_ironside/Kconfig @@ -37,4 +37,10 @@ config NRF_IRONSIDE_CPUCONF_SERVICE help Service used to boot local domain cores. +config NRF_IRONSIDE_UPDATE_SERVICE + bool "IRONside update service" + select NRF_IRONSIDE_CALL + help + Service used to update the IRONside SE firmware. + endmenu diff --git a/drivers/firmware/nrf_ironside/update.c b/drivers/firmware/nrf_ironside/update.c new file mode 100644 index 00000000000..8de21303b05 --- /dev/null +++ b/drivers/firmware/nrf_ironside/update.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int ironside_update(const struct ironside_update_blob *update) +{ + int err; + struct ironside_call_buf *const buf = ironside_call_alloc(); + + buf->id = IRONSIDE_CALL_ID_UPDATE_SERVICE_V0; + buf->args[IRONSIDE_UPDATE_SERVICE_UPDATE_PTR_IDX] = (uintptr_t)update; + + ironside_call_dispatch(buf); + + if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { + err = buf->args[IRONSIDE_UPDATE_SERVICE_RETCODE_IDX]; + } else { + err = buf->status; + } + + ironside_call_release(buf); + + return err; +} diff --git a/include/zephyr/drivers/firmware/nrf_ironside/update.h b/include/zephyr/drivers/firmware/nrf_ironside/update.h new file mode 100644 index 00000000000..62191b3285b --- /dev/null +++ b/include/zephyr/drivers/firmware/nrf_ironside/update.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_UPDATE_H_ +#define ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_UPDATE_H_ + +#include +#include + +/** + * @name Update service error codes. + * @{ + */ + +/** Caller does not have access to the provided update candidate buffer. */ +#define IRONSIDE_UPDATE_ERROR_NOT_PERMITTED (1) +/** Failed to write the update metadata to SICR. */ +#define IRONSIDE_UPDATE_ERROR_SICR_WRITE_FAILED (2) + +/** + * @} + */ + +/** Length of the update manifest in bytes */ +#define IRONSIDE_UPDATE_MANIFEST_LENGTH (256) +/** Length of the update public key in bytes. */ +#define IRONSIDE_UPDATE_PUBKEY_LENGTH (32) +/** Length of the update signature in bytes. */ +#define IRONSIDE_UPDATE_SIGNATURE_LENGTH (64) + +/* IRONside call identifiers with implicit versions. + * + * With the initial "version 0", the service ABI is allowed to break until the + * first production release of IRONside SE. + */ +#define IRONSIDE_CALL_ID_UPDATE_SERVICE_V0 1 + +/* Index of the update blob pointer within the service buffer. */ +#define IRONSIDE_UPDATE_SERVICE_UPDATE_PTR_IDX (0) +/* Index of the return code within the service buffer. */ +#define IRONSIDE_UPDATE_SERVICE_RETCODE_IDX (0) + +/** + * @brief IRONside update blob. + */ +struct ironside_update_blob { + uint8_t manifest[IRONSIDE_UPDATE_MANIFEST_LENGTH]; + uint8_t pubkey[IRONSIDE_UPDATE_PUBKEY_LENGTH]; + uint8_t signature[IRONSIDE_UPDATE_SIGNATURE_LENGTH]; + uint32_t firmware[]; +}; + +/** + * @brief Request a firmware upgrade of the IRONside SE. + * + * This invokes the IRONside SE update service. The device must be restarted for the update + * to be installed. Check the update status in the application boot report to see if the update + * was successfully installed. + * + * @param update Pointer to update blob + * + * @retval -IRONSIDE_UPDATE_ERROR_NOT_PERMITTED if missing access to the update candidate. + * @retval -IRONSIDE_UPDATE_ERROR_SICR_WRITE_FAILED if writing update parameters to SICR failed. + * @returns Positive non-0 error status if reported by IRONside call. + * @returns 0 on a successful request (although the update itself may still fail). + * + */ +int ironside_update(const struct ironside_update_blob *update); + +#endif /* ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_UPDATE_H_ */