Skip to content

Commit

Permalink
suit: Added the possibility to halt cores in some cases
Browse files Browse the repository at this point in the history
This commit adds the possibility to stop cores
(and restart them) - however only in the case
if it is the only local core started.

Signed-off-by: Artur Hadasz <[email protected]>
  • Loading branch information
tomchy authored and ahasztag committed Nov 26, 2024
1 parent d0e8f48 commit aa94043
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 4 deletions.
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
74 changes: 71 additions & 3 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,67 @@

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("Cortex core %d is not running - skip CPU halt", cpu_id);
break;
} else {

Check warning on line 57 in subsys/suit/platform/sdfw/src/runners/suit_run_nrf54h20.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

UNNECESSARY_ELSE

subsys/suit/platform/sdfw/src/runners/suit_run_nrf54h20.c:57 else is not generally useful after a break or return
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,9 +87,14 @@ 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%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);
} 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 */
Expand Down Expand Up @@ -59,5 +125,7 @@ suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
return SUIT_PLAT_ERR_CRASH;
}

running_cpus |= BIT(cpu_id);

return SUIT_PLAT_SUCCESS;
}
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
6 changes: 5 additions & 1 deletion subsys/suit/platform/sdfw/src/suit_plat_invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ int suit_plat_invoke(suit_component_t image_handle, struct zcbor_string *invoke_
switch (component_type) {
case SUIT_COMPONENT_TYPE_MEM:
/* memory-mapped */
ret = suit_plat_cpu_run(cpu_id, run_address);
ret = suit_plat_cpu_halt(cpu_id);

if (ret == 0) {
ret = suit_plat_cpu_run(cpu_id, run_address);
}
break;
default:
LOG_ERR("Unsupported component type");
Expand Down

0 comments on commit aa94043

Please sign in to comment.