Skip to content

Commit

Permalink
suit: Add API to halt Cortex cores
Browse files Browse the repository at this point in the history
Add internal API that allows to halt Cortex cores.

Ref: NCSDK-29997

Signed-off-by: Tomasz Chyrowicz <[email protected]>
  • Loading branch information
tomchy committed Nov 18, 2024
1 parent 0a046b2 commit 2895a16
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 40 deletions.
30 changes: 25 additions & 5 deletions subsys/suit/platform/sdfw/include/suit_cpu_run.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,41 @@
#ifndef SUIT_PLAT_RUN_CPU_H__
#define SUIT_PLAT_RUN_CPU_H__

#include <suit_platform.h>
#include <suit_plat_err.h>

#ifdef __cplusplus
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.
*
* @note Implementation depends on SoC on which it's built.
*
* @param cpu_id ID of CPU to be started
* @param run_address Start address for given CPU
* @return int 0 in case of success, otherwise error code
* @param[in] cpu_id ID of CPU to be started
* @param[in] run_address Start address for given CPU
*
* @retval SUIT_PLAT_SUCCESS in case of successful start
* @retval SUIT_PLAT_ERR_CRASH if CPU start failed
* @retval SUIT_PLAT_ERR_UNSUPPORTED if handling CPU start is not supported
* @retval SUIT_PLAT_ERR_INVAL if CPU ID is unknown
* @retval SUIT_PLAT_ERR_INCORRECT_STATE if CPU is already started
*/
int suit_plat_cpu_run(uint8_t cpu_id, intptr_t run_address);
suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address);

#ifdef __cplusplus
}
Expand Down
117 changes: 92 additions & 25 deletions subsys/suit/platform/sdfw/src/runners/suit_run_nrf54h20.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,115 @@

#include <suit_cpu_run.h>
#include <zephyr/logging/log.h>
#include <suit_platform_internal.h>
#include <drivers/nrfx_common.h>

#ifdef CONFIG_SDFW_VPRS
#include <sdfw/vprs.h>
#endif /* CONFIG_SDFW_VPRS */

#ifdef CONFIG_SDFW_RESET_HANDLING_ENABLED
#include <sdfw/reset_mgr.h>
#endif /* CONFIG_SDFW_RESET_HANDLING_ENABLED */

LOG_MODULE_REGISTER(suit_plat_run, CONFIG_SUIT_LOG_LEVEL);

int suit_plat_cpu_run(uint8_t cpu_id, intptr_t run_address)
/** 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 */
case NRF_PROCESSOR_RADIOCORE: /* RadioCore */
#ifdef CONFIG_SDFW_RESET_HANDLING_ENABLED
/* Single run address implies no NSVTOR, so keep at reset value of 0x0. */
return reset_mgr_init_and_boot_processor(cpu_id, run_address, 0);
#else
return SUIT_SUCCESS;
if ((running_cpus & BIT(cpu_id)) != 0) {
LOG_INF("Halting Cortex core %d", cpu_id);
ret = reset_mgr_boot_processor(cpu_id, true);
} else {
LOG_INF("Cortex core %d is not running - skip CPU halt", cpu_id);
}
#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;
break;

case NRF_PROCESSOR_SYSCTRL: /* SysCtrl */
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;

case NRF_PROCESSOR_BBPR: { /* BBPR - Baseband Processor */
LOG_ERR("No implementation for BBPR invoke");
return SUIT_ERR_UNSUPPORTED_PARAMETER;
} break;
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;
}

case NRF_PROCESSOR_SYSCTRL: { /* SysCtrl */
suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
{
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("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 */
break;

case NRF_PROCESSOR_SYSCTRL: /* SysCtrl */
#ifdef CONFIG_SDFW_VPRS
LOG_INF("Starting SysCtrl from address 0x%lx", run_address);
return vprs_sysctrl_start((uintptr_t)run_address);
} break;

case NRF_PROCESSOR_PPR: /* PPR(VPR) */
case NRF_PROCESSOR_FLPR: { /* FLPR(VPR) */
LOG_ERR("No implementation for VPR invoke");
return SUIT_ERR_UNSUPPORTED_PARAMETER;
} break;

default: {
LOG_ERR("Unsupported CPU ID");
return SUIT_ERR_UNSUPPORTED_PARAMETER;
ret = vprs_sysctrl_start((uintptr_t)run_address);
#else /* CONFIG_SDFW_VPRS */
LOG_WRN("SysCtrl core handling not supported - skip VPR start");
#endif /* CONFIG_SDFW_VPRS */
break;

case NRF_PROCESSOR_PPR: /* PPR(VPR) */
case NRF_PROCESSOR_FLPR: /* FLPR(VPR) */
LOG_ERR("Application VPR %d start 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 start CPU %d from address 0x%lx (err: %d)", cpu_id, run_address,
ret);
return SUIT_PLAT_ERR_CRASH;
}

running_cpus |= BIT(cpu_id);

return SUIT_PLAT_SUCCESS;
}
30 changes: 20 additions & 10 deletions subsys/suit/platform/sdfw/src/runners/suit_run_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@

#include <suit_cpu_run.h>
#include <zephyr/logging/log.h>
#include <suit_platform_internal.h>
#include <suit_platform.h>

/*
* Meant to be used in integration tests on posix.
* Meant to be used in integration tests on posix.
* May require changes to accommodate other cpu_ids
*/

Expand All @@ -19,18 +17,30 @@

LOG_MODULE_REGISTER(suit_plat_run, CONFIG_SUIT_LOG_LEVEL);

int suit_plat_cpu_run(uint8_t cpu_id, intptr_t run_address)
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 run");
return SUIT_SUCCESS;
} break;
case NRF_PROCESSORPOSIX_2:
LOG_INF("Mock AppCore/RadioCore halt");
return SUIT_PLAT_SUCCESS;

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

suit_plat_err_t suit_plat_cpu_run(uint8_t cpu_id, uintptr_t run_address)
{
switch (cpu_id) {
case NRF_PROCESSORPOSIX_1:
case NRF_PROCESSORPOSIX_2:
LOG_INF("Mock AppCore/RadioCore run");
return SUIT_PLAT_SUCCESS;

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

0 comments on commit 2895a16

Please sign in to comment.