Commit cba9dcef authored by Mathieu Choplain's avatar Mathieu Choplain Committed by Fabio Baltieri
Browse files

Revert "arch: arm: cortex_m: Add API for scb save and restore"



This reverts commit a90a47b1.

This commit was written with CMSIS 5 in mind, where some Cortex-M cores
have "SHP" in the SCB_Type, and some have "SHPR". This is not correct as
Zephyr is *supposed* to be using CMSIS 6 for Cortex-M... but CI actually
picks up CMSIS 5 instead (it includes both with CMSIS 5 taking priority).

The end result is that Zephyr's CI builds this happily but it causes build
failures on downstream users (e.g., example-application).

Revert the commit now, as it is not used yet by anyone. The revised version
using only "SHPR" shall be reintroduced once the CI issue has been fixed.

Signed-off-by: default avatarMathieu Choplain <mathieu.choplain@st.com>
parent 64131856
Loading
Loading
Loading
Loading
+0 −111
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 * Copyright (c) 2025 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 */
@@ -23,21 +22,6 @@
#include <zephyr/linker/linker-defs.h>
#include <zephyr/cache.h>
#include <zephyr/arch/cache.h>
#include <zephyr/arch/arm/cortex_m/scb.h>

/* For historical reasons, in Cortex-M family, CMSIS code calls System Handler Priority
 * register SHP or SHPR. This code defines the name of the register
 * according to the specific Cortex-M variant.
 */
#if defined(CONFIG_CPU_CORTEX_M0)  || \
	defined(CONFIG_CPU_CORTEX_M0PLUS)  || \
	defined(CONFIG_CPU_CORTEX_M1)  || \
	defined(CONFIG_CPU_CORTEX_M3) || \
	defined(CONFIG_CPU_CORTEX_M4)
#define SHPR_FIELD_NAME SHP
#else
#define SHPR_FIELD_NAME SHPR
#endif

#if defined(CONFIG_CPU_HAS_NXP_SYSMPU)
#include <fsl_sysmpu.h>
@@ -167,98 +151,3 @@ void z_arm_init_arch_hw_at_boot(void)
	barrier_isync_fence_full();
}
#endif /* CONFIG_INIT_ARCH_HW_AT_BOOT */

/**
 * @brief Save essential SCB registers into a provided context structure.
 *
 * This function reads the current values of critical System Control Block (SCB)
 * registers that are safe to backup, and stores them into the `context` structure.
 * Access to SCB registers requires atomicity and consistency, so calling code
 * should guarantee that interrupts are disabled.
 *
 * @param context Pointer to an `scb_context` structure where the register
 * values will be stored. Must not be NULL.
 */
void z_arm_save_scb_context(struct scb_context *context)
{
	__ASSERT_NO_MSG(context != NULL);

#if defined(CONFIG_CPU_CORTEX_M_HAS_VTOR)
	context->vtor  = SCB->VTOR;
#endif
	context->aircr = SCB->AIRCR;
	context->scr   = SCB->SCR;
	context->ccr   = SCB->CCR;

	/* Backup System Handler Priority Registers */
	volatile uint32_t *shpr = (volatile uint32_t *) SCB->SHPR_FIELD_NAME;

	for (int i = 0; i < SHPR_SIZE_W; i++) {
		context->shpr[i] = shpr[i];
	}

	context->shcsr = SCB->SHCSR;
#if defined(CPACR_PRESENT)
	context->cpacr = SCB->CPACR;
#endif /* CPACR_PRESENT */
}

/**
 * @brief Restores essential SCB registers from a provided context structure.
 *
 * This function writes the values from the `context` structure back to the
 * respective System Control Block (SCB) registers. Access to SCB registers
 * requires atomicity and consistency, so calling code should guarantee that
 * interrupts are disabled.
 *
 * @warning The ICSR register is NOT restored directly due to its volatile nature
 * and presence of read-only status bits and write-only clear/set bits.
 * Direct restoration can lead to undefined behavior or corrupt interrupt state.
 * If specific ICSR bits need to be managed as part of a context,
 * a separate, highly controlled mechanism should be implemented.
 *
 * @param context Pointer to a `scb_context` structure containing the
 * register values to be restored. Must not be NULL.
 */
void z_arm_restore_scb_context(const struct scb_context *context)
{
	__ASSERT_NO_MSG(context != NULL);

#if defined(CONFIG_CPU_CORTEX_M_HAS_VTOR)
	/* Restore Vector Table Offset Register first if it was modified. */
	SCB->VTOR = context->vtor;
#endif
	/* Restore AIRCR: Must write the VECTKEY (0x05FA) along with the desired bits.
	 * Ensure only the relevant modifiable bits are restored.
	 */
	SCB->AIRCR = (context->aircr & ~SCB_AIRCR_VECTKEY_Msk) |
					(0x05FAUL << SCB_AIRCR_VECTKEY_Pos);

	SCB->SCR = context->scr;
	SCB->CCR = context->ccr;

	/* Restore System Handler Priority Registers */
	volatile uint32_t *shpr = (volatile uint32_t *) SCB->SHPR_FIELD_NAME;

	for (int i = 0; i < SHPR_SIZE_W; i++) {
		shpr[i] = context->shpr[i];
	}

	/* Restore SHCSR */
	SCB->SHCSR = context->shcsr;

#if defined(CPACR_PRESENT)
	/* Restore CPACR */
	SCB->CPACR = context->cpacr;
#endif /* CPACR_PRESENT */

	/**
	 * Ensure that updates to the SCB are visible by executing a DSB followed by ISB.
	 * This sequence is recommended in the M-profile Architecture Reference Manuals:
	 *   - ARMv6: DDI0419 Issue E - §B2.5 "Barrier support for system correctness"
	 *   - ARMv7: DDI0403 Issue E.e - §A3.7.3 "Memory barriers" (at end of section)
	 *   - ARMv8: DDI0553 Version B.Y - §B7.2.16 "Synchronization requirements [...]"
	 */
	__DSB();
	__ISB();
}
+0 −89
Original line number Diff line number Diff line
/*
 * Copyright (c) 2025 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief System control block context helpers for Cortex-M CPUs
 *
 * System control block context helpers for backup and restore
 */

#ifndef ARM_CORTEX_M_SCB_H_
#define ARM_CORTEX_M_SCB_H_

#include <stdint.h>
#include <cmsis_core.h>

/* Define macros for CPU-conditional features */
#if defined(CONFIG_CPU_CORTEX_M0)  || \
	defined(CONFIG_CPU_CORTEX_M0PLUS)  || \
	defined(CONFIG_CPU_CORTEX_M1) || \
	defined(CONFIG_CPU_CORTEX_M23)
#define SHPR_SIZE_W 2
#else
#define SHPR_SIZE_W 3
#define CPACR_PRESENT 1
#endif

/**
 * @brief Structure to store essential, mutable SCB register values for backup/restore.
 *
 * This structure explicitly lists the SCB registers that are safe and meaningful
 * to backup and restore for common system state management. It avoids volatile,
 * read-only, or write-only status bits that should not be directly restored.
 */
struct scb_context {
#if defined(CONFIG_CPU_CORTEX_M_HAS_VTOR)
	uint32_t vtor;   /*!< offset 0x08, Vector Table Offset Register */
#endif
	uint32_t aircr;  /*!< offset 0x0C, Application Interrupt and Reset Control Register
			  * (only modifiable bits)
			  */
	uint32_t scr;    /*!< offset 0x10, System Control Register */
	uint32_t ccr;    /*!< offset 0x14, Configuration Control Register */
	uint32_t shpr[SHPR_SIZE_W]; /*!< offset 0x18 or 0x1C, System Handler Priority Registers */
	uint32_t shcsr;  /*!< offset 0x24, System Handler Control and State Register */
#if defined(CPACR_PRESENT)
	uint32_t cpacr; /*!< offset 0x88, Coprocessor Access Control Register */
#endif /* CPACR_PRESENT */
};

/**
 * @name SCB Register Backup/Restore Functions
 * @brief Functions for saving and restoring mutable SCB register state.
 * @{
 */

/**
 * @brief Save essential SCB registers into a provided context structure.
 *
 * This function reads the current values of critical System Control Block (SCB)
 * registers that are safe to backup and stores them into the `context` structure.
 *
 * @param context Pointer to an `scb_context` structure where the register
 * values will be stored. Must not be NULL.
 */
void z_arm_save_scb_context(struct scb_context *context);

/**
 * @brief Restores essential SCB registers from a provided context structure.
 *
 * This function writes the values from the `context` structure back to the
 * respective System Control Block (SCB) registers.
 *
 * @warning Extreme caution is advised when restoring SCB registers. Only
 * mutable registers are restored. Specifically, the ICSR register
 * is NOT restored directly due to its volatile nature and read-only/
 * write-only bits.
 *
 * @param context Pointer to a `scb_context` structure containing the
 * register values to be restored. Must not be NULL.
 */
void z_arm_restore_scb_context(const struct scb_context *context);

/** @} */

#endif /* ARM_CORTEX_M_SCB_H_ */