k_thread_abort() pends PendSV with SCB->ICSR |= PENDSVSET, the third
such site after arch_swap() and z_arm_exc_exit(). ICSR's writable bits
are write-one-to-set or write-one-to-clear and writing zero is a no-op,
so the read-modify-write is equivalent to a plain store while also
writing back a stale snapshot of the other write-one bits.
This path is not hot, so the motivation is consistency and dropping
that stale write-back rather than the saved access. The SHCSR update
immediately below stays a read-modify-write: its bits are ordinary
read/write ones that have to be preserved.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
arch_swap() and z_arm_exc_exit() pended PendSV with a read-modify-write
of SCB->ICSR. The register's writable bits are all write-one-to-set or
write-one-to-clear and writing zero to them has no effect, so the read
and the OR are pointless: a plain store of PENDSVSET is equivalent and
one memory access shorter on the two hottest exception paths. It also
avoids writing back a stale snapshot of the other write-one bits (for
instance re-pending a SysTick whose pend bit was cleared between the
read and the write, were the sequence ever preempted).
Measured standalone against main (latency_measure in cycles, lower is
better; thread_metric scores, higher is better):
* mps2/an385 (Cortex-M3, QEMU icount):
- latency_measure: mean -1.8% over 47 ops, min/max/median
-5.0/+0.0/-1.1%; k_yield context switch 182 -> 180 cycles.
- thread_metric: cooperative and preemptive +1.1%.
* az3166_iotdevkit (STM32F412, Cortex-M4 @ 96 MHz):
- thread_metric: preemptive +2.0%, cooperative +1.1%.
- latency_measure: ops stay within ±2 cycles of code-placement
noise, min/max/median -2.0/+2.2/+0.0%.
* Flash, az3166 latency_measure image: -8 B at both -Os and -O2.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Clang's default ARM TLS codegen accesses the TLS block through
TPIDRURO (the per-CPU pointer) instead of TPIDRURW, which Zephyr
uses as the TLS base pointer on Cortex-A/R. This produced corrupted
z_tls_current and other thread-local accesses since the wrong base
was used.
Pass -mtp=soft to force calls through Zephyr's own __aeabi_read_tp,
matching the GCC toolchain's target_arm.cmake and Zephyr's TPIDRURW
based TLS mechanism.
Signed-off-by: Chidvilas Yerramsetti <cyerrams@qti.qualcomm.com>
Replace hand-written assembly with CMSIS APIs in the implementation
of USE_SWITCH, as in the review comments for #85248. This should
allow better maintainability and compiler compatibility, and ensure
correctness with respect to instruction barriers.
A small change to include order is needed to avoid errors when the
cmsis_core.h header includes zephyr/irq.h before the
arch/arm/irq.h implementation is included.
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Laurie Fay <Laurie.Fay@arm.com>
The shared Cortex-A/R SMP support (GIC SGI-based scheduler IPIs,
secondary core bring-up via reset-time voting locks) is sufficient to
run SMP on ARMv8-A AArch32. Enabling it only requires selecting the
capability flags SCHED_IPI_SUPPORTED (under SMP) and
ARCH_HAS_DIRECTED_IPIS. Also drop the stale "UP only" note.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
send_ipi() means to skip CPUs whose cpu_map[] entry is not yet
populated, but it compares the sender's MPIDR against INV_MPID
instead of the target's. GET_MPIDR() never returns INV_MPID, so the
guard never fires and an unmapped entry reaches gic_raise_sgi().
Fix this.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
Remove unused extern declarations of offload_routine from cortex_m
and cortex_a_r exception.h as currently there are no users for these.
The global offload_routine (and the irq_offload code that set it to
the offloaded routine and cleared it back to NULL) was introduced by
commit 75caa2b084 ("arm: exception-assisted kernel panic/oops support")
so that _IsInIsr() could tell whether the active SVC was an irq_offload()
call.
On cortex-m, commit 4f11b6f8cf ("arch: arm: re-implement
z_arch_is_in_isr") switched arch_is_in_isr() to read the IPSR and
dropped the offload_routine != NULL check.
On cortex_a_r, the declaration was introduced by commit c30a71df95
("arch: arm: Add Cortex-R support") but it was never referenced.
arch_is_in_isr() derives interrupt context from arch_curr_cpu()->nested.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
The Cortex-A/R cores previously shared the Cortex-M irq_offload
implementation (arch/arm/core/irq_offload.c), which stores the offloaded
routine and parameter in global state and brackets the triggering svc
with k_sched_lock(). This is unsuitable for Cortex-A/R because:
On SMP, CPUs might need to run their offloaded functions at the same
time (for eg. the smp_abort test) so a single global routine/parameter
pair cannot be used. Also, k_sched_lock() is illegal in interrupt context,
so the shared backend cannot honour CONFIG_IRQ_OFFLOAD_NESTED
(irq_offload() called from an ISR, for eg. test_nested_irq_offload test).
Add a dedicated cortex_a_r/irq_offload.c that fixes the above by:
1. keeping the offloaded routine/parameter per-CPU, indexed by
_current_cpu->id, so concurrent CPUs no longer interfere with each
other.
2. using arch_irq_lock()/arch_irq_unlock() instead of k_sched_lock() to
pin the caller to its CPU while the per-CPU slot is written and the
svc is taken, while remaining legal from interrupt context. On
Cortex-A/R the SVC is not masked by CPSR.I. So it still traps with
interrupts locked.
The offloaded routine/parameter are kept in a per-CPU slot rather than
passed in registers (as arm64 does) to keep this change self-contained
in C and to avoid modifying the shared SVC exception entry used for
context switch, oops and syscalls.
Build the new file for Cortex-A/R, and select ARCH_HAS_IRQ_OFFLOAD_NESTED
for CPU_AARCH32_CORTEX_A and CPU_AARCH32_CORTEX_R.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
arch_cpu_start() relied solely on the reset.S voting lock to bring up
secondary cores. That is sufficient only on platforms that release all
cores at reset. On platforms that hold secondaries powered off until
requested (e.g. the Arm FVP Base model), they must be explicitly
powered on with their reset vector pointing at the Zephyr entry point.
Use the generic pm_cpu_on() API to start each secondary at __start.
This dispatches to whichever CPU power driver is enabled. The call is
guarded by CONFIG_PM_CPU_OPS, leaving platforms that release
all cores at reset unaffected.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
arm_cpu_boot_params is populated by the primary core and consumed by
the secondary being brought up. On platforms that start secondaries
cold, the secondary begins executing with its caches and MMU disabled
and reads the parameters directly from main memory.
The primary used sys_cache_data_invd_range() on the structure, which
invalidates the cache lines without writing them back. The freshly
written parameters can therefore be discarded before reaching memory,
leaving the secondary to read stale values (e.g. a wrong MPID).
Use sys_cache_data_flush_range() to write the lines back instead,
followed by a DSB to guarantee the flush has completed before the
secondary is brought up.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
z_arm_mmu_init() runs on every CPU and rebuilds the single, globally
shared L1/L2 page tables on each call. On SMP this is not only
unnecessary duplicate work on the secondary cores (the primary has
already built the tables), but also unsafe. While a secondary core
rebuilds the tables, descriptors that are live and in use by other
cores (the primary or any secondaries with their MMUs enabled) can
temporarily hold invalid values, which can lead to aborts on the
cores using the tables. In practice this manifested as a prefetch
abort on the primary core as soon as a secondary core was brought up
and began (re)building the shared tables.
Fix this by mirroring the arm64 z_arm64_mm_init(is_primary_core)
design: build the tables only on the primary core, in a new
arm_mmu_setup_ptables() helper, and have every core program its MMU
registers and enable translation using the shared tables. As the
page table region's memory attributes are needed while programming
TTBR0, introduce another helper arm_mmu_get_pt_attrs() that is run
by all the cores to look this up.
Also, remove the unused z_arm_mmu_init declaration from
cortex_m/kernel_arch_func.h as that header is included only under
CPU_CORTEX_M.
Single-core behaviour is unchanged.
Signed-off-by: Silesh C V <silesh@alifsemi.com>
arch_irq_lock() and arch_irq_unlock() executed an ISB after every
BASEPRI write on ARMv7-M/ARMv8-M Mainline, and after CPSIE on ARMv6-M/
ARMv8-M Baseline unlock: two pipeline flushes for every kernel critical
section. Neither is architecturally required. Priority-raising MSR
writes are self-synchronizing (Arm DAI 0321A, section 4.8), and on
unlock a pended interrupt is taken within a couple of instructions
anyway; only arch_swap() relies on the pended PendSV being recognized
before the next instruction executes, so it gains an explicit ISB.
Cortex-M7 r0p0/r0p1 keeps the ISB on the raising side, where erratum
440977 (formerly 837070) can delay a priority-raising BASEPRI write. The
CONFIG_CORTEX_M_ERRATUM_440977_WORKAROUND option defaults to y on M7;
the same ISB in the PendSV handler prologue is handled identically.
The ISB occupies the instruction that can still be preempted before the
critical region begins. Retain this existing sequence to avoid masking
higher-priority interrupts through PRIMASK, as Arm's documented
CPSID i/MSR/CPSIE i workaround would do.
Measured standalone against main (latency_measure in cycles, lower is
better; thread_metric scores, higher is better):
* az3166_iotdevkit (STM32F412, Cortex-M4 @ 96 MHz):
- latency_measure: mean -3.3% over 47 ops, min/max/median
-8.1/+0.6/-2.9%; semaphore give no-waiter 74 -> 68 cycles.
- thread_metric: synchronization +15.4%, cooperative +3.3%,
preemptive +4.6%, interrupt +2.9%.
* mps2/an385 (Cortex-M3, QEMU icount):
- latency_measure: mean -3.8%, min/max/median -6.8/+0.0/-3.8%.
- thread_metric: synchronization +8.3%.
* Flash, az3166 latency_measure image: -400 B at -Os, -424 B at -O2.
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
ARM_MPU_REGION_INIT() currently includes the MPU region size in the region
attributes for both Cortex-M and Cortex-R.
On Cortex-M, the region attributes and size are both programmed through
RASR, so this is correct. Cortex-R uses separate registers for region
access attributes and region size. Including the size in the attributes
therefore corrupts the memory type attributes programmed into DRACR.
Store the encoded region size in the dedicated size field for Cortex-R
and exclude it from the region attributes. This fixes devicetree-defined
MPU regions on Cortex-R, where the region size could alter the TEX, S, C,
and B attribute bits.
Signed-off-by: Andrei-Edward Popa <andrei.popa105@yahoo.com>
This changes the error handling of the call chain of both
arch_mem_map() and arch_mem_unmap() in ARM AArch32 to return
errors if possible when actions fail, instead of causing kernel
panic or silently ignoring them. This allows the error code to
be propagated to the caller so it can be handled properly.
arm_mmu_assign_l2_table() previously relied solely on assertions
to catch running out of L2 page tables. With assertions disabled,
it would underflow the free table counter and hand out a table
which is still in use, silently corrupting existing mappings.
It now returns NULL instead, and the failure is propagated up
through arm_mmu_l2_map_page() and its callers as -ENOMEM.
Unsupported cache modes are now rejected with -ENOTSUP instead
of being silently mapped as device memory, and unmapping a page
table entry of an unexpected type is reported as -EFAULT instead
of only being logged. Boot time mappings keep using assertions
as there is no way to recover from those failures.
Both wrappers now invalidate the TLB even if the operation has
failed, since page tables may have been modified before bailing
out.
Assisted-by: Claude:claude-opus-5
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Mirror the arch_mem_map() change and give arch_mem_unmap() the same
treatment: change the prototype to return int instead of void, so
architecture code has a consistent way to report unmapping failures.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Previously arch_mem_map() was a void function, so architecture
code had no consistent way to report mapping failures to callers
other than panicking or asserting. Change arch_mem_map() to
return int.
Note that this mostly maintains the k_panic() calls unless
the error is easy to handle (like invalid arguments). Each
architecture will need to be amended in the future to properly
handle the error conditions. Also some of the users are
converted to do k_panic() after failure. This is to keep
the signature change commit easier to review.
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
During fault handling on the cortex-m, namely ARMV7_M_ARMV8_M_MAINLINE,
some system control registers are modified before reaching
z_fatal_error(). Applications may want to inspect the state of these
registers at time of fault from within k_sys_fatal_error_handler().
- Extend struct __extra_esf_info with the following relevant system
control registers:
- CFSR
- HFSR
- DFSR
- MMFAR
- BFAR
and extend it with the following SAU registers if
CONFIG_ARM_SECURE_FIRMWARE=y
- SFSR
- SFAR
and the following field indicating whether the ESF is from the
non-secure stack
- bool non_secure
- Update z_arm_fault() to snapshot these registers into the esf copy
extra_info before fault handling touches any of them.
- Extend esf_dump() to include these registers in case they are
present. If CONFIG_ARM_SECURE_FIRMWARE=y, the value of the
non_secure member is dumped, preceeding the system registers, to
indicate whether the SCB registers are from the SCB or SCB_NS
instance.
Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>
if the first call to arch_timing_freq_get() happens after
arch_timing_stop(), CYCCNT stays frozen, ddwt is always 0 and the
calibration loop never terminates.
Enable the cycle counter for the measurement and restore its previous
state afterwards.
Signed-off-by: Yiren Guo <guoyr_2013@hotmail.com>
Remove the "zephyr,memory-region-mpu" property, deprecated in Zephyr 3.5
in favor of the "zephyr,memory-attr" bitmask.
The three BUILD_ASSERT tripwires in the ARM/ARM64 MPU drivers already
turned any remaining use of the property into a build failure, so they go
away with it, together with the now unused NODE_HAS_PROP_AND_OR helper.
The migration section in doc/services/mem_mgmt/index.rst documented a
property that no longer exists, so it is dropped and its value mapping
table moved to the 4.5 migration guide.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
Writing RBAR with the VALID bit and the region number set also updates
RNR (Arm v7-M ARM, B3.5.7), so explicitly selecting the region with a
separate RNR write first is only needed on Cortex-R, whose RBAR variant
has no VALID/REGION fields. Move the RNR write into the Cortex-R
branch, saving one MPU register write per programmed region on every
context switch when MPU_STACK_GUARD or USERSPACE is enabled.
Measured standalone against main (latency_measure in cycles, lower is
better; thread_metric scores, higher is better):
* mps2/an385 (Cortex-M3, QEMU icount, instruction-exact):
- latency_measure, stack guard: mean -1.3%, min/max/median
-3.4/+0.0/-0.4%.
- latency_measure, userspace: mean -1.1%, min/max/median
-2.9/+0.0/-0.6%.
- thread_metric, stack guard: cooperative and preemptive +0.5%.
* az3166_iotdevkit (STM32F412, Cortex-M4 @ 96 MHz):
- thread_metric: +0.2–0.3%.
- latency_measure: within the platform's ±2–3% code-placement
noise (stack guard min/max/median -3.2/+2.4/+0.0%).
* Flash, az3166 stack-guard image: -8 B at -Os, +8 B at -O2.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
MISRA C:2012 Rule 8.2 requires every parameter in a function type to be
named, including the parameters of function pointer parameters.
The C++ ABI __cxa_atexit() stub, its local prototype in the ARM
__aeabi_atexit() wrapper and that wrapper itself left the destructor's
parameter unnamed.
Name them after the arguments the documentation or the
definitions already use. No functional change.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Automatically select ARM_GCC_FP_WORKAROUND (renamed to
ARM_FP_CLOBBER_WORKAROUND as the workaround is needed for
clang as well as GCC) whenever CONFIG_FRAME_POINTER is set.
CONFIG_FRAME_POINTER passes -fno-omit-frame-pointer as a
compile flag, forcing frame pointers to be enabled on all
files. Thus the FP workaround is needed to manually
spill/restore r7 around the context switch.
Similarly the workaround is needed if the scheduler is using
a red-black tree, as this uses dynamic stack allocation.
Signed-off-by: Laurie Fay <Laurie.Fay@arm.com>
The AArch32 A-profile support was shared between ARMv7-A and ARMv8-A
AArch32 by threading "defined(CONFIG_ARMV7_A) ||
defined(CONFIG_AARCH32_ARMV8_A)" through every affected site. Each new
A-profile AArch32 variant would have to be added to all of those guards.
Introduce a hidden capability flag, ARM_A_PROFILE_AARCH32, selected by
both ARMV7_A and AARCH32_ARMV8_A, and migrate the shared guards to the
single CONFIG_ARM_A_PROFILE_AARCH32 symbol. Since the flag is selected
by exactly those two symbols, the guards are logically unchanged; a
future A-profile AArch32 variant now only needs to select the flag to
pick up the shared code paths.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Pei Cheng Sung <pc_sung@realtek.com>
Across the tree, I/DCACHE_LINE_SIZE is required at compile-time for
macros, compiler attributes, & linker scripts to function correctly
even if run-time cache line detection is available.
So remove the dependency of ICACHE_LINE_SIZE on
ICACHE_LINE_SIZE_DETECT=n, and of DCACHE_LINE_SIZE on
DCACHE_LINE_SIZE_DETECT=n.
DCACHE_LINE_SIZE_DETECT & ICACHE_LINE_SIZE_DETECT Kconfig options
enable querying some SoC register for finding the i/d-cache line size
at the expense of taking more memory and code and a slightly
increased boot time.
Add new hidden options D/ICACHE_LINE_SIZE_DETECT_SUPPORT only selected
by the software component (arch/SoC layer, driver) implementing the system
cache API.
Signed-off-by: Abderrahmane JARMOUNI <git@jarmouni.me>
USE_SWITCH isn't yet supported for a non-secure Zephyr image on
Cortex-M, as CONFIG_ARM_STORE_EXC_RETURN is not implemented.
Prevent such a non-functional build by only selecting
USE_SWITCH_SUPPORTED if Zephyr is not running as non-secure.
(USE_SWITCH is fine if Zephyr is running as secure or if there
is no security extension.)
Signed-off-by: Laurie Fay <Laurie.Fay@arm.com>
Vendor HAL interrupt handlers are often entered without their vector
number and have to discover it themselves. On Cortex-M the IPSR
register answers that, but on Cortex-A/R with a GIC the INTID exists
only at acknowledge time inside the ISR wrapper. The Renesas RZ SoCs
work around this today by selecting ARM_CUSTOM_INTERRUPT_CONTROLLER
with pass-through z_soc_irq_* wrappers around the standard GIC driver,
purely to intercept the ack/eoi moments and log the INTID into a
fixed-depth side stack for the FSP HAL, duplicated across six SoCs.
Add k_irq_get_active(), backed by arch_irq_get_active(): the
interrupt line whose handler is executing on the current CPU, or
K_IRQ_ACTIVE_NONE outside interrupt context. The capability symbol
ARCH_HAS_IRQ_GET_ACTIVE only promises the query; whether an
architecture reads it from a register or records it in the dispatch
path is its own business.
On Cortex-A/R recording is the only option, so the implementation is
gated behind an arch-level opt-in, ARM_TRACK_ACTIVE_IRQ, keeping the
cost decision where the cost lives: the shared ISR wrapper publishes
the acknowledged INTID in a per-CPU field of _cpu_arch and keeps the
previous value on the exception stack across the dispatch, so nested
interrupts unwind to the preempted INTID and the outermost exit back
to "none". The stored value is biased by one so the zero-initialized
boot state reads as "none" on every CPU without explicit
initialization, including secondary SMP cores. The wrapper records
whatever get_active returned, so it works with both the GIC and a
custom interrupt controller. Cost is zero when the option is off and
a few instructions per interrupt entry and exit when on.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Drivers that need to touch an interrupt's latched pending state
currently reach into the interrupt controller themselves.
NVIC_ClearPendingIRQ() alone appears at 88 call sites across 50 files
under drivers/, NVIC_SetPendingIRQ() at 34 (26 of them in
drivers/counter/, which pends its own IRQ to fire an alarm whose
deadline has already passed) and NVIC_GetPendingIRQ() at 11. Each
site pulls cmsis_core.h and a CONFIG_CPU_CORTEX_M guard into
otherwise portable code, and several counter drivers had already
written private GIC-or-NVIC dispatch helpers for exactly these
operations.
Add k_irq_set_pending(), k_irq_clear_pending() and k_irq_is_pending()
as ALWAYS_INLINE wrappers over matching arch_irq_* functions, and
implement them for the ARM NVIC (AArch32 Cortex-M) and the GIC
(AArch32 Cortex-A/R and AArch64), where the GIC driver already
exported all three as arm_gic_irq_*.
The k_ prefix is deliberate: vendor HAL headers already declare
plain irq_set_pending()/irq_clear_pending() as their own functions
(the Realtek Ameba ROM ABI, pico-sdk's hardware/irq.h), and several
drivers carry private static helpers or API struct members with the
bare names. A namespaced API collides with none of them, needs no
macro tricks, and no renaming of existing code.
The operations are gated on a single capability symbol,
CONFIG_ARCH_HAS_IRQ_PENDING_OPS, so an unported target fails to
build instead of silently doing nothing. Both implemented backends
support all three operations; should an architecture with partial
support materialize (a RISC-V PLIC can report pending state but only
clears it by claiming, and cannot latch from software), the symbol
can be split then.
Assisted-by: Claude:claude-fable-5
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Remove CONFIG_PLATFORM_SPECIFIC_INIT and its z_arm_platform_init() hook,
deprecated in favour of CONFIG_SOC_RESET_HOOK / soc_reset_hook() well
before Zephyr 4.2 and therefore due for removal in 4.5.
The option had no reader left: neither cortex_m/reset.S nor
cortex_a_r/reset.S tests it, both only branch to soc_reset_hook(). Its
single in-tree selector, soc/renode/cortex_r8_virtual, is migrated to
select SOC_RESET_HOOK and its hook renamed to soc_reset_hook(); the body
is unchanged. Note that this re-activates the SCTLR.V clear on that SoC,
which had silently been dead code since the reset paths stopped calling
z_arm_platform_init() - the SoC now again selects the low exception
vector base as originally intended. It runs slightly later in the reset
sequence, after the per-mode stack pointers are set up. This should be
smoke-tested under Renode.
The stale z_arm_platform_init mention in the IAR linker script helper
comment is updated to soc_reset_hook.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
Add 'config CPU_CORTEX_A5' to arch/arm/core/cortex_a_r/Kconfig file.
Set 'GCC_M_CPU' to 'cortex-a5' in cmake/gcc-m-cpu.cmake for the
compiler.
Signed-off-by: Tony Han <tony.han@microchip.com>
The CFSR register uses write-1-to-clear semantics for all fault
status bits per the ARMv7-M/ARMv8-M Architecture Reference Manual.
Two locations in the MemManage and BusFault handlers incorrectly
used `&= ~Msk` (write-0) instead of `= Msk` (write-1), which has
no effect on these sticky bits.
This caused stale VALID bits to persist, leading subsequent fault
handlers to read expired MMFAR/BFAR addresses and potentially
misdiagnose stack overflows.
Fixeszephyrproject-rtos/zephyr#113515
Signed-off-by: Hongquan Li <hongquan.li@processmission.com>
We already determine whether the target is PMSAv8 or (PMSAv6/PMSAv7)
using the selected architecture profile (ARMv6-M/ARMv7-M or ARMv8-M
Baseline/Mainline) and define a symbol accordingly. Make use of that
symbol everywhere instead of repeating CPU checks all over arch code.
While at it, drop the allowlist which generated a build error when the
MPU was enabled on an "unknown" CPU. The header is only included from
SoC-specific code which knows whether an MPU exists or not, or generic
code gated behind CONFIG_ARM_MPU, which guarantees that the MPU exists
as CONFIG_ARM_MPU depends on CONFIG_CPU_HAS_ARM_MPU.
Note: this tangentially fixes a bug that misclassified ARMv8-R targets
as using the PMSAv6/PMSAv7 MPU. This bug did not seem to have any
adverse effect though...
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
The loop loaded s[counter] before checking counter == maxsize, so it
read s[maxsize] when the first maxsize bytes were all non-NUL and
dereferenced s[0] when maxsize == 0, violating the strnlen()
semantics required by arch_user_string_nlen(). The over-read byte
cannot change the returned length, but if it is not accessible the
exception fixup reports a spurious error and callers reject valid
input with EFAULT.
Check the limit before the load instead.
Fixeszephyrproject-rtos/zephyr#113722
Signed-off-by: Hongquan Li <hongquan.li@processmission.com>
This reverts commit c18885e95f:
the issue that this commit worked around was fixed in the
previous commit by preserving the original stack alignment.
Signed-off-by: Laurie Fay <Laurie.Fay@arm.com>
Preserve the alignment indication and rebuild the hardware frame with its
padding word to ensure the stack is always 8-byte aligned when returning
from exception: this is required on Armv8-M.
When an exception is taken with a stack pointer that is not 8-byte
aligned, Armv8-M, and Armv7-M when configured, adds a 4-byte padding word
to align the exception frame. Bit 9 of xPSR records the presence of this
padding.
However, arm_m_switch_to_cpu() does not restore the padding word when
rebuilding the hardware frame. The existing workaround clears the xPSR
alignment bit, which is sufficient on Armv7-M but is invalid on Armv8-M.
Signed-off-by: Laurie Fay <Laurie.Fay@arm.com>
Declare dummy as a read-write output operand, to reflect how it
is used in the assembly block.
The inline assembly overwrites dummy before reading it, but declares the
operand as input-only. The compiler may therefore assume that the backing
register is unchanged and reuse it for another live value, even though the
assembly clobbers it.
Signed-off-by: Laurie Fay <Laurie.Fay@arm.com>
Add a Cortex-M perf backend that samples interrupted context from the
SysTick exception frame.
Install a SysTick wrapper when stack-sampling perf is enabled and
capture the interrupted stack pointer, EXC_RETURN, and r7 on exception
entry. Validate the complete hardware-stacked frame, including optional
alignment padding and extended FP state, against the Thread-mode or
Handler-mode stack before unwinding with arch_stack_walk().
The Arm stack walker uses EHABI unwind tables, so the backend does not
require CONFIG_FRAME_POINTER. Preserve r7 because EHABI unwind recipes
may use it to recover VSP even when frame pointers are not enabled
globally.
Return -EAGAIN when the interrupted context is invalid or unavailable
so the perf core discards that sample without reporting buffer
exhaustion.
Limit the backend to uniprocessor configurations because its captured
sample state is global and remote SMP sampling does not enter the
SysTick wrapper.
Disable the backend for Non-secure Trusted Execution images. A
Non-secure SysTick can be taken while the core executes Secure code,
but Non-secure firmware cannot access the Secure exception frame.
The stack pointer read by the wrapper instead refers to the suspended
Non-secure context, so it cannot be unwound as the interrupted frame.
Sampling across Security states is unsupported.
Signed-off-by: Sudan Landge <sudan.landge@arm.com>
Cortex-M exception frames can be stacked on MSP when execution is
interrupted in handler mode. The Arm EHABI stack walker currently seeds
VSP from the saved PSP unconditionally, which only works for frames
stacked on PSP.
Select the exception frame stack pointer from EXC_RETURN.SPSEL so
MSP-backed frames seed the unwinder from extra_info.msp, while preserving
the existing PSP path. This also allows perf sampling backends to unwind
handler-mode call chains captured on MSP.
Signed-off-by: Sudan Landge <sudan.landge@arm.com>
Otherwise, "warning: implicit declaration of function 'dump_fault'" is
generated, which may be promoted to an error when also using
CONFIG_COMPILER_WARNINGS_AS_ERRORS=y.
Some variables may be unused when the dump_fault isn't called, so mark them
as unused to avoid warnings.
Signed-off-by: Phil Hindman <phindman@xes-inc.com>
Commit 2222fa1426 removed all callers of
the function arm_core_mpu_mem_partition_config_update()... but not the
function itself, which became dead code lingering in tree since then...
Get rid of this function - it has served no purpose for long enough.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
Rename pm_s2ram.S to pm_s2ram_asm.S and update the
Cortex-M source list to reference the new filename.
This avoids generating colliding object paths for the
C and assembly suspend-to-RAM sources when both are
built together.
Assisted-by: GitHub Copilot:GPT-5.4
Signed-off-by: Evan Chen <bugena123@gmail.com>
Code using this header is only built when CONFIG_ARM_MPU=y so it isn't
necessary to gate the header's declarations behind that option.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
`arm_core_mpu_dev.h` is the header describing the API that must be
implemented by drivers compatible with the core. Some functions were
were however accessed using an extern declaration inside the ARM MPU
Core module instead of a declaration in the API header.
Move the offending functions to the API header, making the extern
declaration unnecessary. While at it, also make `z_arm_mpu_init()`
part of the header because it is required, even if not consumed by
the ARM MPU Core module itself.
Signed-off-by: Mathieu Choplain <mathieu.choplain-ext@st.com>
XN on device-type regions only protects mapped regions; unmapped holes
in the MPU map remain reachable through the PRIVDEFENA background map,
both by Cortex-M7 speculative instruction fetches (Cortex-M7 TRM) and
by PLD linefills to faulting addresses (erratum 1013783, SDEN-1068427,
all M7 revisions).
Add opt-in CONFIG_ARM_MPU_CM7_UNMAPPED_REGION to program region 0 as a
4GB Strongly-ordered, no-access, Execute-Never catch-all, as
recommended by the erratum workaround; static regions start from
region 1 and take precedence. Opt-in because the catch-all defeats the
PRIVDEFENA background map: the static MPU region table must explicitly
cover all memory the firmware uses.
Signed-off-by: Lucien Zhao <lucien.zhao@nxp.com>
Header file include/zephyr/sys_clock.h is deprecated and will be removed
someday. Update the whole file tree to include zephyr/sys/clock.h
straight instead of zephyr/sys_clock.h.
This change was made running the sed shell command below:
$ sed -i 's/zephyr\/sys_clock\.h/zephyr\/sys\/clock\.h/' \
`grep -rsl "zephyr/sys_clock\.h" arch/`
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Add support for stacktrace of threads. The shell command
"kernel unwind <thread_ptr>" now works.
Signed-off-by: Mike J. Chen <mjchen@google.com>
Co-authored-by: Filip Kokosinski <fkokosinski@antmicro.com>
Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
Mapping large memory regions at the soc level will consume too
many l2 entries, adding l1 section mapping functionality to
reduce excessive use of l2 entries.
Signed-off-by: CHEN Xing <xing.chen@microchip.com>
arm_cpu_boot_params stack pointer fields used pointer arithmetic on
two-dimensional K_KERNEL_STACK_ARRAY_DECLARE arrays before casting to
char *, producing invalid initialized pointer values.
Use K_KERNEL_STACK_BUFFER() on the CPU 0 stack elements instead,
matching the runtime initialization in arch_cpu_start().
Fixes#113125
Signed-off-by: Hongquan Li <hongquan.li@processmission.com>
z_main_thread is only needed if multithreading is enabled, so move its
definition inside a multithreading check.
Signed-off-by: Josh DeWitt <josh.dewitt@garmin.com>