diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 3b563d35f3..14f539e072 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -489,6 +489,16 @@ config RISCV_MISALIGNED_HANDLER depends on ARCH_HAVE_MISALIGN_EXCEPTION default y +config RISCV_PERCPU_SCRATCH + bool "Enable Scratch-based Per-CPU storage" + default n + ---help--- + In some special chipsets, multiple CPUs may be bundled in one hardware + thread cluster, which results in hartid and cpuindex not being exactly + the same. + This option will enable Scratch-based Per-CPU storage to distinguish + the real cpu index. + # Option to run NuttX in supervisor mode. This is obviously not usable in # flat mode, is questionable in protected mode, but is mandatory in kernel # mode. @@ -504,6 +514,7 @@ config ARCH_USE_S_MODE bool "Run the NuttX kernel in S-mode" default n depends on ARCH_HAVE_S_MODE && BUILD_KERNEL && ARCH_USE_MMU + select RISCV_PERCPU_SCRATCH ---help--- Most of the RISC-V implementations run in M-mode (flat addressing) and/or U-mode (in case of separate kernel-/userspaces). This provides diff --git a/arch/risc-v/src/Makefile b/arch/risc-v/src/Makefile index 41df61e21c..6a057638f9 100644 --- a/arch/risc-v/src/Makefile +++ b/arch/risc-v/src/Makefile @@ -26,12 +26,6 @@ else ifeq ($(CONFIG_NUTTSBI),y) include nuttsbi/Make.defs endif -# Kernel runs in supervisor mode or machine mode ? - -ifeq ($(CONFIG_ARCH_USE_S_MODE),y) -include common/supervisor/Make.defs -endif - ARCH_SRCDIR = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)chip diff --git a/arch/risc-v/src/common/CMakeLists.txt b/arch/risc-v/src/common/CMakeLists.txt index 28b6be70ab..fa06d942b2 100644 --- a/arch/risc-v/src/common/CMakeLists.txt +++ b/arch/risc-v/src/common/CMakeLists.txt @@ -105,8 +105,11 @@ if(CONFIG_ARCH_ADDRENV) list(APPEND SRCS riscv_addrenv_utils.c riscv_addrenv_shm.c) endif() -if(CONFIG_BUILD_KERNEL) +if(CONFIG_RISCV_PERCPU_SCRATCH) list(APPEND SRCS riscv_percpu.c) +endif() + +if(CONFIG_BUILD_KERNEL) add_subdirectory(supervisor) endif() diff --git a/arch/risc-v/src/common/Make.defs b/arch/risc-v/src/common/Make.defs index 9088cfbe10..f5f1bc637a 100644 --- a/arch/risc-v/src/common/Make.defs +++ b/arch/risc-v/src/common/Make.defs @@ -108,3 +108,13 @@ ifeq ($(CONFIG_ARCH_ADDRENV),y) CMN_CSRCS += riscv_addrenv.c riscv_pgalloc.c riscv_addrenv_perms.c CMN_CSRCS += riscv_addrenv_utils.c riscv_addrenv_shm.c riscv_addrenv_pgmap.c endif + +ifeq ($(CONFIG_RISCV_PERCPU_SCRATCH),y) +CMN_CSRCS += riscv_percpu.c +endif + +# Kernel runs in supervisor mode or machine mode ? + +ifeq ($(CONFIG_ARCH_USE_S_MODE),y) +include common/supervisor/Make.defs +endif diff --git a/arch/risc-v/src/common/riscv_cpustart.c b/arch/risc-v/src/common/riscv_cpustart.c index 068cbce8fe..332cd2e858 100644 --- a/arch/risc-v/src/common/riscv_cpustart.c +++ b/arch/risc-v/src/common/riscv_cpustart.c @@ -77,11 +77,13 @@ void riscv_cpu_boot(int cpu) asm("WFI"); -#ifdef CONFIG_BUILD_KERNEL +#ifdef CONFIG_RISCV_PERCPU_SCRATCH /* Initialize the per CPU areas */ riscv_percpu_add_hart((uintptr_t)cpu); +#endif +#ifdef CONFIG_BUILD_KERNEL /* Enable MMU */ binfo("mmu_enable: satp=%lx\n", g_kernel_pgt_pbase); diff --git a/arch/risc-v/src/common/riscv_macros.S b/arch/risc-v/src/common/riscv_macros.S index 34b2971e28..46e8ac490b 100644 --- a/arch/risc-v/src/common/riscv_macros.S +++ b/arch/risc-v/src/common/riscv_macros.S @@ -357,7 +357,7 @@ ****************************************************************************/ .macro riscv_mhartid out -#ifdef CONFIG_ARCH_USE_S_MODE +#ifdef CONFIG_RISCV_PERCPU_SCRATCH csrr \out, CSR_SCRATCH REGLOAD \out, RISCV_PERCPU_HARTID(\out) #else diff --git a/arch/risc-v/src/common/supervisor/Make.defs b/arch/risc-v/src/common/supervisor/Make.defs index 11c80358e2..65375a3f09 100644 --- a/arch/risc-v/src/common/supervisor/Make.defs +++ b/arch/risc-v/src/common/supervisor/Make.defs @@ -22,7 +22,7 @@ CMN_ASRCS += riscv_syscall.S CMN_CSRCS += riscv_perform_syscall.c -CMN_CSRCS += riscv_percpu.c riscv_sbi.c +CMN_CSRCS += riscv_sbi.c INCLUDES += ${INCDIR_PREFIX}$(ARCH_SRCDIR)$(DELIM)common$(DELIM)supervisor VPATH += common$(DELIM)supervisor diff --git a/arch/risc-v/src/k230/k230_start.c b/arch/risc-v/src/k230/k230_start.c index 956cc497d7..954f31bc74 100644 --- a/arch/risc-v/src/k230/k230_start.c +++ b/arch/risc-v/src/k230/k230_start.c @@ -121,7 +121,7 @@ void k230_start(int mhartid, const char *dtb) { k230_clear_bss(); -#ifdef CONFIG_BUILD_KERNEL +#ifdef CONFIG_RISCV_PERCPU_SCRATCH riscv_percpu_add_hart(mhartid); #else k230_copy_init_data(); diff --git a/arch/risc-v/src/litex/litex_start.c b/arch/risc-v/src/litex/litex_start.c index 54f6ea8dc6..0d0f5135aa 100644 --- a/arch/risc-v/src/litex/litex_start.c +++ b/arch/risc-v/src/litex/litex_start.c @@ -119,7 +119,7 @@ void __litex_start(int hart_index, const void * fdt, int arg) fdt_register((const char *)CONFIG_LITEX_FDT_MEMORY_ADDRESS); } -#ifdef CONFIG_LITEX_CORE_VEXRISCV_SMP +#ifdef CONFIG_RISCV_PERCPU_SCRATCH riscv_percpu_add_hart(0); #endif diff --git a/arch/risc-v/src/mpfs/mpfs_start.c b/arch/risc-v/src/mpfs/mpfs_start.c index 52fd3162fd..8fabae1e0e 100644 --- a/arch/risc-v/src/mpfs/mpfs_start.c +++ b/arch/risc-v/src/mpfs/mpfs_start.c @@ -149,14 +149,14 @@ void __mpfs_start(uint64_t mhartid) mpfs_boardinitialize(); -#ifdef CONFIG_ARCH_USE_S_MODE +#ifdef CONFIG_RISCV_PERCPU_SCRATCH /* Initialize the per CPU areas */ if (mhartid != 0) { riscv_percpu_add_hart(mhartid); } -#endif /* CONFIG_ARCH_USE_S_MODE */ +#endif /* CONFIG_RISCV_PERCPU_SCRATCH */ /* Initialize the caches. Should only be executed from E51 (hart 0) to be * functional. Consider the caches already configured if running without diff --git a/arch/risc-v/src/qemu-rv/qemu_rv_start.c b/arch/risc-v/src/qemu-rv/qemu_rv_start.c index 92f4899bb3..7a413a186e 100644 --- a/arch/risc-v/src/qemu-rv/qemu_rv_start.c +++ b/arch/risc-v/src/qemu-rv/qemu_rv_start.c @@ -119,6 +119,10 @@ void qemu_rv_start(int mhartid, const char *dtb) qemu_rv_clear_bss(); #endif +#ifdef CONFIG_RISCV_PERCPU_SCRATCH + riscv_percpu_add_hart(mhartid); +#endif + #ifdef CONFIG_DEVICE_TREE fdt_register(dtb); #endif