From dc3c9f35607f93efe82d8499a6c034a6d3d6af22 Mon Sep 17 00:00:00 2001 From: Stephanos Ioannidis Date: Thu, 3 Jul 2025 14:40:14 +0900 Subject: [PATCH] arch: riscv: Introduce code model options This commit introduces a new Kconfig choice for configuring the code model used for compilation. All three code models specified by the RISC-V ELF psABI specification are supported: medlow, medany and large. For RV32, the `medlow` code model is always selected. For RV64, the `large` code model is selected if the SRAM or kernel VM base address is greater than or equal to 4 GiB; otherwise, the `medany` code model is selected. Signed-off-by: Stephanos Ioannidis --- arch/riscv/Kconfig | 28 +++++++++++++++++++++++++++ cmake/compiler/gcc/target_riscv.cmake | 24 +++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 735d7c5e4b1..2ec02da20de 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -53,6 +53,34 @@ config RISCV_ALWAYS_SWITCH_THROUGH_ECALL and most people should say n here to minimize context switching overhead. +choice RISCV_CMODEL + prompt "RISC-V Code Model" + default RISCV_CMODEL_LARGE if (SRAM_BASE_ADDRESS > 0xffffffff) || \ + (KERNEL_VM_BASE > 0xffffffff) + default RISCV_CMODEL_MEDANY if 64BIT + default RISCV_CMODEL_MEDLOW + +config RISCV_CMODEL_MEDLOW + bool "Medium-low code model" + help + In medium-low code model (medlow), the program and its statically defined symbols must lie + within a single 2 GiB address range and between absolute addresses -2 GiB and +2 GiB. + +config RISCV_CMODEL_MEDANY + bool "Medium-any code model" + help + In medium-any code model (medany), the program and its statically defined symbols must be + within any single 2 GiB address range. The code generated by this model is + position-independent. + +config RISCV_CMODEL_LARGE + bool "Large code model" + help + In large code model (large), the program and its statically defined symbols have no + restrictions on size and placement. + +endchoice + choice RISCV_SMP_IPI_IMPL prompt "RISC-V SMP IPI implementation" depends on SMP diff --git a/cmake/compiler/gcc/target_riscv.cmake b/cmake/compiler/gcc/target_riscv.cmake index 1f1e9d2332d..58c5ac524ad 100644 --- a/cmake/compiler/gcc/target_riscv.cmake +++ b/cmake/compiler/gcc/target_riscv.cmake @@ -3,11 +3,17 @@ set(riscv_mabi "lp") set(riscv_march "rv") +if(CONFIG_RISCV_CMODEL_MEDLOW) + set(riscv_mcmodel "medlow") +elseif(CONFIG_RISCV_CMODEL_MEDANY) + set(riscv_mcmodel "medany") +elseif(CONFIG_RISCV_CMODEL_LARGE) + set(riscv_mcmodel "large") +endif() + if(CONFIG_64BIT) string(CONCAT riscv_mabi ${riscv_mabi} "64") string(CONCAT riscv_march ${riscv_march} "64") - list(APPEND TOOLCHAIN_C_FLAGS -mcmodel=medany) - list(APPEND TOOLCHAIN_LD_FLAGS -mcmodel=medany) else() string(CONCAT riscv_mabi "i" ${riscv_mabi} "32") string(CONCAT riscv_march ${riscv_march} "32") @@ -123,8 +129,17 @@ if(NOT CONFIG_RISCV_ISA_EXT_M AND string(CONCAT riscv_march ${riscv_march} "_zmmul") endif() -list(APPEND TOOLCHAIN_C_FLAGS -mabi=${riscv_mabi} -march=${riscv_march}) -list(APPEND TOOLCHAIN_LD_FLAGS NO_SPLIT -mabi=${riscv_mabi} -march=${riscv_march}) +list(APPEND TOOLCHAIN_C_FLAGS + -mabi=${riscv_mabi} + -march=${riscv_march} + -mcmodel=${riscv_mcmodel} + ) + +list(APPEND TOOLCHAIN_LD_FLAGS NO_SPLIT + -mabi=${riscv_mabi} + -march=${riscv_march} + -mcmodel=${riscv_mcmodel} + ) # Flags not supported by llext linker # (regexps are supported and match whole word) @@ -146,6 +161,7 @@ set(LLEXT_REMOVE_FLAGS set(LLEXT_APPEND_FLAGS -mabi=${riscv_mabi} -march=${riscv_march} + -mcmodel=${riscv_mcmodel} -mno-relax -msmall-data-limit=0 )