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


The following commit(s) were added to refs/heads/master by this push:
     new 1282b947927 arch/risc-v/rp23xx-rv: Add SMP support for dual Hazard3
1282b947927 is described below

commit 1282b94792767bf40cdb8fb50faf9051db0bda42
Author: Serg Podtynnyi <[email protected]>
AuthorDate: Fri Jun 5 00:01:37 2026 +0700

    arch/risc-v/rp23xx-rv: Add SMP support for dual Hazard3
    
    Add SMP support to rp23xx risc-v port
    
    Signed-off-by: Serg Podtynnyi <[email protected]>
---
 Documentation/platforms/risc-v/rp23xx-rv/index.rst |   2 +-
 arch/risc-v/Kconfig                                |   4 +-
 arch/risc-v/src/common/riscv_cpuinfo.c             |   6 +
 arch/risc-v/src/rp23xx-rv/CMakeLists.txt           |   3 +-
 arch/risc-v/src/rp23xx-rv/Kconfig                  |   3 +
 arch/risc-v/src/rp23xx-rv/Make.defs                |   2 +-
 arch/risc-v/src/rp23xx-rv/chip.h                   |  12 +
 .../risc-v/src/rp23xx-rv/hardware/rp23xx_hazard3.h |   4 +-
 .../src/rp23xx-rv/hardware/rp23xx_memorymap.h      |   2 -
 arch/risc-v/src/rp23xx-rv/hardware/rp23xx_psm.h    |   2 +-
 arch/risc-v/src/rp23xx-rv/hardware/rp23xx_resets.h |   2 +-
 arch/risc-v/src/rp23xx-rv/hardware/rp23xx_sio.h    |   2 +-
 .../src/rp23xx-rv/hardware/rp23xx_usbctrl_dpsram.h |   2 +-
 .../src/rp23xx-rv/hardware/rp23xx_usbctrl_regs.h   |   2 +-
 arch/risc-v/src/rp23xx-rv/rp23xx_cpuidlestack.c    |  93 ------
 arch/risc-v/src/rp23xx-rv/rp23xx_cpustart.c        |  59 ++--
 arch/risc-v/src/rp23xx-rv/rp23xx_head.S            |   5 +-
 arch/risc-v/src/rp23xx-rv/rp23xx_irq.c             |  30 ++
 arch/risc-v/src/rp23xx-rv/rp23xx_smpcall.c         |   4 +-
 arch/risc-v/src/rp23xx-rv/rp23xx_start.c           |   1 -
 arch/risc-v/src/rp23xx-rv/rp23xx_timerisr.c        |  19 ++
 arch/risc-v/src/rp23xx-rv/rp23xx_usbdev.c          | 365 ++++++++++++++-------
 .../configs/{nsh => nsh-smp}/defconfig             |  10 +-
 .../raspberrypi-pico-2-rv/configs/nsh/defconfig    |   7 +-
 .../configs/{usbnsh => usbnsh-smp}/defconfig       |  13 +-
 .../raspberrypi-pico-2-rv/configs/usbnsh/defconfig |  10 +-
 26 files changed, 392 insertions(+), 272 deletions(-)

diff --git a/Documentation/platforms/risc-v/rp23xx-rv/index.rst 
b/Documentation/platforms/risc-v/rp23xx-rv/index.rst
index 01c6aac5ea2..22c5188a3f4 100644
--- a/Documentation/platforms/risc-v/rp23xx-rv/index.rst
+++ b/Documentation/platforms/risc-v/rp23xx-rv/index.rst
@@ -13,7 +13,7 @@ This is RISC-V version of the chip configuration.
 
 This port is experimental and still a work in progress. Use with caution.
 
-SMP (dual core configuration not supported yet)
+SMP is supported, two cores available.
 
 Peripheral Support
 ==================
diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index a721da161db..9d07b61774d 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -448,13 +448,15 @@ config ARCH_CHIP_RP23XX_RV
        select ARCH_RV_ISA_C
        select ARCH_HAVE_RESET
        select ARCH_HAVE_MULTICPU
+       select ARCH_HAVE_MISALIGN_EXCEPTION
        select ARCH_HAVE_I2CRESET
        select ARCH_HAVE_TICKLESS
+       select ARCH_HAVE_DEBUG
+       select RISCV_STRING_FUNCTION
        select ONESHOT
        select ONESHOT_COUNT
        select ONESHOT_FAST_DIVISION
        select ALARM_ARCH
-       select ARCH_HAVE_I2CRESET
        select ARCH_BOARD_COMMON
        ---help---
                Raspberry Pi RP23XX architectures (RISC-V dual Hazard3).
diff --git a/arch/risc-v/src/common/riscv_cpuinfo.c 
b/arch/risc-v/src/common/riscv_cpuinfo.c
index 3d1b8480e0c..aaf9e5170c2 100644
--- a/arch/risc-v/src/common/riscv_cpuinfo.c
+++ b/arch/risc-v/src/common/riscv_cpuinfo.c
@@ -46,6 +46,12 @@ ssize_t up_show_cpuinfo(char *buf, size_t buf_size, off_t 
file_off)
     {
       procfs_sprintf(buf, buf_size, &file_off, "processor\t: %d\n", i);
       procfs_sprintf(buf, buf_size, &file_off, "hart\t\t: %d\n", i);
+      procfs_sprintf(buf, buf_size, &file_off, "BogoMIPS\t: %u.%02u\n",
+                     (CONFIG_BOARD_LOOPSPERMSEC / 1000),
+                     (CONFIG_BOARD_LOOPSPERMSEC / 10) % 100);
+      procfs_sprintf(buf, buf_size, &file_off, "cpu MHz\t\t: %u.%03u\n",
+                     CONFIG_ARCH_CPUINFO_FREQ_KHZ / 1000,
+                     CONFIG_ARCH_CPUINFO_FREQ_KHZ % 1000);
 
       /* ISA */
 
diff --git a/arch/risc-v/src/rp23xx-rv/CMakeLists.txt 
b/arch/risc-v/src/rp23xx-rv/CMakeLists.txt
index 7659ec5cbfa..898cd775f11 100644
--- a/arch/risc-v/src/rp23xx-rv/CMakeLists.txt
+++ b/arch/risc-v/src/rp23xx-rv/CMakeLists.txt
@@ -41,7 +41,8 @@ list(
   rp23xx_pll.c)
 
 if(CONFIG_SMP)
-  list(APPEND SRCS rp23xx_cpustart.c rp23xx_smpcall.c rp23xx_cpuidlestack.c)
+  list(REMOVE_ITEM SRCS riscv_smpcall.c riscv_cpustart.c)
+  list(APPEND SRCS rp23xx_cpustart.c rp23xx_smpcall.c)
 endif()
 
 if(CONFIG_RP23XX_RV_DMAC)
diff --git a/arch/risc-v/src/rp23xx-rv/Kconfig 
b/arch/risc-v/src/rp23xx-rv/Kconfig
index 5ff2509a777..86ae8bff0cc 100644
--- a/arch/risc-v/src/rp23xx-rv/Kconfig
+++ b/arch/risc-v/src/rp23xx-rv/Kconfig
@@ -5,6 +5,9 @@
 
 comment "RP23XX Configuration Options"
 
+config ARCH_RV_ISA_VENDOR_EXTENSIONS
+       default "zba_zbb_zbs_zbkb_zcb_zcmp"
+
 config RP23XX_RV_RP2350B
        bool "Use RP2350B variant (QFN-80)"
        default n
diff --git a/arch/risc-v/src/rp23xx-rv/Make.defs 
b/arch/risc-v/src/rp23xx-rv/Make.defs
index faee3864e6d..5ed35797837 100644
--- a/arch/risc-v/src/rp23xx-rv/Make.defs
+++ b/arch/risc-v/src/rp23xx-rv/Make.defs
@@ -42,9 +42,9 @@ CHIP_CSRCS += rp23xx_xosc.c
 CHIP_CSRCS += rp23xx_pll.c
 
 ifeq ($(CONFIG_SMP),y)
+CMN_CSRCS := $(filter-out riscv_smpcall.c riscv_cpustart.c, $(CMN_CSRCS))
 CHIP_CSRCS += rp23xx_cpustart.c
 CHIP_CSRCS += rp23xx_smpcall.c
-CHIP_CSRCS += rp23xx_cpuidlestack.c
 endif
 
 ifeq ($(CONFIG_RP23XX_RV_DMAC),y)
diff --git a/arch/risc-v/src/rp23xx-rv/chip.h b/arch/risc-v/src/rp23xx-rv/chip.h
index 975d1a87ec1..541b6553136 100644
--- a/arch/risc-v/src/rp23xx-rv/chip.h
+++ b/arch/risc-v/src/rp23xx-rv/chip.h
@@ -37,11 +37,23 @@
 
 #include <arch/rp23xx-rv/chip.h>
 
+#include "riscv_internal.h"
+
 /****************************************************************************
  * Macro Definitions
  ****************************************************************************/
 
 #ifdef __ASSEMBLY__
 
+#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
+.macro  setintstack tmp0, tmp1
+  up_cpu_index \tmp0
+  li    \tmp1, STACKFRAME_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)
+  mul   \tmp1, \tmp0, \tmp1
+  la    \tmp0, g_intstacktop
+  sub   sp, \tmp0, \tmp1
+.endm
+#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 15 */
+
 #endif /* __ASSEMBLY__  */
 #endif /* __ARCH_RISCV_SRC_RP23XX_RV_CHIP_H */
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_hazard3.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_hazard3.h
index ae8bfdb0c1a..e0d040fc8b1 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_hazard3.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_hazard3.h
@@ -27,11 +27,13 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
+#include "rp23xx_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+#define hazard3_block()   __asm__ volatile ("slt x0, x0, x0" ::: "memory")
+#define hazard3_unblock() __asm__ volatile ("slt x0, x0, x1" ::: "memory")
 
 #define hazard3_irqarray_read(csr, index) (READ_AND_SET_CSR(csr, (index)) >> 
16)
 #define hazard3_irqarray_write(csr, index, data) (WRITE_CSR(csr, (index) | 
((uint32_t)(data) << 16)))
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_memorymap.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_memorymap.h
index cfbf668803c..7446fe301f9 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_memorymap.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_memorymap.h
@@ -26,8 +26,6 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
-
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_psm.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_psm.h
index e31a12408e8..725f8e5baed 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_psm.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_psm.h
@@ -27,7 +27,7 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
+#include "rp23xx_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_resets.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_resets.h
index 0f8f7020f78..a39d5b52209 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_resets.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_resets.h
@@ -27,7 +27,7 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
+#include "rp23xx_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_sio.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_sio.h
index c4bc859e6a1..60efe7c38c9 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_sio.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_sio.h
@@ -27,7 +27,7 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
+#include "rp23xx_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_dpsram.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_dpsram.h
index ed6f8569aeb..df941b7a213 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_dpsram.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_dpsram.h
@@ -27,7 +27,7 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
+#include "rp23xx_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
diff --git a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_regs.h 
b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_regs.h
index 31ac8085fae..4390de3b1e4 100644
--- a/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_regs.h
+++ b/arch/risc-v/src/rp23xx-rv/hardware/rp23xx_usbctrl_regs.h
@@ -27,7 +27,7 @@
  * Included Files
  ****************************************************************************/
 
-#include "hardware/rp23xx_memorymap.h"
+#include "rp23xx_memorymap.h"
 
 /****************************************************************************
  * Pre-processor Definitions
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_cpuidlestack.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_cpuidlestack.c
deleted file mode 100644
index 62e3de7cdbe..00000000000
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_cpuidlestack.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************
- * arch/risc-v/src/rp23xx-rv/rp23xx_cpuidlestack.c
- *
- * 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.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <sys/types.h>
-
-#include <nuttx/arch.h>
-#include <nuttx/sched.h>
-
-#include "riscv_internal.h"
-
-#ifdef CONFIG_SMP
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_cpu_idlestack
- *
- * Description:
- *   Allocate a stack for the CPU[n] IDLE task (n > 0) if appropriate and
- *   setup up stack-related information in the IDLE task's TCB.  This
- *   function is always called before up_cpu_start().  This function is
- *   only called for the CPU's initial IDLE task; up_create_task is used for
- *   all normal tasks, pthreads, and kernel threads for all CPUs.
- *
- *   The initial IDLE task is a special case because the CPUs can be started
- *   in different wans in different environments:
- *
- *   1. The CPU may already have been started and waiting in a low power
- *      state for up_cpu_start().  In this case, the IDLE thread's stack
- *      has already been allocated and is already in use.  Here
- *      up_cpu_idlestack() only has to provide information about the
- *      already allocated stack.
- *
- *   2. The CPU may be disabled but started when up_cpu_start() is called.
- *      In this case, a new stack will need to be created for the IDLE
- *      thread and this function is then equivalent to:
- *
- *      return up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL);
- *
- *   The following TCB fields must be initialized by this function:
- *
- *   - adj_stack_size: Stack size after adjustment for hardware, processor,
- *     etc.  This value is retained only for debug purposes.
- *   - stack_alloc_ptr: Pointer to allocated stack
- *   - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
- *     Arguments has been removed from the stack allocation.
- *
- * Input Parameters:
- *   - cpu:         CPU index that indicates which CPU the IDLE task is
- *                  being created for.
- *   - tcb:         The TCB of new CPU IDLE task
- *   - stack_size:  The requested stack size for the IDLE task.  At least
- *                  this much must be allocated.  This should be
- *                  CONFIG_SMP_STACK_SIZE.
- *
- ****************************************************************************/
-
-int up_cpu_idlestack(int cpu, struct tcb_s *tcb, size_t stack_size)
-{
-#if CONFIG_SMP_NCPUS > 1
-  up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL);
-#endif
-  return OK;
-}
-
-#endif /* CONFIG_SMP */
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_cpustart.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_cpustart.c
index 9d0b4db808f..493ba5e9fd7 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_cpustart.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_cpustart.c
@@ -26,21 +26,15 @@
 
 #include <nuttx/config.h>
 
-#include <stdint.h>
-#include <assert.h>
 #include <nuttx/debug.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
 
 #include <nuttx/arch.h>
+#include <nuttx/init.h>
 #include <nuttx/sched_note.h>
 
-#include "nvic.h"
 #include "sched/sched.h"
 #include "init/init.h"
-#include "riscv_internal.h"
-#include "hardware/rp23xx_memorymap.h"
+#include "hardware/rp23xx_hazard3.h"
 #include "hardware/rp23xx_sio.h"
 #include "hardware/rp23xx_psm.h"
 
@@ -62,14 +56,14 @@
 #  define showprogress(c)
 #endif
 
+#define CORE1_BOOT_MSG_LEN  6
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
 
 static volatile bool g_core1_boot;
 
-extern int rp23xx_smp_call_handler(int irq, void *c, void *arg);
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -90,7 +84,7 @@ static void fifo_drain(void)
       getreg32(RP23XX_SIO_FIFO_RD);
     }
 
-  __asm__ volatile ("sev");
+  hazard3_unblock();
 }
 
 /****************************************************************************
@@ -114,14 +108,14 @@ static int fifo_comm(uint32_t msg)
   while (!(getreg32(RP23XX_SIO_FIFO_ST) & RP23XX_SIO_FIFO_ST_RDY))
     ;
   putreg32(msg, RP23XX_SIO_FIFO_WR);
-  __asm__ volatile ("sev");
+  hazard3_unblock();
 
   while (!(getreg32(RP23XX_SIO_FIFO_ST) & RP23XX_SIO_FIFO_ST_VLD))
-    __asm__ volatile ("wfe");
+  hazard3_block();
 
   rcv = getreg32(RP23XX_SIO_FIFO_RD);
 
-  return msg == rcv;
+  return (msg == rcv);
 }
 
 /****************************************************************************
@@ -138,25 +132,23 @@ static int fifo_comm(uint32_t msg)
 
 static void core1_boot(void)
 {
-#if CONFIG_ARCH_INTERRUPTSTACK > 3
-  /* Initializes the stack pointer */
-
-  riscv_initialize_stack();
-#endif
-
   fifo_drain();
 
-  /* Setup NVIC */
-
   up_irqinitialize();
 
+  /* Per-core timer: enable MTIMER interrupt */
+
+  up_timer_initialize();
+
   /* Enable inter-processor FIFO interrupt */
 
-  irq_attach(RP23XX_SIO_IRQ_FIFO, rp23xx_smp_call_handler, NULL);
+  irq_attach(RP23XX_SIO_IRQ_FIFO, riscv_smp_call_handler, NULL);
   up_enable_irq(RP23XX_SIO_IRQ_FIFO);
 
   g_core1_boot = true;
 
+  UP_DMB();
+
 #ifdef CONFIG_SCHED_INSTRUMENTATION
   /* Notify that this CPU has started */
 
@@ -203,7 +195,7 @@ int up_cpu_start(int cpu)
 {
   int i;
   struct tcb_s *tcb = current_task(cpu);
-  uint32_t core1_boot_msg[5];
+  uint32_t core1_boot_msg[CORE1_BOOT_MSG_LEN];
 
   DPRINTF("cpu=%d\n", cpu);
 
@@ -220,19 +212,18 @@ int up_cpu_start(int cpu)
     ;
   clrbits_reg32(RP23XX_PSM_PROC1, RP23XX_PSM_FRCE_OFF);
 
-  /* Send initial VTOR, MSP, PC for Core 1 boot */
-
   core1_boot_msg[0] = 0;
-  core1_boot_msg[1] = 1;
-  core1_boot_msg[2] = getreg32(NVIC_VECTAB);
-  core1_boot_msg[3] = (uint32_t)tcb->stack_base_ptr +
+  core1_boot_msg[1] = 0;
+  core1_boot_msg[2] = 1;
+  core1_boot_msg[3] = READ_CSR(CSR_MTVEC);
+  core1_boot_msg[4] = (uint32_t)tcb->stack_base_ptr +
                                 tcb->adj_stack_size;
-  core1_boot_msg[4] = (uint32_t)core1_boot;
+  core1_boot_msg[5] = (uint32_t)core1_boot;
 
   do
     {
       fifo_drain();
-      for (i = 0; i < 5; i++)
+      for (i = 0; i < CORE1_BOOT_MSG_LEN; i++)
         {
           if (!fifo_comm(core1_boot_msg[i]))
             {
@@ -240,15 +231,17 @@ int up_cpu_start(int cpu)
             }
         }
     }
-  while (i < 5);
+  while (i < CORE1_BOOT_MSG_LEN);
 
   fifo_drain();
 
   /* Enable inter-processor FIFO interrupt */
 
-  irq_attach(RP23XX_SIO_IRQ_FIFO, rp23xx_smp_call_handler, NULL);
+  irq_attach(RP23XX_SIO_IRQ_FIFO, riscv_smp_call_handler, NULL);
   up_enable_irq(RP23XX_SIO_IRQ_FIFO);
 
+  /* Spin until Core 1 signals that it has finished its initialisation */
+
   while (!g_core1_boot);
 
   /* CPU Core 1 boot done */
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_head.S 
b/arch/risc-v/src/rp23xx-rv/rp23xx_head.S
index 64eb67ab340..772545d8004 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_head.S
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_head.S
@@ -30,14 +30,13 @@
 #include "chip.h"
 #include "hardware/rp23xx_memorymap.h"
 #include "riscv_internal.h"
+#include "riscv_macros.S"
 
 /****************************************************************************
  * Public Symbols
  ****************************************************************************/
 
-  /* Imported symbols */
-
-  .extern __trap_vec
+  /* Exported Symbols */
 
   .section .text
   .global __start
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_irq.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_irq.c
index 4d706fd95bb..f9e40cc3cb1 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_irq.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_irq.c
@@ -47,6 +47,10 @@
  * Public Data
  ****************************************************************************/
 
+#ifdef CONFIG_SMP
+extern void rp23xx_send_irqreq(int irqreq);
+#endif
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -91,6 +95,17 @@ void up_irqinitialize(void)
 
 void up_enable_irq(int irq)
 {
+#ifdef CONFIG_SMP
+  if (irq >= RP23XX_IRQ_EXTINT && irq != RP23XX_SIO_IRQ_FIFO &&
+      this_cpu() != 0)
+    {
+      /* Must be handled by Core 0 */
+
+      rp23xx_send_irqreq(irq);
+      return;
+    }
+#endif
+
   if (irq == RISCV_IRQ_MSOFT)
     {
       /* Read mstatus & set machine software interrupt enable in mie */
@@ -114,6 +129,8 @@ void up_enable_irq(int irq)
       hazard3_irqarray_set(RVCSR_MEIEA_OFFSET, 2 * n, mask & 0xffffu);
       hazard3_irqarray_set(RVCSR_MEIEA_OFFSET, 2 * n + 1, mask >> 16);
     }
+
+  UP_DMB();
 }
 
 /****************************************************************************
@@ -126,6 +143,17 @@ void up_enable_irq(int irq)
 
 void up_disable_irq(int irq)
 {
+#ifdef CONFIG_SMP
+  if (irq >= RP23XX_IRQ_EXTINT && irq != RP23XX_SIO_IRQ_FIFO &&
+      this_cpu() != 0)
+    {
+      /* Must be handled by Core 0 */
+
+      rp23xx_send_irqreq(-irq);
+      return;
+    }
+#endif
+
   if (irq == RISCV_IRQ_MSOFT)
     {
       /* Read mstatus & clear machine software interrupt enable in mie */
@@ -147,6 +175,8 @@ void up_disable_irq(int irq)
       hazard3_irqarray_clear(RVCSR_MEIEA_OFFSET, 2 * n, mask & 0xffffu);
       hazard3_irqarray_clear(RVCSR_MEIEA_OFFSET, 2 * n + 1, mask >> 16);
     }
+
+  UP_DMB();
 }
 
 /****************************************************************************
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_smpcall.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_smpcall.c
index 7a4774b3f50..0ac60dbf852 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_smpcall.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_smpcall.c
@@ -83,7 +83,7 @@ static void rp23xx_handle_irqreq(int irqreq)
  ****************************************************************************/
 
 /****************************************************************************
- * Name: rp23xx_smp_call_handler
+ * Name: riscv_smp_call_handler
  *
  * Description:
  *   This is the handler for SMP_CALL.
@@ -93,7 +93,7 @@ static void rp23xx_handle_irqreq(int irqreq)
  *
  ****************************************************************************/
 
-int rp23xx_smp_call_handler(int irq, void *c, void *arg)
+int riscv_smp_call_handler(int irq, void *c, void *arg)
 {
   int cpu = this_cpu();
   int irqreq;
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_start.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_start.c
index 12669a62fd8..58dbb7def13 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_start.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_start.c
@@ -34,7 +34,6 @@
 #include <nuttx/init.h>
 #include <arch/board/board.h>
 
-#include "riscv_internal.h"
 #include "rp23xx_config.h"
 #include "rp23xx_clock.h"
 #include "rp23xx_uart.h"
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_timerisr.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_timerisr.c
index 2a0ae5dcd81..364e25e272a 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_timerisr.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_timerisr.c
@@ -64,9 +64,26 @@
 
 void up_timer_initialize(void)
 {
+#ifdef CONFIG_SMP
+  if (this_cpu() != 0)
+    {
+      up_enable_irq(RISCV_IRQ_MTIMER);
+      return;
+    }
+#endif
+
+  /* Core 0: full timer initialisation */
+
+  /* Stop the timer and reset the counter while we configure it */
+
   putreg32(0, RP23XX_SIO_BASE + RP23XX_SIO_MTIME_CTRL_OFFSET);
   putreg32(0, RP23XX_SIO_BASE + RP23XX_SIO_MTIME_OFFSET);
   putreg32(0, RP23XX_SIO_BASE + RP23XX_SIO_MTIMEH_OFFSET);
+
+  /* Initialise compare registers to maximum so no interrupts fire
+   *  before the alarm subsystem sets the first real deadline.
+   */
+
   putreg32(RP23XX_SIO_MTIMECMP_MASK,
            RP23XX_SIO_BASE + RP23XX_SIO_MTIMECMP_OFFSET);
   putreg32(RP23XX_SIO_MTIMECMPH_MASK,
@@ -81,6 +98,8 @@ void up_timer_initialize(void)
 
   up_alarm_set_lowerhalf(lower);
 
+  /* Start the counter at full system-clock rate */
+
   putreg32(RP23XX_SIO_MTIME_CTRL_EN | RP23XX_SIO_MTIME_CTRL_FULLSPEED,
            RP23XX_SIO_BASE + RP23XX_SIO_MTIME_CTRL_OFFSET);
 }
diff --git a/arch/risc-v/src/rp23xx-rv/rp23xx_usbdev.c 
b/arch/risc-v/src/rp23xx-rv/rp23xx_usbdev.c
index 5718ae7a1af..01d69f0937f 100644
--- a/arch/risc-v/src/rp23xx-rv/rp23xx_usbdev.c
+++ b/arch/risc-v/src/rp23xx-rv/rp23xx_usbdev.c
@@ -33,11 +33,13 @@
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
+#include <sys/param.h>
 #include <nuttx/debug.h>
 
 #include <nuttx/arch.h>
 #include <nuttx/spinlock.h>
 #include <nuttx/kmalloc.h>
+
 #include <nuttx/usb/usb.h>
 #include <nuttx/usb/usbdev.h>
 #include <nuttx/usb/usbdev_trace.h>
@@ -45,6 +47,7 @@
 #include "chip.h"
 #include "riscv_internal.h"
 #include "rp23xx_usbdev.h"
+#include "hardware/rp23xx_hazard3.h"
 
 #include "hardware/rp23xx_resets.h"
 
@@ -320,7 +323,10 @@ static int rp23xx_epread(struct rp23xx_ep_s *privep, 
uint16_t nbytes);
 static void rp23xx_abortrequest(struct rp23xx_ep_s *privep,
                                 struct rp23xx_req_s *privreq,
                                 int16_t result);
-static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result);
+static struct rp23xx_req_s *
+rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result);
+static void rp23xx_callback(struct rp23xx_ep_s  *privep,
+                            struct rp23xx_req_s *callback_req);
 static void rp23xx_txcomplete(struct rp23xx_ep_s *privep);
 static int rp23xx_wrrequest(struct rp23xx_ep_s *privep);
 static void rp23xx_rxcomplete(struct rp23xx_ep_s *privep);
@@ -471,19 +477,15 @@ static void rp23xx_update_buffer_control(struct 
rp23xx_ep_s *privep,
                                          uint32_t and_mask,
                                          uint32_t or_mask)
 {
-  uint32_t value = 0;
-
-  if (and_mask)
+  if (and_mask == 0)
     {
-      value = getreg32(privep->buf_ctrl) & and_mask;
+      putreg32(or_mask, privep->buf_ctrl);
     }
-
-  if (or_mask)
+  else
     {
-      value |= or_mask;
+      uint32_t value = getreg32(privep->buf_ctrl);
+      putreg32((value & and_mask) | or_mask, privep->buf_ctrl);
     }
-
-  putreg32(value, privep->buf_ctrl);
 }
 
 /****************************************************************************
@@ -498,11 +500,15 @@ static int rp23xx_epwrite(struct rp23xx_ep_s *privep, 
uint8_t *buf,
                           uint16_t nbytes)
 {
   uint32_t val;
-  irqstate_t flags;
 
   /* Copy the transmit data into DPSRAM */
 
-  memcpy(privep->data_buf, buf, nbytes);
+  if (nbytes > 0)
+    {
+      memcpy(privep->data_buf, buf, nbytes);
+    }
+
+  UP_DMB();
 
   val = nbytes |
         RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL |
@@ -510,13 +516,11 @@ static int rp23xx_epwrite(struct rp23xx_ep_s *privep, 
uint8_t *buf,
         (privep->next_pid ?
          RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_DATA1_PID : 0);
 
-  privep->next_pid = 1 - privep->next_pid;    /* Invert DATA0 <-> DATA1 */
-
   /* Start the transfer */
 
-  flags = spin_lock_irqsave(&g_usbdev.lock);
+  privep->next_pid = 1 - privep->next_pid;
+
   rp23xx_update_buffer_control(privep, 0, val);
-  spin_unlock_irqrestore(&g_usbdev.lock, flags);
 
   return nbytes;
 }
@@ -532,20 +536,17 @@ static int rp23xx_epwrite(struct rp23xx_ep_s *privep, 
uint8_t *buf,
 static int rp23xx_epread(struct rp23xx_ep_s *privep, uint16_t nbytes)
 {
   uint32_t val;
-  irqstate_t flags;
 
   val = nbytes |
         RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL |
         (privep->next_pid ?
          RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_DATA1_PID : 0);
 
-  privep->next_pid = 1 - privep->next_pid;    /* Invert DATA0 <-> DATA1 */
-
   /* Start the transfer */
 
-  flags = spin_lock_irqsave(&g_usbdev.lock);
+  privep->next_pid = 1 - privep->next_pid;
+
   rp23xx_update_buffer_control(privep, 0, val);
-  spin_unlock_irqrestore(&g_usbdev.lock, flags);
 
   return OK;
 }
@@ -582,29 +583,17 @@ static void rp23xx_abortrequest(struct rp23xx_ep_s 
*privep,
  *
  ****************************************************************************/
 
-static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result)
+static struct rp23xx_req_s *
+rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result)
 {
   struct rp23xx_req_s *privreq;
-  int stalled = privep->stalled;
-  irqstate_t flags;
 
   /* Remove the completed request at the head of the endpoint request list */
 
-  flags = enter_critical_section();
   privreq = rp23xx_rqdequeue(privep);
-  leave_critical_section(flags);
 
   if (privreq)
     {
-      /* If endpoint 0, temporarily reflect the state of protocol stalled
-       * in the callback.
-       */
-
-      if (privep->epphy == 0)
-        {
-          privep->stalled = privep->dev->stalled;
-        }
-
       /* Save the result in the request structure */
 
       privreq->req.result = result;
@@ -612,12 +601,9 @@ static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, 
int16_t result)
       /* Callback to the request completion handler */
 
       privreq->flink = NULL;
-      privreq->req.callback(&privep->ep, &privreq->req);
-
-      /* Restore the stalled indication */
-
-      privep->stalled = stalled;
     }
+
+  return privreq;
 }
 
 /****************************************************************************
@@ -631,8 +617,14 @@ static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, 
int16_t result)
 static void rp23xx_txcomplete(struct rp23xx_ep_s *privep)
 {
   struct rp23xx_req_s *privreq;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&g_usbdev.lock);
 
   privreq = rp23xx_rqpeek(privep);
+
+  struct rp23xx_req_s *callback_req = NULL;
+
   if (!privreq)
     {
       usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_TXREQLOST), privep->epphy);
@@ -646,11 +638,42 @@ static void rp23xx_txcomplete(struct rp23xx_ep_s *privep)
         {
           usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
           privep->txnullpkt = 0;
-          rp23xx_reqcomplete(privep, OK);
+          callback_req = rp23xx_reqcomplete(privep, OK);
         }
     }
 
   rp23xx_wrrequest(privep);
+  spin_unlock_irqrestore(&g_usbdev.lock, flags);
+
+  rp23xx_callback(privep, callback_req);
+}
+
+/****************************************************************************
+ * Name: rp23xx_callback
+ *
+ * Description:
+ *   Call req callback
+ *
+ ****************************************************************************/
+
+static void rp23xx_callback(struct rp23xx_ep_s *privep,
+                            struct rp23xx_req_s *callback_req)
+{
+  irqstate_t flags;
+
+  if (callback_req && callback_req->req.callback)
+    {
+      /* Pass protocol stall state to EP0 callbacks */
+
+      if (privep->epphy == 0)
+        {
+          flags = spin_lock_irqsave(&g_usbdev.lock);
+          privep->stalled = privep->dev->stalled;
+          spin_unlock_irqrestore(&g_usbdev.lock, flags);
+        }
+
+      callback_req->req.callback(&privep->ep, &callback_req->req);
+    }
 }
 
 /****************************************************************************
@@ -677,22 +700,6 @@ static int rp23xx_wrrequest(struct rp23xx_ep_s *privep)
       return OK;
     }
 
-  /* Ignore any attempt to send a zero length packet on anything but EP0IN */
-
-  if (privreq->req.len == 0)
-    {
-      if (privep->epphy == 0)
-        {
-          rp23xx_epwrite(privep, NULL, 0);
-        }
-      else
-        {
-          usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_NULLPACKET), 0);
-        }
-
-      return OK;
-    }
-
   /* Get the number of bytes left to be sent in the packet */
 
   bytesleft = privreq->req.len - privreq->req.xfrd;
@@ -702,7 +709,7 @@ static int rp23xx_wrrequest(struct rp23xx_ep_s *privep)
    */
 
   usbtrace(TRACE_WRITE(privep->epphy), (uint16_t)bytesleft);
-  if (bytesleft > 0 || privep->txnullpkt)
+  if (bytesleft > 0 || privep->txnullpkt || privreq->req.len == 0)
     {
       /* Try to send maxpacketsize -- unless we don't have that many
        * bytes to send.
@@ -743,29 +750,48 @@ static void rp23xx_rxcomplete(struct rp23xx_ep_s *privep)
 {
   struct rp23xx_req_s *privreq;
   uint16_t nrxbytes;
+  uint16_t available;
+  uint16_t copy_len;
+  irqstate_t flags;
+  struct rp23xx_req_s *callback_req = NULL;
 
   nrxbytes = getreg32(privep->buf_ctrl)
              & RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_LEN_MASK;
 
+  flags = spin_lock_irqsave(&g_usbdev.lock);
+
   privreq = rp23xx_rqpeek(privep);
   if (!privreq)
     {
+      spin_unlock_irqrestore(&g_usbdev.lock, flags);
       usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_RXREQLOST), privep->epphy);
       return;
     }
 
-  memcpy(privreq->req.buf + privreq->req.xfrd, privep->data_buf, nrxbytes);
+  available = privreq->req.len - privreq->req.xfrd;
+  copy_len = MIN(nrxbytes, available);
+
+  memcpy(privreq->req.buf + privreq->req.xfrd, privep->data_buf, copy_len);
+  privreq->req.xfrd += copy_len;
 
-  privreq->req.xfrd += nrxbytes;
+  if (nrxbytes > available)
+    {
+      usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_EPREAD), privep->epphy);
+      privreq->req.result = -EIO;
+    }
 
   if (privreq->req.xfrd >= privreq->req.len ||
       nrxbytes < privep->ep.maxpacket)
     {
       usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
-      rp23xx_reqcomplete(privep, OK);
+      callback_req =
+      rp23xx_reqcomplete(privep, privreq->req.result == -EIO ? -EIO : OK);
     }
 
   rp23xx_rdrequest(privep);
+  spin_unlock_irqrestore(&g_usbdev.lock, flags);
+
+  rp23xx_callback(privep, callback_req);
 }
 
 /****************************************************************************
@@ -846,6 +872,35 @@ static void rp23xx_handle_zlp(struct rp23xx_usbdev_s *priv)
   priv->zlp_stat = RP23XX_ZLP_NONE;
 }
 
+static void rp23xx_drain_queue(struct rp23xx_ep_s *privep,
+                               struct rp23xx_req_s **list_head)
+{
+  struct rp23xx_req_s *privreq;
+  struct rp23xx_req_s *tail = NULL;
+
+  while (!rp23xx_rqempty(privep))
+    {
+      usbtrace(TRACE_COMPLETE(privep->epphy),
+               (rp23xx_rqpeek(privep))->req.xfrd);
+      privreq = rp23xx_rqdequeue(privep);
+      if (privreq)
+        {
+          privreq->req.result = -ESHUTDOWN;
+          privreq->flink = NULL;
+          if (!*list_head)
+            {
+              *list_head = privreq;
+            }
+          else
+            {
+              tail->flink = privreq;
+            }
+
+          tail = privreq;
+        }
+    }
+}
+
 /****************************************************************************
  * Name: rp23xx_cancelrequests
  *
@@ -856,11 +911,23 @@ static void rp23xx_handle_zlp(struct rp23xx_usbdev_s 
*priv)
 
 static void rp23xx_cancelrequests(struct rp23xx_ep_s *privep)
 {
-  while (!rp23xx_rqempty(privep))
+  struct rp23xx_req_s *local_list = NULL;
+  struct rp23xx_req_s *next;
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&g_usbdev.lock);
+  rp23xx_drain_queue(privep, &local_list);
+  spin_unlock_irqrestore(&g_usbdev.lock, flags);
+
+  while (local_list)
     {
-      usbtrace(TRACE_COMPLETE(privep->epphy),
-               (rp23xx_rqpeek(privep))->req.xfrd);
-      rp23xx_reqcomplete(privep, -ESHUTDOWN);
+      next = local_list->flink;
+      if (local_list->req.callback)
+        {
+          local_list->req.callback(&privep->ep, &local_list->req);
+        }
+
+      local_list = next;
     }
 }
 
@@ -1209,16 +1276,17 @@ static void rp23xx_usbintr_setup(struct rp23xx_usbdev_s 
*priv)
 
   /* Read USB control request data */
 
+  UP_DMB();
   memcpy(&priv->ctrl, (void *)RP23XX_USBCTRL_DPSRAM_SETUP_PACKET,
          USB_SIZEOF_CTRLREQ);
   len = GETUINT16(priv->ctrl.len);
 
   /* Reset PID and stall status in setup stage */
 
+  rp23xx_epstall(&priv->eplist[0].ep, true);
+  rp23xx_epstall(&priv->eplist[1].ep, true);
   priv->eplist[0].next_pid = 1;
   priv->eplist[1].next_pid = 1;
-  priv->eplist[0].stalled = false;
-  priv->eplist[1].stalled = false;
 
   /* ZLP type in status stage */
 
@@ -1264,6 +1332,7 @@ static void rp23xx_usbintr_ep0out(struct rp23xx_usbdev_s 
*priv,
       return;
     }
 
+  UP_DMB();
   memcpy(priv->ep0data + priv->ep0datlen, privep->data_buf, len);
   priv->ep0datlen += len;
 
@@ -1307,7 +1376,7 @@ static bool rp23xx_usbintr_buffstat(struct 
rp23xx_usbdev_s *priv)
     {
       if (stat & bit)
         {
-          clrbits_reg32(bit, RP23XX_USBCTRL_REGS_BUFF_STATUS);
+          putreg32(bit, RP23XX_USBCTRL_REGS_BUFF_STATUS);
           privep = &priv->eplist[RP23XX_DPTOEP(i)];
 
           if (i == 1)
@@ -1382,7 +1451,7 @@ static void rp23xx_usbintr_busreset(struct 
rp23xx_usbdev_s *priv)
       CLASS_DISCONNECT(priv->driver, &priv->usbdev);
     }
 
-  clrbits_reg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
+  putreg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
                 RP23XX_USBCTRL_REGS_SIE_STATUS);
 }
 
@@ -1411,7 +1480,7 @@ static int rp23xx_usbinterrupt(int irq, void *context, 
void *arg)
 
   if (stat & RP23XX_USBCTRL_REGS_INTR_SETUP_REQ)
     {
-      clrbits_reg32(RP23XX_USBCTRL_REGS_SIE_STATUS_SETUP_REC,
+      putreg32(RP23XX_USBCTRL_REGS_SIE_STATUS_SETUP_REC,
                     RP23XX_USBCTRL_REGS_SIE_STATUS);
 
       rp23xx_usbintr_setup(priv);
@@ -1419,7 +1488,7 @@ static int rp23xx_usbinterrupt(int irq, void *context, 
void *arg)
 
   if (stat & RP23XX_USBCTRL_REGS_INTR_BUS_RESET)
     {
-      clrbits_reg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
+      putreg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
                     RP23XX_USBCTRL_REGS_SIE_STATUS);
 
       rp23xx_usbintr_busreset(priv);
@@ -1466,10 +1535,7 @@ static int rp23xx_epconfigure(struct usbdev_ep_s *ep,
   uinfo("config: EP%d %s %d maxpacket=%d\n", privep->epphy,
         privep->in ? "IN" : "OUT", eptype, maxpacket);
 
-  if (desc)
-    {
-      privep->ep.maxpacket = GETUINT16(desc->mxpacketsize);
-    }
+  privep->ep.maxpacket = GETUINT16(desc->mxpacketsize);
 
   if (privep->epphy != 0)
     {
@@ -1477,10 +1543,14 @@ static int rp23xx_epconfigure(struct usbdev_ep_s *ep,
        * (No need for EP0 because it has the dedicated buffer)
        */
 
-      privep->data_buf = (uint8_t *)(RP23XX_USBCTRL_DPSRAM_BASE +
-                                     priv->next_offset);
-      priv->next_offset =
-                     (priv->next_offset + privep->ep.maxpacket + 63) & ~63;
+      if (privep->data_buf == NULL)
+        {
+          privep->data_buf = (uint8_t *)(RP23XX_USBCTRL_DPSRAM_BASE +
+                                          priv->next_offset);
+          priv->next_offset =
+                          (priv->next_offset +
+                           privep->ep.maxpacket + 63) & ~63;
+        }
 
       /* Enable EP */
 
@@ -1506,6 +1576,8 @@ static int rp23xx_epconfigure(struct usbdev_ep_s *ep,
 static int rp23xx_epdisable(struct usbdev_ep_s *ep)
 {
   struct rp23xx_ep_s *privep = (struct rp23xx_ep_s *)ep;
+  struct rp23xx_req_s *local_list = NULL;
+  struct rp23xx_req_s *next;
   irqstate_t flags;
 
 #ifdef CONFIG_DEBUG_FEATURES
@@ -1519,18 +1591,28 @@ static int rp23xx_epdisable(struct usbdev_ep_s *ep)
   usbtrace(TRACE_EPDISABLE, privep->epphy);
   uinfo("EP%d\n", privep->epphy);
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&g_usbdev.lock);
 
-  privep->ep.maxpacket = 64;
+  privep->ep.maxpacket = RP23XX_EP0MAXPACKET;
   privep->stalled = false;
   privep->next_pid = 0;
   putreg32(0, privep->buf_ctrl);
 
   /* Cancel all queued requests */
 
-  rp23xx_cancelrequests(privep);
+  rp23xx_drain_queue(privep, &local_list);
+  spin_unlock_irqrestore(&g_usbdev.lock, flags);
+
+  while (local_list)
+    {
+      next = local_list->flink;
+      if (local_list->req.callback)
+        {
+          local_list->req.callback(&privep->ep, &local_list->req);
+        }
 
-  leave_critical_section(flags);
+      local_list = next;
+    }
 
   return OK;
 }
@@ -1623,12 +1705,13 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep,
   req->result = -EINPROGRESS;
   req->xfrd = 0;
 
-  flags = enter_critical_section();
+  flags = spin_lock_irqsave(&g_usbdev.lock);
 
   if (privep->stalled && privep->in)
     {
+      spin_unlock_irqrestore(&g_usbdev.lock, flags);
       rp23xx_abortrequest(privep, privreq, -EBUSY);
-      ret = -EBUSY;
+      return -EBUSY;
     }
 
   /* Handle IN (device-to-host) requests */
@@ -1668,7 +1751,7 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep,
         }
     }
 
-  leave_critical_section(flags);
+  spin_unlock_irqrestore(&g_usbdev.lock, flags);
   return ret;
 }
 
@@ -1676,14 +1759,18 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep,
  * Name: rp23xx_epcancel
  *
  * Description:
- *   Cancel an I/O request previously sent to an endpoint
+ * Cancel an I/O request previously sent to an endpoint
  *
  ****************************************************************************/
 
-static int rp23xx_epcancel(struct usbdev_ep_s *ep,
-                           struct usbdev_req_s *req)
+static int rp23xx_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
 {
   struct rp23xx_ep_s *privep = (struct rp23xx_ep_s *)ep;
+  struct rp23xx_req_s *privreq = (struct rp23xx_req_s *)req;
+  struct rp23xx_req_s *curr;
+  struct rp23xx_req_s *prev = NULL;
+  bool found = false;
+  bool is_head = false;
   irqstate_t flags;
 
 #ifdef CONFIG_DEBUG_FEATURES
@@ -1696,12 +1783,64 @@ static int rp23xx_epcancel(struct usbdev_ep_s *ep,
 
   usbtrace(TRACE_EPCANCEL, privep->epphy);
 
-  /* Remove request from req_queue */
+  flags = spin_lock_irqsave(&g_usbdev.lock);
 
-  flags = enter_critical_section();
-  rp23xx_cancelrequests(privep);
-  leave_critical_section(flags);
-  return OK;
+  for (curr = privep->head; curr != NULL; prev = curr, curr = curr->flink)
+    {
+      if (curr == privreq)
+        {
+          found = true;
+          break;
+        }
+    }
+
+  if (found)
+    {
+      if (curr == privep->head)
+        {
+          is_head = true;
+
+          putreg32(0, privep->buf_ctrl);
+
+          privep->head = curr->flink;
+          if (!privep->head)
+            {
+              privep->tail = NULL;
+            }
+        }
+      else
+        {
+          prev->flink = curr->flink;
+          if (privep->tail == curr)
+            {
+              privep->tail = prev;
+            }
+        }
+
+      curr->flink = NULL;
+      curr->req.result = -ECANCELED;
+
+      if (is_head && privep->head != NULL)
+        {
+          if (privep->in)
+            {
+              rp23xx_wrrequest(privep);
+            }
+          else
+            {
+              rp23xx_rdrequest(privep);
+            }
+        }
+    }
+
+  spin_unlock_irqrestore(&g_usbdev.lock, flags);
+
+  if (found && privreq->req.callback)
+    {
+      privreq->req.callback(&privep->ep, &privreq->req);
+    }
+
+  return found ? OK : -ENOENT;
 }
 
 /****************************************************************************
@@ -1985,7 +2124,7 @@ static int rp23xx_pullup(struct usbdev_s *dev, bool 
enable)
  ****************************************************************************/
 
 /****************************************************************************
- * Name: riscv_usbinitialize
+ * Name: rp23xx_usbinitialize
  *
  * Description:
  *   Initialize the USB driver
@@ -2020,7 +2159,7 @@ void rp23xx_usbinitialize(void)
   for (i = 0; i < RP23XX_NENDPOINTS; i++)
     {
       g_usbdev.eplist[i].ep.ops = &g_epops;
-      g_usbdev.eplist[i].ep.maxpacket = 64;
+      g_usbdev.eplist[i].ep.maxpacket = RP23XX_EP0MAXPACKET;
       g_usbdev.eplist[i].dev = &g_usbdev;
       g_usbdev.eplist[i].epphy = 0;
       g_usbdev.eplist[i].head = NULL;
@@ -2075,13 +2214,29 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
 
   memset((void *)RP23XX_USBCTRL_DPSRAM_BASE, 0, 0x1000);
 
-  putreg32(RP23XX_USBCTRL_REGS_USB_MUXING_SOFTCON |
+  /* Enable interrupt */
+
+  up_enable_irq(RP23XX_USBCTRL_IRQ);
+
+  setbits_reg32(RP23XX_USBCTRL_REGS_USB_MUXING_SOFTCON |
            RP23XX_USBCTRL_REGS_USB_MUXING_TO_PHY,
            RP23XX_USBCTRL_REGS_USB_MUXING);
-  putreg32(RP23XX_USBCTRL_REGS_USB_PWR_VBUS_DETECT |
+
+  setbits_reg32(RP23XX_USBCTRL_REGS_USB_PWR_VBUS_DETECT |
            RP23XX_USBCTRL_REGS_USB_PWR_VBUS_DETECT_OVERRIDE_EN,
            RP23XX_USBCTRL_REGS_USB_PWR);
 
+  setbits_reg32(RP23XX_USBCTRL_REGS_MAIN_CTRL_CONTROLLER_EN,
+           RP23XX_USBCTRL_REGS_MAIN_CTRL);
+
+  setbits_reg32(RP23XX_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
+           RP23XX_USBCTRL_REGS_SIE_CTRL);
+
+  setbits_reg32(RP23XX_USBCTRL_REGS_INTR_BUFF_STATUS |
+           RP23XX_USBCTRL_REGS_INTR_BUS_RESET |
+           RP23XX_USBCTRL_REGS_INTR_SETUP_REQ,
+           RP23XX_USBCTRL_REGS_INTE);
+
   rp23xx_allocep(&g_usbdev.usbdev, 0x00, 0, USB_EP_ATTR_XFER_CONTROL);
   rp23xx_allocep(&g_usbdev.usbdev, 0x80, 1, USB_EP_ATTR_XFER_CONTROL);
 
@@ -2100,20 +2255,6 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
   modifyreg32(RP23XX_USBCTRL_REGS_MAIN_CTRL,
               RP23XX_USBCTRL_REGS_MAIN_CTRL_PHY_ISO, 0);
 
-  putreg32(RP23XX_USBCTRL_REGS_MAIN_CTRL_CONTROLLER_EN,
-           RP23XX_USBCTRL_REGS_MAIN_CTRL);
-
-  /* Enable interrupt */
-
-  putreg32(RP23XX_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
-           RP23XX_USBCTRL_REGS_SIE_CTRL);
-  putreg32(RP23XX_USBCTRL_REGS_INTR_BUFF_STATUS |
-           RP23XX_USBCTRL_REGS_INTR_BUS_RESET |
-           RP23XX_USBCTRL_REGS_INTR_SETUP_REQ,
-           RP23XX_USBCTRL_REGS_INTE);
-
-  up_enable_irq(RP23XX_USBCTRL_IRQ);
-
   return OK;
 }
 
diff --git 
a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig 
b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh-smp/defconfig
similarity index 87%
copy from boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig
copy to boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh-smp/defconfig
index 85c48d36f41..26495face95 100644
--- a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig
+++ b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh-smp/defconfig
@@ -16,21 +16,21 @@ CONFIG_ARCH_BOARD_COMMON=y
 CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
 CONFIG_ARCH_CHIP="rp23xx-rv"
 CONFIG_ARCH_CHIP_RP23XX_RV=y
+CONFIG_ARCH_INTERRUPTSTACK=4096
 CONFIG_ARCH_RISCV=y
-CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb"
+CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4096
 CONFIG_DISABLE_POSIX_TIMERS=y
 CONFIG_EXAMPLES_HELLO=y
 CONFIG_FS_PROCFS=y
 CONFIG_FS_PROCFS_REGISTER=y
-CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IDLETHREAD_STACKSIZE=4096
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4096
-CONFIG_IRQ_WORK_STACKSIZE=4096
 CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_READLINE=y
@@ -40,6 +40,8 @@ CONFIG_READLINE_CMD_HISTORY=y
 CONFIG_RISCV_TOOLCHAIN_GNU_RV32=y
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_WAITPID=y
+CONFIG_SMP=y
+CONFIG_SMP_NCPUS=2
 CONFIG_START_DAY=9
 CONFIG_START_MONTH=2
 CONFIG_START_YEAR=2021
diff --git 
a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig 
b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig
index 85c48d36f41..2323dfad0a4 100644
--- a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig
+++ b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/nsh/defconfig
@@ -17,20 +17,19 @@ CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
 CONFIG_ARCH_CHIP="rp23xx-rv"
 CONFIG_ARCH_CHIP_RP23XX_RV=y
 CONFIG_ARCH_RISCV=y
-CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb"
+CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
 CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4096
 CONFIG_DISABLE_POSIX_TIMERS=y
 CONFIG_EXAMPLES_HELLO=y
 CONFIG_FS_PROCFS=y
 CONFIG_FS_PROCFS_REGISTER=y
-CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IDLETHREAD_STACKSIZE=4096
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4096
-CONFIG_IRQ_WORK_STACKSIZE=4096
 CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_READLINE=y
diff --git 
a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig 
b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh-smp/defconfig
similarity index 83%
copy from boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig
copy to 
boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh-smp/defconfig
index 91bbda7cf49..c8c6e91c7b2 100644
--- a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig
+++ b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh-smp/defconfig
@@ -17,22 +17,25 @@ CONFIG_ARCH_BOARD_COMMON=y
 CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
 CONFIG_ARCH_CHIP="rp23xx-rv"
 CONFIG_ARCH_CHIP_RP23XX_RV=y
+CONFIG_ARCH_INTERRUPTSTACK=4096
 CONFIG_ARCH_RISCV=y
-CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb"
+CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
+CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_CDCACM=y
 CONFIG_CDCACM_CONSOLE=y
+CONFIG_CDCACM_DISABLE_RXBUF=y
+CONFIG_CDCACM_DISABLE_TXBUF=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4096
 CONFIG_DISABLE_POSIX_TIMERS=y
 CONFIG_EXAMPLES_HELLO=y
 CONFIG_FS_PROCFS=y
 CONFIG_FS_PROCFS_REGISTER=y
-CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IDLETHREAD_STACKSIZE=4096
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4096
-CONFIG_IRQ_WORK_STACKSIZE=4096
 CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_READLINE=y
@@ -43,6 +46,8 @@ CONFIG_READLINE_CMD_HISTORY=y
 CONFIG_RISCV_TOOLCHAIN_GNU_RV32=y
 CONFIG_RR_INTERVAL=200
 CONFIG_SCHED_WAITPID=y
+CONFIG_SMP=y
+CONFIG_SMP_NCPUS=2
 CONFIG_START_DAY=9
 CONFIG_START_MONTH=2
 CONFIG_START_YEAR=2021
diff --git 
a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig 
b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig
index 91bbda7cf49..5bfb01cf93d 100644
--- a/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig
+++ b/boards/risc-v/rp23xx-rv/raspberrypi-pico-2-rv/configs/usbnsh/defconfig
@@ -18,21 +18,23 @@ CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
 CONFIG_ARCH_CHIP="rp23xx-rv"
 CONFIG_ARCH_CHIP_RP23XX_RV=y
 CONFIG_ARCH_RISCV=y
-CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb"
+CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
+CONFIG_BOARDCTL_RESET=y
 CONFIG_BOARD_LOOPSPERMSEC=15000
 CONFIG_BUILTIN=y
 CONFIG_CDCACM=y
 CONFIG_CDCACM_CONSOLE=y
+CONFIG_CDCACM_DISABLE_RXBUF=y
+CONFIG_CDCACM_DISABLE_TXBUF=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4096
 CONFIG_DISABLE_POSIX_TIMERS=y
 CONFIG_EXAMPLES_HELLO=y
 CONFIG_FS_PROCFS=y
 CONFIG_FS_PROCFS_REGISTER=y
-CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_IDLETHREAD_STACKSIZE=4096
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4096
-CONFIG_IRQ_WORK_STACKSIZE=4096
 CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
 CONFIG_NSH_BUILTIN_APPS=y
 CONFIG_NSH_READLINE=y

Reply via email to