rp2: Add support for RP2350 in RISCV mode.

As part of this change, the RV32I native emitter is enabled on RISCV
board variants.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2024-08-08 14:34:22 +10:00
parent 34e463d861
commit 4fc6cf9141
4 changed files with 58 additions and 11 deletions

View File

@ -93,6 +93,14 @@ include(${MICROPY_DIR}/py/usermod.cmake)
add_executable(${MICROPY_TARGET}) add_executable(${MICROPY_TARGET})
# Provide a C-level definitions of PICO_ARM.
# (The pico-sdk already defines PICO_RISCV when it's enabled.)
if(PICO_ARM)
target_compile_definitions(pico_platform_headers INTERFACE
PICO_ARM=1
)
endif()
set(MICROPY_QSTRDEFS_PORT set(MICROPY_QSTRDEFS_PORT
${MICROPY_PORT_DIR}/qstrdefsport.h ${MICROPY_PORT_DIR}/qstrdefsport.h
) )
@ -108,7 +116,6 @@ set(MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/netutils/netutils.c ${MICROPY_DIR}/shared/netutils/netutils.c
${MICROPY_DIR}/shared/netutils/trace.c ${MICROPY_DIR}/shared/netutils/trace.c
${MICROPY_DIR}/shared/readline/readline.c ${MICROPY_DIR}/shared/readline/readline.c
${MICROPY_DIR}/shared/runtime/gchelper_thumb1.s
${MICROPY_DIR}/shared/runtime/gchelper_native.c ${MICROPY_DIR}/shared/runtime/gchelper_native.c
${MICROPY_DIR}/shared/runtime/interrupt_char.c ${MICROPY_DIR}/shared/runtime/interrupt_char.c
${MICROPY_DIR}/shared/runtime/mpirq.c ${MICROPY_DIR}/shared/runtime/mpirq.c
@ -123,6 +130,16 @@ set(MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/tinyusb/mp_usbd_runtime.c ${MICROPY_DIR}/shared/tinyusb/mp_usbd_runtime.c
) )
if(PICO_ARM)
list(APPEND MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/runtime/gchelper_thumb1.s
)
elseif(PICO_RISCV)
list(APPEND MICROPY_SOURCE_LIB
${MICROPY_DIR}/shared/runtime/gchelper_rv32i.s
)
endif()
set(MICROPY_SOURCE_DRIVERS set(MICROPY_SOURCE_DRIVERS
${MICROPY_DIR}/drivers/bus/softspi.c ${MICROPY_DIR}/drivers/bus/softspi.c
${MICROPY_DIR}/drivers/dht/dht.c ${MICROPY_DIR}/drivers/dht/dht.c
@ -178,7 +195,6 @@ set(MICROPY_SOURCE_QSTR
) )
set(PICO_SDK_COMPONENTS set(PICO_SDK_COMPONENTS
cmsis_core
hardware_adc hardware_adc
hardware_base hardware_base
hardware_boot_lock hardware_boot_lock
@ -222,6 +238,17 @@ set(PICO_SDK_COMPONENTS
tinyusb_device tinyusb_device
) )
if(PICO_ARM)
list(APPEND PICO_SDK_COMPONENTS
cmsis_core
)
elseif(PICO_RISCV)
list(APPEND PICO_SDK_COMPONENTS
hardware_hazard3
hardware_riscv
)
endif()
# Use our custom pico_float_micropython float implementation. This is needed for two reasons: # Use our custom pico_float_micropython float implementation. This is needed for two reasons:
# - to fix inf handling in pico-sdk's __wrap___aeabi_fadd(); # - to fix inf handling in pico-sdk's __wrap___aeabi_fadd();
# - so we can use our own libm functions, to fix inaccuracies in the pico-sdk versions. # - so we can use our own libm functions, to fix inaccuracies in the pico-sdk versions.
@ -243,7 +270,7 @@ if(PICO_RP2040)
${PICO_SDK_PATH}/src/rp2_common/pico_float/float_init_rom_rp2040.c ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_init_rom_rp2040.c
${PICO_SDK_PATH}/src/rp2_common/pico_float/float_v1_rom_shim_rp2040.S ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_v1_rom_shim_rp2040.S
) )
elseif(PICO_RP2350) elseif(PICO_RP2350 AND PICO_ARM)
target_sources(pico_float_micropython INTERFACE target_sources(pico_float_micropython INTERFACE
${PICO_SDK_PATH}/src/rp2_common/pico_float/float_aeabi_dcp.S ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_aeabi_dcp.S
${PICO_SDK_PATH}/src/rp2_common/pico_float/float_conv_m33.S ${PICO_SDK_PATH}/src/rp2_common/pico_float/float_conv_m33.S
@ -491,6 +518,12 @@ target_link_options(${MICROPY_TARGET} PRIVATE
-Wl,--wrap=runtime_init_clocks -Wl,--wrap=runtime_init_clocks
) )
if(PICO_RP2350)
target_link_options(${MICROPY_TARGET} PRIVATE
-Wl,--defsym=__micropy_extra_stack__=4096
)
endif()
# Apply optimisations to performance-critical source code. # Apply optimisations to performance-critical source code.
set_source_files_properties( set_source_files_properties(
${MICROPY_PY_DIR}/map.c ${MICROPY_PY_DIR}/map.c
@ -563,7 +596,7 @@ endif()
pico_add_extra_outputs(${MICROPY_TARGET}) pico_add_extra_outputs(${MICROPY_TARGET})
pico_find_compiler(PICO_COMPILER_SIZE ${PICO_GCC_TRIPLE}-size) pico_find_compiler_with_triples(PICO_COMPILER_SIZE "${PICO_GCC_TRIPLE}" size)
add_custom_command(TARGET ${MICROPY_TARGET} add_custom_command(TARGET ${MICROPY_TARGET}
POST_BUILD POST_BUILD

View File

@ -60,10 +60,8 @@
#endif #endif
#if PICO_RP2040 #if PICO_RP2040
#include "RP2040.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk #include "RP2040.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk
#elif PICO_RP2350 #elif PICO_RP2350 && PICO_ARM
#include "RP2350.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk #include "RP2350.h" // cmsis, for PendSV_IRQn and SCB/SCB_SCR_SEVONPEND_Msk
#else
#error Unknown processor
#endif #endif
#include "pico/aon_timer.h" #include "pico/aon_timer.h"
#include "shared/timeutils/timeutils.h" #include "shared/timeutils/timeutils.h"
@ -82,7 +80,9 @@ bi_decl(bi_program_feature_group_with_flags(BINARY_INFO_TAG_MICROPYTHON,
int main(int argc, char **argv) { int main(int argc, char **argv) {
// This is a tickless port, interrupts should always trigger SEV. // This is a tickless port, interrupts should always trigger SEV.
#if PICO_ARM
SCB->SCR |= SCB_SCR_SEVONPEND_Msk; SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
#endif
pendsv_init(); pendsv_init();
soft_timer_init(); soft_timer_init();

View File

@ -78,10 +78,16 @@
// MicroPython emitters // MicroPython emitters
#define MICROPY_PERSISTENT_CODE_LOAD (1) #define MICROPY_PERSISTENT_CODE_LOAD (1)
#if PICO_ARM
#define MICROPY_EMIT_THUMB (1) #define MICROPY_EMIT_THUMB (1)
#define MICROPY_EMIT_THUMB_ARMV7M (0)
#define MICROPY_EMIT_INLINE_THUMB (1) #define MICROPY_EMIT_INLINE_THUMB (1)
#if PICO_RP2040
#define MICROPY_EMIT_THUMB_ARMV7M (0)
#define MICROPY_EMIT_INLINE_THUMB_FLOAT (0) #define MICROPY_EMIT_INLINE_THUMB_FLOAT (0)
#endif
#elif PICO_RISCV
#define MICROPY_EMIT_RV32 (1)
#endif
// Optimisations // Optimisations
#define MICROPY_OPT_COMPUTED_GOTO (1) #define MICROPY_OPT_COMPUTED_GOTO (1)

View File

@ -31,10 +31,10 @@
#if PICO_RP2040 #if PICO_RP2040
#include "RP2040.h" #include "RP2040.h"
#elif PICO_RP2350 #elif PICO_RP2350 && PICO_ARM
#include "RP2350.h" #include "RP2350.h"
#else #elif PICO_RISCV
#error Unknown chip #include "pico/aon_timer.h"
#endif #endif
#if MICROPY_PY_NETWORK_CYW43 #if MICROPY_PY_NETWORK_CYW43
@ -43,6 +43,8 @@
static pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS]; static pendsv_dispatch_t pendsv_dispatch_table[PENDSV_DISPATCH_NUM_SLOTS];
void PendSV_Handler(void);
// Using the nowait variant here as softtimer updates PendSV from the loop of mp_wfe_or_timeout(), // Using the nowait variant here as softtimer updates PendSV from the loop of mp_wfe_or_timeout(),
// where we don't want the CPU event bit to be set. // where we don't want the CPU event bit to be set.
static recursive_mutex_nowait_t pendsv_mutex; static recursive_mutex_nowait_t pendsv_mutex;
@ -75,10 +77,16 @@ void pendsv_resume(void) {
void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) { void pendsv_schedule_dispatch(size_t slot, pendsv_dispatch_t f) {
pendsv_dispatch_table[slot] = f; pendsv_dispatch_table[slot] = f;
if (pendsv_mutex.mutex.enter_count == 0) { if (pendsv_mutex.mutex.enter_count == 0) {
#if PICO_ARM
// There is a race here where other core calls pendsv_suspend() before // There is a race here where other core calls pendsv_suspend() before
// ISR can execute, but dispatch will happen later when other core // ISR can execute, but dispatch will happen later when other core
// calls pendsv_resume(). // calls pendsv_resume().
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
#elif PICO_RISCV
struct timespec ts;
aon_timer_get_time(&ts);
aon_timer_enable_alarm(&ts, PendSV_Handler, false);
#endif
} else { } else {
#if MICROPY_PY_NETWORK_CYW43 #if MICROPY_PY_NETWORK_CYW43
CYW43_STAT_INC(PENDSV_DISABLED_COUNT); CYW43_STAT_INC(PENDSV_DISABLED_COUNT);