From 011e3f317f4471bfa366bbd6ab5efc30128f0939 Mon Sep 17 00:00:00 2001 From: Sylwester Konczyk Date: Thu, 31 Oct 2024 15:18:01 +0100 Subject: [PATCH] suit: SDFW update over sdfw_mirror Copy directive checks a location of SDFW/SDFW_Recovery update candidate and tries to install it using sdfw_mirror, if necessary Signed-off-by: Sylwester Konczyk --- .../suit/platform/sdfw/src/suit_plat_copy.c | 112 ++++++++++++++++++ .../suit/platform/sdfw/src/suit_plat_ipuc.c | 2 +- .../utils/include/suit_plat_decode_util.h | 2 +- tests/subsys/suit/check_content/prj.conf | 1 + tests/subsys/suit/copy/prj.conf | 2 + tests/subsys/suit/digest/prj.conf | 1 + tests/subsys/suit/digest_sink/prj.conf | 1 + tests/subsys/suit/fetch/prj.conf | 1 + tests/subsys/suit/integrated_fetch/prj.conf | 1 + tests/subsys/suit/ipuc/prj.conf | 1 + tests/subsys/suit/write/prj.conf | 1 + 11 files changed, 123 insertions(+), 2 deletions(-) diff --git a/subsys/suit/platform/sdfw/src/suit_plat_copy.c b/subsys/suit/platform/sdfw/src/suit_plat_copy.c index e88aed51bc45..23fe90ae6d56 100644 --- a/subsys/suit/platform/sdfw/src/suit_plat_copy.c +++ b/subsys/suit/platform/sdfw/src/suit_plat_copy.c @@ -12,9 +12,11 @@ #include #include #include +#include #if CONFIG_SUIT_IPUC #include +#include #endif /* CONFIG_SUIT_IPUC */ #ifdef CONFIG_SUIT_STREAM @@ -140,6 +142,7 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle, { #ifdef CONFIG_SUIT_STREAM struct stream_sink dst_sink; + uint32_t soc_spec_number = 0; #ifdef CONFIG_SUIT_STREAM_SOURCE_MEMPTR const uint8_t *payload_ptr; size_t payload_size; @@ -167,6 +170,29 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle, return SUIT_ERR_UNSUPPORTED_COMPONENT_ID; } + if (dst_component_type == SUIT_COMPONENT_TYPE_SOC_SPEC) { + struct zcbor_string *component_id = NULL; + + ret = suit_plat_component_id_get(dst_handle, &component_id); + if (ret != SUIT_SUCCESS) { + LOG_ERR("suit_plat_component_id_get failed - error %i", ret); + return ret; + } + + plat_ret = suit_plat_decode_component_number(component_id, &soc_spec_number); + if (plat_ret != SUIT_PLAT_SUCCESS) { + LOG_ERR("suit_plat_decode_component_number failed - error %i", plat_ret); + ret = suit_plat_err_to_processor_err_convert(plat_ret); + return ret; + } + + if (soc_spec_number != SUIT_SECDOM_COMPONENT_NUMBER_SDFW && + soc_spec_number != SUIT_SECDOM_COMPONENT_NUMBER_SDFW_RECOVERY) { + LOG_ERR("Unsupported destination component type"); + return SUIT_ERR_UNSUPPORTED_COMPONENT_ID; + } + } + /* Get source component type based on component handle*/ ret = suit_plat_component_type_get(src_handle, &src_component_type); if (ret != SUIT_SUCCESS) { @@ -250,6 +276,92 @@ int suit_plat_copy(suit_component_t dst_handle, suit_component_t src_handle, } } + if (ret == SUIT_SUCCESS && dst_component_type == SUIT_COMPONENT_TYPE_SOC_SPEC && + (soc_spec_number == SUIT_SECDOM_COMPONENT_NUMBER_SDFW || + soc_spec_number == SUIT_SECDOM_COMPONENT_NUMBER_SDFW_RECOVERY)) { + uintptr_t sdfw_update_area_addr = 0; + size_t sdfw_update_area_size = 0; + + suit_memory_sdfw_update_area_info_get(&sdfw_update_area_addr, + &sdfw_update_area_size); + + if (sdfw_update_area_size > 0) { + /* SoC enforces constrains on update candidate location + */ + if ((uintptr_t)payload_ptr < sdfw_update_area_addr || + (uintptr_t)payload_ptr + payload_size > + sdfw_update_area_addr + sdfw_update_area_size) { + + LOG_WRN("SDFW or SDFW_RECOVERY update - candidate mirror required " + "(%d bytes)", + payload_size); +#ifdef CONFIG_SUIT_IPUC + struct stream_sink mirror_sink; + intptr_t mirror_addr = + suit_plat_ipuc_sdfw_mirror_addr(payload_size); + + if (mirror_addr == 0) { + LOG_ERR("SDFW or SDFW_RECOVERY update - candidate mirror " + "not found"); + ret = suit_plat_err_to_processor_err_convert( + SUIT_PLAT_ERR_NOMEM); + } + + if (ret == SUIT_SUCCESS) { + plat_ret = suit_flash_sink_get( + &mirror_sink, (uint8_t *)mirror_addr, payload_size); + if (plat_ret != SUIT_PLAT_SUCCESS) { + LOG_ERR("Could not acquire SDFW or SDFW_RECOVERY " + "mirror sink: %d", + plat_ret); + ret = suit_plat_err_to_processor_err_convert( + plat_ret); + } + } + + if (ret == SUIT_SUCCESS && mirror_sink.erase != NULL) { + plat_ret = mirror_sink.erase(mirror_sink.ctx); + if (plat_ret != SUIT_PLAT_SUCCESS) { + LOG_ERR("SDFW or SDFW_RECOVERY mirror sink erase " + "failed: %d", + plat_ret); + } + } + + if (ret == SUIT_SUCCESS) { + LOG_INF("Streaming to SDFW or SDFW_RECOVERY mirror sink, " + "%d bytes", + payload_size); + plat_ret = suit_generic_address_streamer_stream( + payload_ptr, payload_size, &mirror_sink); + + if (mirror_sink.flush != NULL) { + mirror_sink.flush(mirror_sink.ctx); + } + + if (mirror_sink.release != NULL) { + mirror_sink.release(mirror_sink.ctx); + } + + if (plat_ret != SUIT_PLAT_SUCCESS) { + LOG_ERR("Streaming to SDFW or SDFW_RECOVERY mirror " + "sink failed: %d", + plat_ret); + ret = suit_plat_err_to_processor_err_convert( + plat_ret); + } + } + + if (ret == SUIT_SUCCESS) { + payload_ptr = (uint8_t *)mirror_addr; + } +#else + ret = suit_plat_err_to_processor_err_convert(SUIT_PLAT_ERR_NOMEM); +#endif + } + } + } + if (ret == SUIT_SUCCESS) { ret = suit_generic_address_streamer_stream(payload_ptr, payload_size, &dst_sink); if (ret != SUIT_PLAT_SUCCESS) { diff --git a/subsys/suit/platform/sdfw/src/suit_plat_ipuc.c b/subsys/suit/platform/sdfw/src/suit_plat_ipuc.c index 03073cd65b54..c981aa46add8 100644 --- a/subsys/suit/platform/sdfw/src/suit_plat_ipuc.c +++ b/subsys/suit/platform/sdfw/src/suit_plat_ipuc.c @@ -183,7 +183,7 @@ suit_plat_err_t suit_plat_ipuc_revoke(suit_component_t handle) intptr_t slot_address = 0; size_t slot_size = 0; - if (suit_plat_decode_address_size(&p_entry->component_id, &slot_address, &slot_size) == + if (suit_plat_decode_address_size(&ipuc_entry->component_id, &slot_address, &slot_size) == SUIT_PLAT_SUCCESS) { LOG_INF("Revoking IPUC, address: %p, size: %d bytes", (void *)slot_address, slot_size); diff --git a/subsys/suit/utils/include/suit_plat_decode_util.h b/subsys/suit/utils/include/suit_plat_decode_util.h index 75a235ac2e41..9eec0a1c9173 100644 --- a/subsys/suit/utils/include/suit_plat_decode_util.h +++ b/subsys/suit/utils/include/suit_plat_decode_util.h @@ -10,7 +10,7 @@ #include #ifdef CONFIG_SUIT_METADATA #include -#endif /* CONFIG_SUIT_METaDATA */ +#endif /* CONFIG_SUIT_METADATA */ #ifdef CONFIG_SUIT_PLATFORM #include #endif /* CONFIG_SUIT_PLATFORM*/ diff --git a/tests/subsys/suit/check_content/prj.conf b/tests/subsys/suit/check_content/prj.conf index 56cf1b4e4928..c34c1dad1cb8 100644 --- a/tests/subsys/suit/check_content/prj.conf +++ b/tests/subsys/suit/check_content/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_STREAM_SINK_DIGEST=y diff --git a/tests/subsys/suit/copy/prj.conf b/tests/subsys/suit/copy/prj.conf index 13e595fdd976..b70813f2efbb 100644 --- a/tests/subsys/suit/copy/prj.conf +++ b/tests/subsys/suit/copy/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_SINK_SELECTOR=y @@ -26,3 +27,4 @@ CONFIG_FLASH=y CONFIG_FLASH_MAP=y CONFIG_SUIT_IPUC=y +CONFIG_MOCK_SDFW_ARBITER=y diff --git a/tests/subsys/suit/digest/prj.conf b/tests/subsys/suit/digest/prj.conf index b7bd1d839a6c..e3afd99ea785 100644 --- a/tests/subsys/suit/digest/prj.conf +++ b/tests/subsys/suit/digest/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_STREAM_SINK_DIGEST=y diff --git a/tests/subsys/suit/digest_sink/prj.conf b/tests/subsys/suit/digest_sink/prj.conf index a5a8b387f2cd..bf38b1adb6dd 100644 --- a/tests/subsys/suit/digest_sink/prj.conf +++ b/tests/subsys/suit/digest_sink/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_STREAM_SINK_DIGEST=y diff --git a/tests/subsys/suit/fetch/prj.conf b/tests/subsys/suit/fetch/prj.conf index 36e16b17990c..b99e62316ace 100644 --- a/tests/subsys/suit/fetch/prj.conf +++ b/tests/subsys/suit/fetch/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_SINK_SELECTOR=y diff --git a/tests/subsys/suit/integrated_fetch/prj.conf b/tests/subsys/suit/integrated_fetch/prj.conf index 44ded7c4da29..9b8d192cdac1 100644 --- a/tests/subsys/suit/integrated_fetch/prj.conf +++ b/tests/subsys/suit/integrated_fetch/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_SINK_SELECTOR=y diff --git a/tests/subsys/suit/ipuc/prj.conf b/tests/subsys/suit/ipuc/prj.conf index 5f9bed4472a5..a21234bde761 100644 --- a/tests/subsys/suit/ipuc/prj.conf +++ b/tests/subsys/suit/ipuc/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_SINK_SELECTOR=y diff --git a/tests/subsys/suit/write/prj.conf b/tests/subsys/suit/write/prj.conf index 6700b234fb3f..2250adf3289d 100644 --- a/tests/subsys/suit/write/prj.conf +++ b/tests/subsys/suit/write/prj.conf @@ -9,6 +9,7 @@ CONFIG_ZTEST=y CONFIG_SUIT=y CONFIG_SUIT_PROCESSOR=y CONFIG_SUIT_PLATFORM=y +CONFIG_SUIT_METADATA=y CONFIG_SUIT_STREAM=y CONFIG_SUIT_SINK_SELECTOR=y