From e02804355d9d79e2c5ecc9b2da1326f3f4449314 Mon Sep 17 00:00:00 2001
From: Terraneo Federico <fede.tft@miosix.org>
Date: Tue, 14 Jan 2025 00:40:30 +0100
Subject: [PATCH] Sharing common code between armv6m and armv7m to support
 processes

---
 .../armv6m/interfaces-impl/userspace_impl.h   | 155 +---------------
 .../armv7m/interfaces-impl/userspace_impl.h   | 167 +-----------------
 .../cortexMx_userspace.cpp}                   |   0
 miosix/arch/cpu/common/cortexMx_userspace.h   | 166 +++++++++++++++++
 miosix/config/Makefile.inc                    |  23 +--
 5 files changed, 180 insertions(+), 331 deletions(-)
 rename miosix/arch/cpu/{armv7m/interfaces-impl/userspace.cpp => common/cortexMx_userspace.cpp} (100%)
 create mode 100644 miosix/arch/cpu/common/cortexMx_userspace.h

diff --git a/miosix/arch/cpu/armv6m/interfaces-impl/userspace_impl.h b/miosix/arch/cpu/armv6m/interfaces-impl/userspace_impl.h
index b0fcfcd8..909798a7 100644
--- a/miosix/arch/cpu/armv6m/interfaces-impl/userspace_impl.h
+++ b/miosix/arch/cpu/armv6m/interfaces-impl/userspace_impl.h
@@ -1,154 +1 @@
-/***************************************************************************
- *   Copyright (C) 2018-2024 by Terraneo Federico                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   As a special exception, if other files instantiate templates or use   *
- *   macros or inline functions from this file, or you compile this file   *
- *   and link it with other works to produce a work based on this file,    *
- *   this file does not by itself cause the resulting work to be covered   *
- *   by the GNU General Public License. However the source code for this   *
- *   file must still be made available in accordance with the GNU General  *
- *   Public License. This exception does not invalidate any other reasons  *
- *   why a work based on this file might be covered by the GNU General     *
- *   Public License.                                                       *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
- ***************************************************************************/
-
-#pragma once
-
-#include "config/miosix_settings.h"
-#include "interfaces/arch_registers.h"
-#include <cassert>
-
-namespace miosix {
-
-#ifdef WITH_PROCESSES
-
-inline void portableSwitchToUserspace()
-{
-    asm volatile("movs r3, #1\n\t"
-                 "svc  0"
-                 :::"r3");
-}
-
-namespace {
-/*
- * ARM syscall parameter mapping
- * Syscall id is r3, saved at registers[3]
- *
- * Parameter 1 is r0, saved at registers[0]
- * Parameter 2 is r1, saved at registers[1]
- * Parameter 3 is r2, saved at registers[2]
- * Parameter 4 is r12, saved at registers[4]
- */
-constexpr unsigned int armSyscallMapping[]={0,1,2,4};
-}
-
-//
-// class SyscallParameters
-//
-
-inline SyscallParameters::SyscallParameters(unsigned int *context) :
-        registers(reinterpret_cast<unsigned int*>(context[0])) {}
-
-inline int SyscallParameters::getSyscallId() const
-{
-    return registers[3];
-}
-
-inline unsigned int SyscallParameters::getParameter(unsigned int index) const
-{
-    assert(index<4);
-    return registers[armSyscallMapping[index]];
-}
-
-inline void SyscallParameters::setParameter(unsigned int index, unsigned int value)
-{
-    assert(index<4);
-    registers[armSyscallMapping[index]]=value;
-}
-
-namespace fault {
-/**
- * \internal
- * Possible kind of faults that the ARM Cortex CPUs can report.
- * They are used to print debug information if a process causes a fault.
- * This is a regular enum enclosed in a namespace instead of an enum class
- * as due to the need to loosely couple fault types for different architectures
- * the arch-independent code uses int to store generic fault types.
- */
-enum FaultType
-{
-    NONE=0,          //Not a fault
-    STACKOVERFLOW=1, //Stack overflow
-    MP=2,            //Process attempted data access outside its memory
-    MP_NOADDR=3,     //Process attempted data access outside its memory (missing addr)
-    MP_XN=4,         //Process attempted code access outside its memory
-    UF_DIVZERO=5,    //Process attempted to divide by zero
-    UF_UNALIGNED=6,  //Process attempted unaligned memory access
-    UF_COPROC=7,     //Process attempted a coprocessor access
-    UF_EXCRET=8,     //Process attempted an exception return
-    UF_EPSR=9,       //Process attempted to access the EPSR
-    UF_UNDEF=10,     //Process attempted to execute an invalid instruction
-    UF_UNEXP=11,     //Unexpected usage fault
-    HARDFAULT=12,    //Hardfault (for example process executed a BKPT instruction)
-    BF=13,           //Busfault
-    BF_NOADDR=14,    //Busfault (missing addr)
-};
-
-} //namespace fault
-
-//
-// class MPUConfiguration
-//
-
-inline void MPUConfiguration::IRQenable()
-{
-    #if __MPU_PRESENT==1
-    MPU->RBAR=regValues[0];
-    MPU->RASR=regValues[1];
-    MPU->RBAR=regValues[2];
-    MPU->RASR=regValues[3];
-    __set_CONTROL(3);
-    #endif //__MPU_PRESENT==1
-}
-
-inline void MPUConfiguration::IRQdisable()
-{
-    #if __MPU_PRESENT==1
-    __set_CONTROL(2);
-    #endif //__MPU_PRESENT==1
-}
-
-#endif //WITH_PROCESSES
-
-inline void IRQenableMPUatBoot()
-{
-    #if __MPU_PRESENT==1
-    MPU->CTRL=MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
-    #endif //__MPU_PRESENT==1
-}
-
-/**
- * \internal
- * Convert a memory region size to a bit pattern that can be written in the MPU
- * registers.
- * On some architectures the MPU is also used to set cacheability regions in the
- * address space, thus this function is useful also when processes are disabled
- * \param size in bytes >32
- * \return a value that can be written to MPU->RASR to represent that size
- */
-unsigned int sizeToMpu(unsigned int size);
-
-} //namespace miosix
+#include "../../common/cortexMx_userspace.h"
diff --git a/miosix/arch/cpu/armv7m/interfaces-impl/userspace_impl.h b/miosix/arch/cpu/armv7m/interfaces-impl/userspace_impl.h
index 3f79c961..909798a7 100644
--- a/miosix/arch/cpu/armv7m/interfaces-impl/userspace_impl.h
+++ b/miosix/arch/cpu/armv7m/interfaces-impl/userspace_impl.h
@@ -1,166 +1 @@
-/***************************************************************************
- *   Copyright (C) 2018-2024 by Terraneo Federico                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   As a special exception, if other files instantiate templates or use   *
- *   macros or inline functions from this file, or you compile this file   *
- *   and link it with other works to produce a work based on this file,    *
- *   this file does not by itself cause the resulting work to be covered   *
- *   by the GNU General Public License. However the source code for this   *
- *   file must still be made available in accordance with the GNU General  *
- *   Public License. This exception does not invalidate any other reasons  *
- *   why a work based on this file might be covered by the GNU General     *
- *   Public License.                                                       *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
- ***************************************************************************/
-
-#pragma once
-
-#include "config/miosix_settings.h"
-#include "interfaces/arch_registers.h"
-#include "interfaces/cpu_const.h"
-#include <cassert>
-
-namespace miosix {
-
-#ifdef WITH_PROCESSES
-
-inline void portableSwitchToUserspace()
-{
-    asm volatile("movs r3, #1\n\t"
-                 "svc  0"
-                 :::"r3");
-}
-
-namespace {
-/*
- * ARM syscall parameter mapping
- * Syscall id is r3, saved at registers[3]
- *
- * Parameter 1 is r0, saved at registers[0]
- * Parameter 2 is r1, saved at registers[1]
- * Parameter 3 is r2, saved at registers[2]
- * Parameter 4 is r12, saved at registers[4]
- */
-constexpr unsigned int armSyscallMapping[]={0,1,2,4};
-}
-
-//
-// class SyscallParameters
-//
-
-inline SyscallParameters::SyscallParameters(unsigned int *context) :
-        registers(reinterpret_cast<unsigned int*>(context[STACK_OFFSET_IN_CTXSAVE])) {}
-
-inline int SyscallParameters::getSyscallId() const
-{
-    return registers[3];
-}
-
-inline unsigned int SyscallParameters::getParameter(unsigned int index) const
-{
-    assert(index<4);
-    return registers[armSyscallMapping[index]];
-}
-
-inline void SyscallParameters::setParameter(unsigned int index, unsigned int value)
-{
-    assert(index<4);
-    registers[armSyscallMapping[index]]=value;
-}
-
-namespace fault {
-/**
- * \internal
- * Possible kind of faults that the ARM Cortex CPUs can report.
- * They are used to print debug information if a process causes a fault.
- * This is a regular enum enclosed in a namespace instead of an enum class
- * as due to the need to loosely couple fault types for different architectures
- * the arch-independent code uses int to store generic fault types.
- */
-enum FaultType
-{
-    NONE=0,          //Not a fault
-    STACKOVERFLOW=1, //Stack overflow
-    MP=2,            //Process attempted data access outside its memory
-    MP_NOADDR=3,     //Process attempted data access outside its memory (missing addr)
-    MP_XN=4,         //Process attempted code access outside its memory
-    MP_STACK=5,      //Process had invalid SP while entering IRQ
-    UF_DIVZERO=6,    //Process attempted to divide by zero
-    UF_UNALIGNED=7,  //Process attempted unaligned memory access
-    UF_COPROC=8,     //Process attempted a coprocessor access
-    UF_EXCRET=9,     //Process attempted an exception return
-    UF_EPSR=10,      //Process attempted to access the EPSR
-    UF_UNDEF=11,     //Process attempted to execute an invalid instruction
-    UF_UNEXP=12,     //Unexpected usage fault
-    HARDFAULT=13,    //Hardfault (for example process executed a BKPT instruction)
-    BF=14,           //Busfault
-    BF_NOADDR=15     //Busfault (missing addr)
-};
-
-} //namespace fault
-
-//
-// class MPUConfiguration
-//
-
-inline void MPUConfiguration::IRQenable()
-{
-    #if __MPU_PRESENT==1
-    MPU->RBAR=regValues[0];
-    MPU->RASR=regValues[1];
-    MPU->RBAR=regValues[2];
-    MPU->RASR=regValues[3];
-    // Set bit 0 of CONTROL register to switch thread mode to unprivileged. When
-    // we'll return from the interrupt the MPU will check the access permissions
-    // for unprivileged processes which only allow access to regions 6 and 7
-    __set_CONTROL(3);
-    #endif //__MPU_PRESENT==1
-}
-
-inline void MPUConfiguration::IRQdisable()
-{
-    #if __MPU_PRESENT==1
-    // Clear bit 0 of CONTROL register to switch thread mode to privileged. When
-    // we'll return from the interrupt the MPU will check the access permissions
-    // for privileged processes which includes the default memory map as we set
-    // MPU_CTRL_PRIVDEFENA at boot plus additional regions to set constraints
-    // such as cacheability. Thus we never truly disable the MPU.
-    __set_CONTROL(2);
-    #endif //__MPU_PRESENT==1
-}
-
-#endif //WITH_PROCESSES
-
-inline void IRQenableMPUatBoot()
-{
-    #if __MPU_PRESENT==1
-    MPU->CTRL = MPU_CTRL_HFNMIENA_Msk
-              | MPU_CTRL_PRIVDEFENA_Msk
-              | MPU_CTRL_ENABLE_Msk;
-    #endif //__MPU_PRESENT==1
-}
-
-/**
- * \internal
- * Convert a memory region size to a bit pattern that can be written in the MPU
- * registers.
- * On some architectures the MPU is also used to set cacheability regions in the
- * address space, thus this function is useful also when processes are disabled
- * \param size in bytes >32
- * \return a value that can be written to MPU->RASR to represent that size
- */
-unsigned int sizeToMpu(unsigned int size);
-
-} //namespace miosix
+#include "../../common/cortexMx_userspace.h"
diff --git a/miosix/arch/cpu/armv7m/interfaces-impl/userspace.cpp b/miosix/arch/cpu/common/cortexMx_userspace.cpp
similarity index 100%
rename from miosix/arch/cpu/armv7m/interfaces-impl/userspace.cpp
rename to miosix/arch/cpu/common/cortexMx_userspace.cpp
diff --git a/miosix/arch/cpu/common/cortexMx_userspace.h b/miosix/arch/cpu/common/cortexMx_userspace.h
new file mode 100644
index 00000000..3f79c961
--- /dev/null
+++ b/miosix/arch/cpu/common/cortexMx_userspace.h
@@ -0,0 +1,166 @@
+/***************************************************************************
+ *   Copyright (C) 2018-2024 by Terraneo Federico                          *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#pragma once
+
+#include "config/miosix_settings.h"
+#include "interfaces/arch_registers.h"
+#include "interfaces/cpu_const.h"
+#include <cassert>
+
+namespace miosix {
+
+#ifdef WITH_PROCESSES
+
+inline void portableSwitchToUserspace()
+{
+    asm volatile("movs r3, #1\n\t"
+                 "svc  0"
+                 :::"r3");
+}
+
+namespace {
+/*
+ * ARM syscall parameter mapping
+ * Syscall id is r3, saved at registers[3]
+ *
+ * Parameter 1 is r0, saved at registers[0]
+ * Parameter 2 is r1, saved at registers[1]
+ * Parameter 3 is r2, saved at registers[2]
+ * Parameter 4 is r12, saved at registers[4]
+ */
+constexpr unsigned int armSyscallMapping[]={0,1,2,4};
+}
+
+//
+// class SyscallParameters
+//
+
+inline SyscallParameters::SyscallParameters(unsigned int *context) :
+        registers(reinterpret_cast<unsigned int*>(context[STACK_OFFSET_IN_CTXSAVE])) {}
+
+inline int SyscallParameters::getSyscallId() const
+{
+    return registers[3];
+}
+
+inline unsigned int SyscallParameters::getParameter(unsigned int index) const
+{
+    assert(index<4);
+    return registers[armSyscallMapping[index]];
+}
+
+inline void SyscallParameters::setParameter(unsigned int index, unsigned int value)
+{
+    assert(index<4);
+    registers[armSyscallMapping[index]]=value;
+}
+
+namespace fault {
+/**
+ * \internal
+ * Possible kind of faults that the ARM Cortex CPUs can report.
+ * They are used to print debug information if a process causes a fault.
+ * This is a regular enum enclosed in a namespace instead of an enum class
+ * as due to the need to loosely couple fault types for different architectures
+ * the arch-independent code uses int to store generic fault types.
+ */
+enum FaultType
+{
+    NONE=0,          //Not a fault
+    STACKOVERFLOW=1, //Stack overflow
+    MP=2,            //Process attempted data access outside its memory
+    MP_NOADDR=3,     //Process attempted data access outside its memory (missing addr)
+    MP_XN=4,         //Process attempted code access outside its memory
+    MP_STACK=5,      //Process had invalid SP while entering IRQ
+    UF_DIVZERO=6,    //Process attempted to divide by zero
+    UF_UNALIGNED=7,  //Process attempted unaligned memory access
+    UF_COPROC=8,     //Process attempted a coprocessor access
+    UF_EXCRET=9,     //Process attempted an exception return
+    UF_EPSR=10,      //Process attempted to access the EPSR
+    UF_UNDEF=11,     //Process attempted to execute an invalid instruction
+    UF_UNEXP=12,     //Unexpected usage fault
+    HARDFAULT=13,    //Hardfault (for example process executed a BKPT instruction)
+    BF=14,           //Busfault
+    BF_NOADDR=15     //Busfault (missing addr)
+};
+
+} //namespace fault
+
+//
+// class MPUConfiguration
+//
+
+inline void MPUConfiguration::IRQenable()
+{
+    #if __MPU_PRESENT==1
+    MPU->RBAR=regValues[0];
+    MPU->RASR=regValues[1];
+    MPU->RBAR=regValues[2];
+    MPU->RASR=regValues[3];
+    // Set bit 0 of CONTROL register to switch thread mode to unprivileged. When
+    // we'll return from the interrupt the MPU will check the access permissions
+    // for unprivileged processes which only allow access to regions 6 and 7
+    __set_CONTROL(3);
+    #endif //__MPU_PRESENT==1
+}
+
+inline void MPUConfiguration::IRQdisable()
+{
+    #if __MPU_PRESENT==1
+    // Clear bit 0 of CONTROL register to switch thread mode to privileged. When
+    // we'll return from the interrupt the MPU will check the access permissions
+    // for privileged processes which includes the default memory map as we set
+    // MPU_CTRL_PRIVDEFENA at boot plus additional regions to set constraints
+    // such as cacheability. Thus we never truly disable the MPU.
+    __set_CONTROL(2);
+    #endif //__MPU_PRESENT==1
+}
+
+#endif //WITH_PROCESSES
+
+inline void IRQenableMPUatBoot()
+{
+    #if __MPU_PRESENT==1
+    MPU->CTRL = MPU_CTRL_HFNMIENA_Msk
+              | MPU_CTRL_PRIVDEFENA_Msk
+              | MPU_CTRL_ENABLE_Msk;
+    #endif //__MPU_PRESENT==1
+}
+
+/**
+ * \internal
+ * Convert a memory region size to a bit pattern that can be written in the MPU
+ * registers.
+ * On some architectures the MPU is also used to set cacheability regions in the
+ * address space, thus this function is useful also when processes are disabled
+ * \param size in bytes >32
+ * \return a value that can be written to MPU->RASR to represent that size
+ */
+unsigned int sizeToMpu(unsigned int size);
+
+} //namespace miosix
diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc
index c10843b4..b90c1742 100644
--- a/miosix/config/Makefile.inc
+++ b/miosix/config/Makefile.inc
@@ -1521,7 +1521,7 @@ else ifeq ($(ARCH),cortexM3_stm32f1)
     ARCH_SRC +=                                           \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp               \
     arch/cpu/common/cortexMx_interrupts.cpp               \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp         \
+    arch/cpu/common/cortexMx_userspace.cpp                \
     arch/common/os_timer/stm32_16bit_os_timer.cpp         \
     arch/common/os_timer/stm32_rtc_os_timer.cpp           \
     arch/common/sleep/cortexMx_sleep.cpp                  \
@@ -1990,7 +1990,7 @@ else ifeq ($(ARCH),cortexM4_stm32f4)
     ARCH_SRC +=                                               \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                   \
     arch/cpu/common/cortexMx_interrupts.cpp                   \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp             \
+    arch/cpu/common/cortexMx_userspace.cpp                    \
     arch/common/os_timer/stm32_32bit_os_timer.cpp             \
     arch/common/sleep/cortexMx_sleep.cpp                      \
     arch/common/drivers/stm32_gpio.cpp                        \
@@ -2276,7 +2276,7 @@ else ifeq ($(ARCH),cortexM3_stm32f2)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/stm32_32bit_os_timer.cpp            \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/stm32_gpio.cpp                       \
@@ -2378,7 +2378,7 @@ else ifeq ($(ARCH),cortexM3_stm32l1)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/stm32_16bit_os_timer.cpp            \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/stm32_gpio.cpp                       \
@@ -2456,7 +2456,7 @@ else ifeq ($(ARCH),cortexM3_efm32gg)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/efm32_gpio.cpp                       \
     arch/common/drivers/efm32_serial.cpp                     \
@@ -2640,7 +2640,7 @@ else ifeq ($(ARCH),cortexM7_stm32f7)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/stm32_32bit_os_timer.cpp            \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/cache/cortexMx_cache.cpp                     \
@@ -2787,7 +2787,7 @@ else ifeq ($(ARCH),cortexM7_stm32h7)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/stm32_32bit_os_timer.cpp            \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/cache/cortexMx_cache.cpp                     \
@@ -2971,7 +2971,7 @@ else ifeq ($(ARCH),cortexM4_stm32f3)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/stm32_32bit_os_timer.cpp            \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/stm32_gpio.cpp                       \
@@ -3073,7 +3073,7 @@ else ifeq ($(ARCH),cortexM4_stm32l4)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/stm32_32bit_os_timer.cpp            \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/stm32_gpio.cpp                       \
@@ -3144,7 +3144,7 @@ else ifeq ($(ARCH),cortexM4_atsam4l)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/atsam4l_os_timer.cpp                \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/serial_atsam4l.cpp                   \
@@ -3207,7 +3207,7 @@ else ifeq ($(ARCH),cortexM3_efm32g)
     ARCH_SRC +=                                              \
     arch/cpu/armv7m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
-    arch/cpu/armv7m/interfaces-impl/userspace.cpp            \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/efm32_os_timer.cpp                  \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/efm32_gpio.cpp                       \
@@ -3381,6 +3381,7 @@ else ifeq ($(ARCH),cortexM0plus_rp2040)
     ARCH_SRC +=                                              \
     arch/cpu/armv6m/interfaces-impl/cpu.cpp                  \
     arch/cpu/common/cortexMx_interrupts.cpp                  \
+    arch/cpu/common/cortexMx_userspace.cpp                   \
     arch/common/os_timer/rp2040_os_timer.cpp                 \
     arch/common/sleep/cortexMx_sleep.cpp                     \
     arch/common/drivers/rp2040_serial.cpp                    \
-- 
GitLab