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');

Reply via email to