This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit dd4ce54a123d95b1f1d024006c06d8f8701f85b2 Author: Denis V. Meltsaykin <[email protected]> AuthorDate: Wed Oct 28 17:15:55 2026 +0100 arch/rp23xx: Map the SRAM Shareable so that atomics exclude the other core. Since the per-arch up_testset() was removed, spin_lock() is an LDAEX/STREX exchange. The Cortex-M33 checks an exclusive access with the global exclusive monitor of RP2350 only for Shareable memory, and the default memory map makes the SRAM Non-shareable. The two cores then see only their local monitors: both can take g_cpu_irqlock at once, and run in a critical section together. This corrupted the scheduler: both CPUs took the same task from the ready-to-run list and ran it, and the critical section bookkeeping ended with g_cpu_irqlock held by no CPU, so that both CPUs spun on it and the system hung in the middle of the output of smp or ostest. Map the SRAM, SCRATCH_X and SCRATCH_Y included, as Normal, Non-cacheable, Shareable memory with an MPU region, and keep the default memory map for everything else. The MPU is banked per core, so core 0 sets it up in __start() and core 1 in core1_boot(). Signed-off-by: Denis Meltsaykin <[email protected]> Assisted-By: Claude Opus 5.5 <[email protected]> --- arch/arm/src/rp23xx/rp23xx_cpustart.c | 5 ++ arch/arm/src/rp23xx/rp23xx_mpu.h | 90 +++++++++++++++++++++++++++++++++++ arch/arm/src/rp23xx/rp23xx_start.c | 7 +++ 3 files changed, 102 insertions(+) diff --git a/arch/arm/src/rp23xx/rp23xx_cpustart.c b/arch/arm/src/rp23xx/rp23xx_cpustart.c index 88af83da455..f131bcd20a9 100644 --- a/arch/arm/src/rp23xx/rp23xx_cpustart.c +++ b/arch/arm/src/rp23xx/rp23xx_cpustart.c @@ -40,6 +40,7 @@ #include "sched/sched.h" #include "init/init.h" #include "arm_internal.h" +#include "rp23xx_mpu.h" #include "hardware/rp23xx_memorymap.h" #include "hardware/rp23xx_sio.h" #include "hardware/rp23xx_psm.h" @@ -146,6 +147,10 @@ static void core1_boot(void) arm_fpuconfig(); + /* Let the atomic operations exclude the other core */ + + rp23xx_mpu_share_sram(); + fifo_drain(); /* Setup NVIC */ diff --git a/arch/arm/src/rp23xx/rp23xx_mpu.h b/arch/arm/src/rp23xx/rp23xx_mpu.h new file mode 100644 index 00000000000..70c2172600c --- /dev/null +++ b/arch/arm/src/rp23xx/rp23xx_mpu.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/arm/src/rp23xx/rp23xx_mpu.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_RP23XX_RP23XX_MPU_H +#define __ARCH_ARM_SRC_RP23XX_RP23XX_MPU_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <stdint.h> + +#include "arm_internal.h" +#include "mpu.h" +#include "hardware/rp23xx_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The SRAM, including the SCRATCH_X and SCRATCH_Y banks */ + +#define RP23XX_MPU_SRAM_BASE RP23XX_SRAM_BASE +#define RP23XX_MPU_SRAM_SIZE (520 * 1024) + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rp23xx_mpu_share_sram + * + * Description: + * The Cortex-M33 checks an exclusive access (LDREX/STREX) with the global + * exclusive monitor of RP2350 only when the memory is Shareable. The + * default memory map makes the SRAM Non-shareable, so the two cores see + * only their own local monitors and an atomic operation, a spinlock among + * them, does not exclude the other core. + * + * Map the SRAM as Normal, Non-cacheable, Shareable memory with an MPU + * region and keep the default memory map for everything else. The MPU + * is banked per core, so each core must call this before it relies on an + * atomic operation. + * + ****************************************************************************/ + +static inline void rp23xx_mpu_share_sram(void) +{ + uintptr_t base = RP23XX_MPU_SRAM_BASE; + uintptr_t limit = RP23XX_MPU_SRAM_BASE + RP23XX_MPU_SRAM_SIZE - 1; + + putreg32(0, MPU_CTRL); + UP_MB(); + + /* Attribute index 0: Normal memory, Non-cacheable */ + + modifyreg32(MPU_MAIR0, 0xff, MPU_MAIR_NONCACHEABLE); + + putreg32(0, MPU_RNR); + putreg32((base & MPU_RBAR_BASE_MASK) | MPU_RBAR_SH_OUTER | + MPU_RBAR_AP_RWRW, MPU_RBAR); + putreg32((limit & MPU_RLAR_LIMIT_MASK) | (0 << MPU_RLAR_INDX_SHIFT) | + MPU_RLAR_ENABLE, MPU_RLAR); + + putreg32(MPU_CTRL_ENABLE | MPU_CTRL_PRIVDEFENA, MPU_CTRL); + UP_MB(); +} + +#endif /* __ARCH_ARM_SRC_RP23XX_RP23XX_MPU_H */ diff --git a/arch/arm/src/rp23xx/rp23xx_start.c b/arch/arm/src/rp23xx/rp23xx_start.c index 6ec67f9abff..142317f47a7 100644 --- a/arch/arm/src/rp23xx/rp23xx_start.c +++ b/arch/arm/src/rp23xx/rp23xx_start.c @@ -39,6 +39,7 @@ #include "rp23xx_config.h" #include "rp23xx_clock.h" #include "rp23xx_uart.h" +#include "rp23xx_mpu.h" #include "hardware/rp23xx_sio.h" #ifdef CONFIG_RP23XX_PM_SUSPEND @@ -287,6 +288,12 @@ void __start(void) rp23xx_hwinit(false); +#ifdef CONFIG_SMP + /* Let the atomic operations exclude the other core */ + + rp23xx_mpu_share_sram(); +#endif + /* Then start NuttX */ showprogress('\r');
