Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

suit: Added the possibility to halt cores in some cases #19079

Merged
merged 1 commit into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions subsys/suit/platform/sdfw/include/suit_cpu_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@
extern "C" {
#endif

/**
* @brief Halt specified CPU.
*
* @note Implementation depends on SoC on which it's built.
*
* @param[in] cpu_id ID of CPU to be halted
*
* @retval SUIT_PLAT_SUCCESS in case of successful halt
* @retval SUIT_PLAT_ERR_CRASH if CPU halt failed
* @retval SUIT_PLAT_ERR_UNSUPPORTED if handling CPU halt is not supported
* @retval SUIT_PLAT_ERR_INVAL if CPU ID is unknown
*/
suit_plat_err_t suit_plat_cpu_halt(uint8_t cpu_id);

/**
* @brief Run specified CPU.
*
Expand Down
94 changes: 87 additions & 7 deletions subsys/suit/platform/sdfw/src/runners/suit_run_nrf54h20.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,66 @@

LOG_MODULE_REGISTER(suit_plat_run, CONFIG_SUIT_LOG_LEVEL);

#define HALTABLE_CPUS (BIT(NRF_PROCESSOR_APPLICATION) | BIT(NRF_PROCESSOR_RADIOCORE))

/** Bitmask indicating, which CPU IDs were invoked.
*
* @note Since it is not possible to invoke the same CPU twice or halt a CPU that
* was not invoked, this value is used to detect those unsupported operations.
*/
static uint32_t running_cpus;

suit_plat_err_t suit_plat_cpu_halt(uint8_t cpu_id)
{
int ret = 0;

switch (cpu_id) {
case NRF_PROCESSOR_APPLICATION: /* AppCore */
case NRF_PROCESSOR_RADIOCORE: /* RadioCore */
#ifdef CONFIG_SDFW_RESET_HANDLING_ENABLED
if ((running_cpus & BIT(cpu_id)) == 0) {
LOG_INF("Cortex core %d is not running - skip CPU halt", cpu_id);
} else if ((running_cpus & HALTABLE_CPUS) == BIT(cpu_id)) {
LOG_INF("Halting CPU %d", cpu_id);
ret = reset_mgr_reset_domains_sync();
} else {
LOG_ERR("Failed to halt CPU %d", cpu_id);
LOG_ERR("Halting single CPU while other CPUs are running is not supported");
return SUIT_PLAT_ERR_UNSUPPORTED;
}
#else /* CONFIG_SDFW_RESET_HANDLING_ENABLED */
LOG_WRN("Cortex core handling not supported - skip CPU %d halt", cpu_id);
#endif /* CONFIG_SDFW_RESET_HANDLING_ENABLED */
break;

case NRF_PROCESSOR_SYSCTRL: /* SysCtrl */
if ((running_cpus & BIT(cpu_id)) == 0) {
LOG_INF("Sysctrl is not running - skip CPU halt");
break;
}
LOG_ERR("Halting SysCtrl is not supported");
return SUIT_PLAT_ERR_UNSUPPORTED;

case NRF_PROCESSOR_PPR: /* PPR(VPR) */
case NRF_PROCESSOR_FLPR: /* FLPR(VPR) */
LOG_ERR("Application VPR %d halt is not supported in SUIT", cpu_id);
return SUIT_PLAT_ERR_UNSUPPORTED;

default:
LOG_ERR("Unsupported CPU ID: %d", cpu_id);
return SUIT_PLAT_ERR_INVAL;
}

if (ret != 0) {
LOG_ERR("Failed to halt CPU %d (err: %d)", cpu_id, ret);
return SUIT_PLAT_ERR_CRASH;
}

running_cpus &= ~BIT(cpu_id);

return SUIT_PLAT_SUCCESS;
}

suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
{
int ret = 0;
Expand All @@ -26,18 +86,29 @@ suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
case NRF_PROCESSOR_APPLICATION: /* AppCore */
case NRF_PROCESSOR_RADIOCORE: /* RadioCore */
#ifdef CONFIG_SDFW_RESET_HANDLING_ENABLED
LOG_INF("Starting Cortex core %d from address 0x%lx", cpu_id, run_address);
/* Single run address implies no NSVTOR, so keep at reset value of 0x0. */
ret = reset_mgr_init_and_boot_processor(cpu_id, run_address, 0);
if ((running_cpus & BIT(cpu_id)) == 0) {
LOG_INF("Starting Cortex core %d from address 0x%p", cpu_id,
(void *) run_address);
/* Single run address implies no NSVTOR, so keep at reset value of 0x0. */
ret = reset_mgr_init_and_boot_processor(cpu_id, run_address, 0);
} else {
LOG_ERR("Cortex core %d is running - fail CPU start", cpu_id);
return SUIT_PLAT_ERR_INCORRECT_STATE;
}
#else /* CONFIG_SDFW_RESET_HANDLING_ENABLED */
LOG_WRN("Cortex core handling not supported - skip CPU %d start", cpu_id);
#endif /* CONFIG_SDFW_RESET_HANDLING_ENABLED */
break;

case NRF_PROCESSOR_SYSCTRL: /* SysCtrl */
#ifdef CONFIG_SDFW_VPRS
LOG_INF("Starting SysCtrl from address 0x%lx", run_address);
ret = vprs_sysctrl_start((uintptr_t)run_address);
if ((running_cpus & BIT(cpu_id)) == 0) {
LOG_INF("Starting SysCtrl from address 0x%p", (void *) run_address);
ret = vprs_sysctrl_start((uintptr_t)run_address);
} else {
LOG_ERR("SysCtrl is already running - fail CPU start");
return SUIT_PLAT_ERR_INCORRECT_STATE;
}
#else /* CONFIG_SDFW_VPRS */
LOG_WRN("SysCtrl core handling not supported - skip VPR start");
#endif /* CONFIG_SDFW_VPRS */
Expand All @@ -54,10 +125,19 @@ suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
}

if (ret != 0) {
LOG_ERR("Failed to start CPU %d from address 0x%lx (err: %d)", cpu_id, run_address,
ret);
LOG_ERR("Failed to start CPU %d from address 0x%p (err: %d)", cpu_id,
(void *) run_address, ret);
return SUIT_PLAT_ERR_CRASH;
}

running_cpus |= BIT(cpu_id);

return SUIT_PLAT_SUCCESS;
}

#ifdef CONFIG_ZTEST
void suit_plat_halt_all_cores_simulate(void)
{
running_cpus = 0;
}
#endif /* CONFIG_ZTEST */
14 changes: 14 additions & 0 deletions subsys/suit/platform/sdfw/src/runners/suit_run_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@

LOG_MODULE_REGISTER(suit_plat_run, CONFIG_SUIT_LOG_LEVEL);

suit_plat_err_t suit_plat_cpu_halt(uint8_t cpu_id)
{
switch (cpu_id) {
case NRF_PROCESSORPOSIX_1:
case NRF_PROCESSORPOSIX_2:
LOG_INF("Mock AppCore/RadioCore halt");
return SUIT_PLAT_SUCCESS;

default:
LOG_ERR("Unsupported CPU ID (%d)", cpu_id);
return SUIT_PLAT_ERR_INVAL;
}
}

suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
{
switch (cpu_id) {
Expand Down
21 changes: 11 additions & 10 deletions subsys/suit/platform/sdfw/src/suit_plat_invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,21 +90,22 @@ int suit_plat_invoke(suit_component_t image_handle, struct zcbor_string *invoke_
return SUIT_ERR_UNSUPPORTED_PARAMETER;
}

if (component_type != SUIT_COMPONENT_TYPE_MEM) {
LOG_ERR("Unsupported component type");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}

ret = suit_plat_cpu_halt(cpu_id);
if (ret != SUIT_PLAT_SUCCESS) {
LOG_ERR("Failed to halt CPU %d", cpu_id);
return SUIT_ERR_CRASH;
}
#ifdef CONFIG_SUIT_EVENTS
/* Clear all pending invoke events */
(void)suit_event_clear(cpu_id, SUIT_EVENT_INVOKE_MASK);
#endif /* CONFIG_SUIT_EVENTS */

/* Check if component type supports invocation */
switch (component_type) {
case SUIT_COMPONENT_TYPE_MEM:
/* memory-mapped */
ret = suit_plat_cpu_run(cpu_id, run_address);
break;
default:
LOG_ERR("Unsupported component type");
return SUIT_ERR_UNSUPPORTED_COMPONENT_ID;
}
ret = suit_plat_cpu_run(cpu_id, run_address);

if ((ret == SUIT_SUCCESS) && synchronous) {
#ifdef CONFIG_SUIT_EVENTS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

#include <zephyr/ztest.h>
#include <mocks.h>
#include <mocks_sdfw.h>
#include <suit_plat_component_compatibility.h>
#include <suit_storage.h>
#include <suit_execution_mode.h>
Expand Down Expand Up @@ -36,7 +36,7 @@ static void *test_suite_setup(void)
static void test_before(void *data)
{
/* Reset mocks */
mocks_reset();
mocks_sdfw_reset();

/* Reset common FFF internal structures */
FFF_RESET_HISTORY();
Expand Down
4 changes: 2 additions & 2 deletions tests/subsys/suit/copy/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <suit_plat_ipuc.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#include <mocks.h>
#include <mocks_sdfw.h>

#define WRITE_ADDR 0x1A00080000

Expand All @@ -22,7 +22,7 @@ static uint8_t test_data[] = {0, 1, 2, 3, 4, 5, 6, 7};
static void test_before(void *data)
{
/* Reset mocks */
mocks_reset();
mocks_sdfw_reset();

/* Reset common FFF internal structures */
FFF_RESET_HISTORY();
Expand Down
4 changes: 2 additions & 2 deletions tests/subsys/suit/fetch/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <suit_platform_internal.h>
#include <suit_plat_ipuc.h>
#include <suit_dfu_cache.h>
#include <mocks.h>
#include <mocks_sdfw.h>

#define TEST_DATA_SIZE 64
#define WRITE_ADDR 0x1A00080000
Expand Down Expand Up @@ -79,7 +79,7 @@ static void setup_cache_with_sample_entries(void)
static void test_before(void *data)
{
/* Reset mocks */
mocks_reset();
mocks_sdfw_reset();

/* Reset common FFF internal structures */
FFF_RESET_HISTORY();
Expand Down
2 changes: 1 addition & 1 deletion tests/subsys/suit/invoke/src/test_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ ZTEST(invoke_tests, test_invoke_NOK_unsupported_cpu_id)
zassert_equal(ret, SUIT_SUCCESS, "create_component_handle failed - error %i", ret);

ret = suit_plat_invoke(handle, NULL);
zassert_equal(ret, SUIT_PLAT_ERR_INVAL,
zassert_equal(ret, SUIT_ERR_CRASH,
"suit_plat_invoke should have failed - unsupported cpu_id");
zassert_equal(SUIT_SUCCESS, suit_plat_release_component_handle(handle),
"Unable to release component handle after test");
Expand Down
4 changes: 2 additions & 2 deletions tests/subsys/suit/ipuc/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <suit_plat_ipuc.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#include <mocks.h>
#include <mocks_sdfw.h>

static uint8_t test_data[] = {0, 1, 2, 3, 4, 5, 6, 7};

Expand All @@ -29,7 +29,7 @@ static struct zcbor_string ipuc_component_id = {
static void test_before(void *data)
{
/* Reset mocks */
mocks_reset();
mocks_sdfw_reset();

/* Reset common FFF internal structures */
FFF_RESET_HISTORY();
Expand Down
2 changes: 1 addition & 1 deletion tests/subsys/suit/mocks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
#

add_subdirectory_ifdef(CONFIG_MOCK_NRFX nrfx)
add_subdirectory_ifdef(CONFIG_MOCK_SDFW_ARBITER sdfw)
add_subdirectory_ifdef(CONFIG_MOCK_SDFW sdfw)
2 changes: 2 additions & 0 deletions tests/subsys/suit/mocks/nrfx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ target_include_directories(suit_nrfx_mocks INTERFACE
if(TARGET zephyr)
target_link_libraries(zephyr_interface INTERFACE suit_nrfx_mocks)
zephyr_library_link_libraries(suit_nrfx_mocks)
elseif(TARGET testbinary)
target_link_libraries(testbinary PRIVATE suit_nrfx_mocks)
else()
message(FATAL_ERROR "Unknown test binary target name")
endif()
14 changes: 14 additions & 0 deletions tests/subsys/suit/mocks/nrfx/include/nrfx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef NRFX_H__
#define NRFX_H__

#include <drivers/nrfx_common.h>

typedef NRF_PROCESSORID_Type nrf_processor_t;

#endif /* NRFX_H__ */
8 changes: 8 additions & 0 deletions tests/subsys/suit/mocks/sdfw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ target_include_directories(suit_sdfw_mocks INTERFACE
if(CONFIG_MOCK_SDFW_ARBITER)
target_compile_options(suit_sdfw_mocks INTERFACE -DCONFIG_SDFW_ARBITER)
endif()
if(CONFIG_MOCK_SDFW_RESET_MGR)
target_compile_options(suit_sdfw_mocks INTERFACE -DCONFIG_SDFW_RESET_HANDLING_ENABLED)
endif()
if(CONFIG_MOCK_SDFW_VPRS)
target_compile_options(suit_sdfw_mocks INTERFACE -DCONFIG_SDFW_VPRS)
endif()

if(TARGET zephyr)
target_link_libraries(zephyr_interface INTERFACE suit_sdfw_mocks)
zephyr_library_link_libraries(suit_sdfw_mocks)
elseif(TARGET testbinary)
target_link_libraries(testbinary PRIVATE suit_sdfw_mocks)
else()
message(FATAL_ERROR "Unknown test binary target name")
endif()
13 changes: 13 additions & 0 deletions tests/subsys/suit/mocks/sdfw/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
#

config MOCK_SDFW
bool

config MOCK_SDFW_ARBITER
bool "Include SDFW arbiter mocks"
select MOCK_SDFW

config MOCK_SDFW_RESET_MGR
bool "Include SDFW reset_mgr mocks"
select MOCK_SDFW

config MOCK_SDFW_VPRS
bool "Include SDFW vprs mocks"
select MOCK_SDFW
24 changes: 24 additions & 0 deletions tests/subsys/suit/mocks/sdfw/include/mock_sdfw_reset_mgr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef MOCK_SDFW_RESET_MGR_H__
#define MOCK_SDFW_RESET_MGR_H__

#include <zephyr/fff.h>
#include <mock_globals.h>

#include <sdfw/reset_mgr.h>

FAKE_VALUE_FUNC(int, reset_mgr_reset_domains_sync);
FAKE_VALUE_FUNC(int, reset_mgr_init_and_boot_processor, nrf_processor_t, uintptr_t, uintptr_t);

static inline void mock_sdfw_reset_mgr_reset(void)
{
RESET_FAKE(reset_mgr_reset_domains_sync);
RESET_FAKE(reset_mgr_init_and_boot_processor);
}

#endif /* MOCK_SDFW_RESET_MGR_H__ */
22 changes: 22 additions & 0 deletions tests/subsys/suit/mocks/sdfw/include/mock_sdfw_vprs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#ifndef MOCK_SDFW_VPRS_H__
#define MOCK_SDFW_VPRS_H__

#include <zephyr/fff.h>
#include <mock_globals.h>

#include <sdfw/vprs.h>

FAKE_VALUE_FUNC(int, vprs_sysctrl_start, uintptr_t);

static inline void mock_sdfw_vprs_reset(void)
{
RESET_FAKE(vprs_sysctrl_start);
}

#endif /* MOCK_SDFW_VPRS_H__ */
Loading