From e8502149381289f195c0e8e7aa520e72bac75595 Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Mon, 25 Oct 2021 12:26:06 -0500 Subject: [PATCH] Platform updates (#611) * Platform updates - Add PICO_RP2040=1 to rp2040 builds - Add new PICO_RP2040_B0/1/2_SUPPORTED macros and retailer chip specific code to use - Add doxygen to platform.h - Make pico.h includable from assembly (because header order is important and tricky) - split out platform_asm.h - Switch to using PICO_RP2040_B0_SUPPORTED in board headers --- .../include/boards/adafruit_feather_rp2040.h | 8 +- .../boards/adafruit_itsybitsy_rp2040.h | 8 +- .../include/boards/adafruit_qtpy_rp2040.h | 8 +- .../include/boards/adafruit_trinkey_qt2040.h | 8 +- .../boards/arduino_nano_rp2040_connect.h | 8 +- .../include/boards/melopero_shake_rp2040.h | 8 +- src/boards/include/boards/pico.h | 8 +- .../include/boards/pimoroni_interstate75.h | 8 +- .../include/boards/pimoroni_keybow2040.h | 8 +- src/boards/include/boards/pimoroni_pga2040.h | 8 +- .../include/boards/pimoroni_picolipo_16mb.h | 8 +- .../include/boards/pimoroni_picolipo_4mb.h | 8 +- .../include/boards/pimoroni_picosystem.h | 8 +- .../include/boards/pimoroni_plasma2040.h | 8 +- src/boards/include/boards/pimoroni_tiny2040.h | 8 +- src/boards/include/boards/sparkfun_micromod.h | 8 +- src/boards/include/boards/sparkfun_promicro.h | 8 +- .../include/boards/sparkfun_thingplus.h | 8 +- src/common/pico_base/include/pico.h | 9 +- src/common/pico_base/include/pico/config.h | 2 +- src/common/pico_base/include/pico/error.h | 4 + src/common/pico_base/include/pico/types.h | 3 + .../pico_platform/include/pico/platform.h | 2 +- .../include/hardware/platform_defs.h | 17 +- src/rp2_common.cmake | 2 +- .../hardware_irq/irq_handler_chain.S | 2 +- src/rp2_common/pico_bit_ops/bit_ops_aeabi.S | 10 +- .../pico_bootrom/include/pico/bootrom.h | 104 +++--- .../pico_bootsel_via_double_reset.c | 3 +- src/rp2_common/pico_double/double_aeabi.S | 8 +- src/rp2_common/pico_double/double_init_rom.c | 4 +- .../pico_double/double_v1_rom_shim.S | 2 +- .../rp2040_usb_device_enumeration.c | 23 +- src/rp2_common/pico_float/float_aeabi.S | 10 +- src/rp2_common/pico_float/float_init_rom.c | 4 +- src/rp2_common/pico_float/float_v1_rom_shim.S | 2 +- src/rp2_common/pico_mem_ops/mem_ops_aeabi.S | 9 +- .../pico_platform/include/pico/asm_helper.S | 8 +- .../pico_platform/include/pico/platform.h | 329 +++++++++++++++--- src/rp2_common/pico_runtime/runtime.c | 4 - src/rp2_common/pico_standard_link/crt0.S | 3 +- 41 files changed, 431 insertions(+), 277 deletions(-) diff --git a/src/boards/include/boards/adafruit_feather_rp2040.h b/src/boards/include/boards/adafruit_feather_rp2040.h index cc0b9a6..2da8e70 100644 --- a/src/boards/include/boards/adafruit_feather_rp2040.h +++ b/src/boards/include/boards/adafruit_feather_rp2040.h @@ -86,12 +86,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/adafruit_itsybitsy_rp2040.h b/src/boards/include/boards/adafruit_itsybitsy_rp2040.h index 26cde1d..f9d27e9 100644 --- a/src/boards/include/boards/adafruit_itsybitsy_rp2040.h +++ b/src/boards/include/boards/adafruit_itsybitsy_rp2040.h @@ -89,12 +89,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/adafruit_qtpy_rp2040.h b/src/boards/include/boards/adafruit_qtpy_rp2040.h index 299249d..24184c2 100644 --- a/src/boards/include/boards/adafruit_qtpy_rp2040.h +++ b/src/boards/include/boards/adafruit_qtpy_rp2040.h @@ -88,12 +88,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/adafruit_trinkey_qt2040.h b/src/boards/include/boards/adafruit_trinkey_qt2040.h index 843558b..f9b49df 100644 --- a/src/boards/include/boards/adafruit_trinkey_qt2040.h +++ b/src/boards/include/boards/adafruit_trinkey_qt2040.h @@ -66,12 +66,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/arduino_nano_rp2040_connect.h b/src/boards/include/boards/arduino_nano_rp2040_connect.h index 24f52a1..39c6564 100644 --- a/src/boards/include/boards/arduino_nano_rp2040_connect.h +++ b/src/boards/include/boards/arduino_nano_rp2040_connect.h @@ -77,12 +77,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/melopero_shake_rp2040.h b/src/boards/include/boards/melopero_shake_rp2040.h index a23a373..d07ca61 100644 --- a/src/boards/include/boards/melopero_shake_rp2040.h +++ b/src/boards/include/boards/melopero_shake_rp2040.h @@ -84,12 +84,8 @@ #define PICO_FLASH_SIZE_BYTES (16 * 1024 * 1024) #endif -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pico.h b/src/boards/include/boards/pico.h index 313d085..9e7f537 100644 --- a/src/boards/include/boards/pico.h +++ b/src/boards/include/boards/pico.h @@ -77,12 +77,8 @@ // Drive high to force power supply into PWM mode (lower ripple on 3V3 at light loads) #define PICO_SMPS_MODE_PIN 23 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 1 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 1 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 1 #endif #endif diff --git a/src/boards/include/boards/pimoroni_interstate75.h b/src/boards/include/boards/pimoroni_interstate75.h index e6eec40..e2621b0 100644 --- a/src/boards/include/boards/pimoroni_interstate75.h +++ b/src/boards/include/boards/pimoroni_interstate75.h @@ -174,12 +174,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_keybow2040.h b/src/boards/include/boards/pimoroni_keybow2040.h index 8cd6c1b..43772e8 100644 --- a/src/boards/include/boards/pimoroni_keybow2040.h +++ b/src/boards/include/boards/pimoroni_keybow2040.h @@ -147,12 +147,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_pga2040.h b/src/boards/include/boards/pimoroni_pga2040.h index 90340fa..980f168 100644 --- a/src/boards/include/boards/pimoroni_pga2040.h +++ b/src/boards/include/boards/pimoroni_pga2040.h @@ -72,12 +72,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_picolipo_16mb.h b/src/boards/include/boards/pimoroni_picolipo_16mb.h index a0310fb..338977b 100644 --- a/src/boards/include/boards/pimoroni_picolipo_16mb.h +++ b/src/boards/include/boards/pimoroni_picolipo_16mb.h @@ -85,12 +85,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_picolipo_4mb.h b/src/boards/include/boards/pimoroni_picolipo_4mb.h index 9374f41..871ed83 100644 --- a/src/boards/include/boards/pimoroni_picolipo_4mb.h +++ b/src/boards/include/boards/pimoroni_picolipo_4mb.h @@ -85,12 +85,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_picosystem.h b/src/boards/include/boards/pimoroni_picosystem.h index 34eb643..1e7c80e 100644 --- a/src/boards/include/boards/pimoroni_picosystem.h +++ b/src/boards/include/boards/pimoroni_picosystem.h @@ -156,12 +156,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_plasma2040.h b/src/boards/include/boards/pimoroni_plasma2040.h index 895f264..226aaf5 100644 --- a/src/boards/include/boards/pimoroni_plasma2040.h +++ b/src/boards/include/boards/pimoroni_plasma2040.h @@ -130,12 +130,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/pimoroni_tiny2040.h b/src/boards/include/boards/pimoroni_tiny2040.h index 81605b3..51d17f6 100644 --- a/src/boards/include/boards/pimoroni_tiny2040.h +++ b/src/boards/include/boards/pimoroni_tiny2040.h @@ -120,12 +120,8 @@ #endif // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/sparkfun_micromod.h b/src/boards/include/boards/sparkfun_micromod.h index e6ef44f..0c6e568 100644 --- a/src/boards/include/boards/sparkfun_micromod.h +++ b/src/boards/include/boards/sparkfun_micromod.h @@ -79,12 +79,8 @@ // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/sparkfun_promicro.h b/src/boards/include/boards/sparkfun_promicro.h index 82e96cf..45bb4a2 100644 --- a/src/boards/include/boards/sparkfun_promicro.h +++ b/src/boards/include/boards/sparkfun_promicro.h @@ -79,12 +79,8 @@ // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/boards/include/boards/sparkfun_thingplus.h b/src/boards/include/boards/sparkfun_thingplus.h index b2e4932..d1e69d5 100644 --- a/src/boards/include/boards/sparkfun_thingplus.h +++ b/src/boards/include/boards/sparkfun_thingplus.h @@ -85,12 +85,8 @@ // All boards have B1 RP2040 -#ifndef PICO_FLOAT_SUPPORT_ROM_V1 -#define PICO_FLOAT_SUPPORT_ROM_V1 0 -#endif - -#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 -#define PICO_DOUBLE_SUPPORT_ROM_V1 0 +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 0 #endif #endif diff --git a/src/common/pico_base/include/pico.h b/src/common/pico_base/include/pico.h index c7537b1..1b73651 100644 --- a/src/common/pico_base/include/pico.h +++ b/src/common/pico_base/include/pico.h @@ -8,9 +8,12 @@ #define PICO_H_ /** \file pico.h -* \defgroup pico_base pico_base -* -* Core types and macros for the Raspberry Pi Pico SDK. This header is intended to be included by all source code + * \defgroup pico_base pico_base + * + * Core types and macros for the Raspberry Pi Pico SDK. This header is intended to be included by all source code + * as it includes configuration headers and overrides in the correct order + * + * This header may be included by assembly code */ #include "pico/types.h" diff --git a/src/common/pico_base/include/pico/config.h b/src/common/pico_base/include/pico/config.h index 20f32cb..8d69269 100644 --- a/src/common/pico_base/include/pico/config.h +++ b/src/common/pico_base/include/pico/config.h @@ -8,7 +8,7 @@ #define PICO_CONFIG_H_ // ----------------------------------------------------- -// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO +// NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLY CODE SO // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES // OR USE #ifndef __ASSEMBLER__ guards // ------------- diff --git a/src/common/pico_base/include/pico/error.h b/src/common/pico_base/include/pico/error.h index 722a696..fadb45e 100644 --- a/src/common/pico_base/include/pico/error.h +++ b/src/common/pico_base/include/pico/error.h @@ -7,6 +7,8 @@ #ifndef _PICO_ERROR_H #define _PICO_ERROR_H +#ifndef __ASSEMBLER__ + /*! * Common return codes from pico_sdk methods that return a status */ @@ -18,4 +20,6 @@ enum { PICO_ERROR_NO_DATA = -3, }; +#endif // !__ASSEMBLER__ + #endif \ No newline at end of file diff --git a/src/common/pico_base/include/pico/types.h b/src/common/pico_base/include/pico/types.h index 6b8e66f..8e1627c 100644 --- a/src/common/pico_base/include/pico/types.h +++ b/src/common/pico_base/include/pico/types.h @@ -7,6 +7,8 @@ #ifndef _PICO_TYPES_H #define _PICO_TYPES_H +#ifndef __ASSEMBLER__ + #include "pico/assert.h" #include @@ -89,3 +91,4 @@ typedef struct { #define bool_to_bit(x) ((uint)!!(x)) #endif +#endif diff --git a/src/host/pico_platform/include/pico/platform.h b/src/host/pico_platform/include/pico/platform.h index 499bdf6..98363a3 100644 --- a/src/host/pico_platform/include/pico/platform.h +++ b/src/host/pico_platform/include/pico/platform.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define __not_in_flash(grup) +#define __not_in_flash(group) #define __not_in_flash_func(func) func #define __no_inline_not_in_flash_func(func) #define __in_flash(group) diff --git a/src/rp2040/hardware_regs/include/hardware/platform_defs.h b/src/rp2040/hardware_regs/include/hardware/platform_defs.h index 055ab1d..f3193da 100644 --- a/src/rp2040/hardware_regs/include/hardware/platform_defs.h +++ b/src/rp2040/hardware_regs/include/hardware/platform_defs.h @@ -7,7 +7,7 @@ #ifndef _HARDWARE_PLATFORM_DEFS_H #define _HARDWARE_PLATFORM_DEFS_H -// This header is included from C and assembler - only define macros +// This header is included from C and assembler - intended mostly for #defines; guard other stuff with #ifdef __ASSEMBLER__ #ifndef _u #ifdef __ASSEMBLER__ @@ -38,20 +38,5 @@ #define XOSC_MHZ _u(12) -// PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_standard_link -#ifndef PICO_STACK_SIZE -#define PICO_STACK_SIZE _u(0x800) -#endif - -// PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_standard_link -#ifndef PICO_HEAP_SIZE -#define PICO_HEAP_SIZE _u(0x800) -#endif - -// PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_runtime -#ifndef PICO_NO_RAM_VECTOR_TABLE -#define PICO_NO_RAM_VECTOR_TABLE 0 -#endif - #endif diff --git a/src/rp2_common.cmake b/src/rp2_common.cmake index 67a1a7b..c04e551 100644 --- a/src/rp2_common.cmake +++ b/src/rp2_common.cmake @@ -37,7 +37,7 @@ function(pico_add_extra_outputs TARGET) add_custom_command(TARGET ${TARGET}_symlinked POST_BUILD COMMAND rm -f "${PICO_SYMLINK_ELF_AS_FILENAME}" COMMAND ln -s -r $ "${PICO_SYMLINK_ELF_AS_FILENAME}" - COMMENT "Symlinking from ${PICO_SYMLINK_ELF_AS_FILENAME} to $" + COMMENT "Symlinking from ${PICO_SYMLINK_ELF_AS_FILENAME} to ${TARGET}" ) endif () # PICO_CMAKE_CONFIG: PICO_NO_UF2, Disable UF2 output, type=bool, default=0, group=build diff --git a/src/rp2_common/hardware_irq/irq_handler_chain.S b/src/rp2_common/hardware_irq/irq_handler_chain.S index 6a8a4b6..7d7be7d 100644 --- a/src/rp2_common/hardware_irq/irq_handler_chain.S +++ b/src/rp2_common/hardware_irq/irq_handler_chain.S @@ -4,7 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "hardware/platform_defs.h" +#include "pico.h" #include "hardware/irq.h" #if !PICO_DISABLE_SHARED_IRQ_HANDLERS diff --git a/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S b/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S index 7c0b42c..eba839e 100644 --- a/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S +++ b/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S @@ -9,6 +9,8 @@ .thumb #include "pico/asm_helper.S" +#include "pico/bootrom.h" + __pre_init __aeabi_bits_init, 00010 .macro bits_section name @@ -24,10 +26,10 @@ __pre_init __aeabi_bits_init, 00010 .equ BITS_FUNC_COUNT, 4 .align 4 aeabi_bits_funcs: - .word rom_table_code('P','3') // popcount32 - .word rom_table_code('L','3') // clz32 - .word rom_table_code('T','3') // ctz32 - .word rom_table_code('R','3') // reverse32 + .word ROM_FUNC_POPCOUNT32 + .word ROM_FUNC_CLZ32 + .word ROM_FUNC_CTZ32 + .word ROM_FUNC_REVERSE32 aeabi_bits_funcs_end: .section .text diff --git a/src/rp2_common/pico_bootrom/include/pico/bootrom.h b/src/rp2_common/pico_bootrom/include/pico/bootrom.h index cd9b155..e557893 100644 --- a/src/rp2_common/pico_bootrom/include/pico/bootrom.h +++ b/src/rp2_common/pico_bootrom/include/pico/bootrom.h @@ -12,8 +12,60 @@ /** \file bootrom.h * \defgroup pico_bootrom pico_bootrom * Access to functions and data in the RP2040 bootrom + * + * This header may be included by assembly code */ +// ROM FUNCTIONS + +#define ROM_FUNC_POPCOUNT32 ROM_TABLE_CODE('P', '3') +#define ROM_FUNC_REVERSE32 ROM_TABLE_CODE('R', '3') +#define ROM_FUNC_CLZ32 ROM_TABLE_CODE('L', '3') +#define ROM_FUNC_CTZ32 ROM_TABLE_CODE('T', '3') +#define ROM_FUNC_MEMSET ROM_TABLE_CODE('M', 'S') +#define ROM_FUNC_MEMSET4 ROM_TABLE_CODE('S', '4') +#define ROM_FUNC_MEMCPY ROM_TABLE_CODE('M', 'C') +#define ROM_FUNC_MEMCPY44 ROM_TABLE_CODE('C', '4') +#define ROM_FUNC_RESET_USB_BOOT ROM_TABLE_CODE('U', 'B') +#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F') +#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X') +#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E') +#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P') +#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C') +#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X') + +/*! \brief Return a bootrom lookup code based on two ASCII characters + * \ingroup pico_bootrom + * + * These codes are uses to lookup data or function addresses in the bootrom + * + * \param c1 the first character + * \param c2 the second character + * \return the 'code' to use in rom_func_lookup() or rom_data_lookup() + */ +#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8)) + +#ifndef __ASSEMBLER__ + +// ROM FUNCTION SIGNATURES + +typedef uint32_t (*rom_popcount32_fn)(uint32_t); +typedef uint32_t (*rom_reverse32_fn)(uint32_t); +typedef uint32_t (*rom_clz32_fn)(uint32_t); +typedef uint32_t (*rom_ctz32_fn)(uint32_t); +typedef uint8_t *(*rom_memset_fn)(uint8_t *, uint8_t, uint32_t); +typedef uint32_t *(*rom_memset4_fn)(uint32_t *, uint8_t, uint32_t); +typedef uint32_t *(*rom_memcpy_fn)(uint8_t *, const uint8_t *, uint32_t); +typedef uint32_t *(*rom_memcpy44_fn)(uint32_t *, const uint32_t *, uint32_t); +typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t); +typedef rom_reset_usb_boot_fn reset_usb_boot_fn; // kept for backwards compatibility +typedef void (*rom_connect_internal_flash_fn)(void); +typedef void (*rom_flash_exit_xip_fn)(void); +typedef void (*rom_flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint8_t); +typedef void (*rom_flash_range_program_fn)(uint32_t, const uint8_t*, size_t); +typedef void (*rom_flash_flush_cache_fn)(void); +typedef void (*rom_flash_enter_cmd_xip_fn)(void); + #ifdef __cplusplus extern "C" { #endif @@ -28,10 +80,9 @@ extern "C" { * \return the 'code' to use in rom_func_lookup() or rom_data_lookup() */ static inline uint32_t rom_table_code(uint8_t c1, uint8_t c2) { - return (((uint)c2) << 8u) | (uint)c1; + return ROM_TABLE_CODE((uint32_t) c1, (uint32_t) c2); } - /*! * \brief Lookup a bootrom function by code * \ingroup pico_bootrom @@ -61,54 +112,6 @@ void *rom_data_lookup(uint32_t code); */ bool rom_funcs_lookup(uint32_t *table, unsigned int count); -// The following is a list of bootrom functions available via rom_func_lookup and their signature - -typedef uint32_t (*rom_popcount32_fn)(uint32_t); -#define ROM_FUNC_POPCOUNT32 rom_table_code('P', '3') - -typedef uint32_t (*rom_reverse32_fn)(uint32_t); -#define ROM_FUNC_REVERSE32 rom_table_code('R', '3') - -typedef uint32_t (*rom_clz32_fn)(uint32_t); -#define ROM_FUNC_CLZ32 rom_table_code('L', '3') - -typedef uint32_t (*rom_ctz32_fn)(uint32_t); -#define ROM_FUNC_CTZ32 rom_table_code('T', '3') - -typedef uint8_t *(*rom_memset_fn)(uint8_t *, uint8_t, uint32_t); -#define ROM_FUNC_MEMSET rom_table_code('M', 'S') - -typedef uint32_t *(*rom_memset4_fn)(uint32_t *, uint8_t, uint32_t); -#define ROM_FUNC_MEMSET4 rom_table_code('S', '4') - -typedef uint32_t *(*rom_memcpy_fn)(uint8_t *, const uint8_t *, uint32_t); -#define ROM_FUNC_MEMCPY rom_table_code('M', 'C') - -typedef uint32_t *(*rom_memcpy44_fn)(uint32_t *, const uint32_t *, uint32_t); -#define ROM_FUNC_MEMCPY44 rom_table_code('C', '4') - -typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t); -typedef rom_reset_usb_boot_fn reset_usb_boot_fn; // kept for backwards compatibility -#define ROM_FUNC_RESET_USB_BOOT rom_table_code('U', 'B') - -typedef void (*rom_connect_internal_flash_fn)(void); -#define ROM_FUNC_CONNECT_INTERNAL_FLASH rom_table_code('I', 'F') - -typedef void (*rom_flash_exit_xip_fn)(void); -#define ROM_FUNC_FLASH_EXIT_XIP rom_table_code('E', 'X') - -typedef void (*rom_flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint8_t); -#define ROM_FUNC_FLASH_RANGE_ERASE rom_table_code('R', 'E') - -typedef void (*rom_flash_range_program_fn)(uint32_t, const uint8_t*, size_t); -#define ROM_FUNC_FLASH_RANGE_PROGRAM rom_table_code('R', 'P') - -typedef void (*rom_flash_flush_cache_fn)(void); -#define ROM_FUNC_FLASH_FLUSH_CACHE rom_table_code('F', 'C') - -typedef void (*rom_flash_enter_cmd_xip_fn)(void); -#define ROM_FUNC_FLASH_ENTER_CMD_XIP rom_table_code('C', 'X') - // Bootrom function: rom_table_lookup // Returns the 32 bit pointer into the ROM if found or NULL otherwise. typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); @@ -155,4 +158,5 @@ static inline void __attribute__((noreturn)) reset_usb_boot(uint32_t usb_activit } #endif +#endif // !__ASSEMBLER__ #endif diff --git a/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c b/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c index 595a2d5..d333ab2 100644 --- a/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c +++ b/src/rp2_common/pico_bootsel_via_double_reset/pico_bootsel_via_double_reset.c @@ -43,8 +43,7 @@ static const uint32_t magic_token[] = { static uint32_t __uninitialized_ram(magic_location)[count_of(magic_token)]; -/*! \brief Check for double reset and enter BOOTSEL mode if detected - * \ingroup pico_bootsel_via_double_reset +/* Check for double reset and enter BOOTSEL mode if detected * * This function is registered to run automatically before main(). The * algorithm is: diff --git a/src/rp2_common/pico_double/double_aeabi.S b/src/rp2_common/pico_double/double_aeabi.S index a871e43..0c59738 100644 --- a/src/rp2_common/pico_double/double_aeabi.S +++ b/src/rp2_common/pico_double/double_aeabi.S @@ -83,7 +83,7 @@ __check_nan_d2: .macro table_tail_call SF_TABLE_OFFSET push {r3, r4} -#if PICO_DOUBLE_SUPPORT_ROM_V1 +#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED #ifndef NDEBUG movs r3, #0 mov ip, r3 @@ -99,12 +99,12 @@ __check_nan_d2: push {r3, r4} ldr r3, =sd_table ldr r3, [r3, #\SF_TABLE_OFFSET] -#if PICO_DOUBLE_SUPPORT_ROM_V1 +#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED mov ip, pc #endif str r3, [sp, #4] pop {r3, pc} -#if PICO_DOUBLE_SUPPORT_ROM_V1 +#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED .byte \SF_TABLE_OFFSET, 0xdf .word \shim #endif @@ -733,7 +733,7 @@ sincos_shim_bootstrap: push {r2, r3, r4} movs r3, #0x13 ldrb r3, [r3] -#if PICO_DOUBLE_SUPPORT_ROM_V1 +#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED cmp r3, #1 bne 1f ldr r3, =dsincos_shim diff --git a/src/rp2_common/pico_double/double_init_rom.c b/src/rp2_common/pico_double/double_init_rom.c index 79ecff6..af6f6a2 100644 --- a/src/rp2_common/pico_double/double_init_rom.c +++ b/src/rp2_common/pico_double/double_init_rom.c @@ -12,7 +12,7 @@ // IT IS ***NOT*** SAFE TO CALL THESE FUNCTION POINTERS FROM ARBITRARY CODE uint32_t sd_table[SF_TABLE_V2_SIZE / 2]; -#if !PICO_DOUBLE_SUPPORT_ROM_V1 +#if !(PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED) static __attribute__((noreturn)) void missing_double_func_shim(void) { panic("missing double function"); } @@ -23,7 +23,7 @@ void __attribute__((weak)) *sf_clz_func; void __aeabi_double_init(void) { int rom_version = rp2040_rom_version(); -#if PICO_DOUBLE_SUPPORT_ROM_V1 +#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED if (rom_version == 1) { // this is a little tricky.. we only want to pull in a shim if the corresponding function diff --git a/src/rp2_common/pico_double/double_v1_rom_shim.S b/src/rp2_common/pico_double/double_v1_rom_shim.S index a9b59cd..7a14ca4 100644 --- a/src/rp2_common/pico_double/double_v1_rom_shim.S +++ b/src/rp2_common/pico_double/double_v1_rom_shim.S @@ -63,7 +63,7 @@ regular_func double_table_shim_on_use_helper str r0, [sp, #12] pop {r0-r2, pc} -#if PICO_DOUBLE_SUPPORT_ROM_V1 +#if PICO_DOUBLE_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED // Note that the V1 ROM has no double support, so this is basically the identical // library, and shim inter-function calls do not bother to redirect back thru the // wrapper functions diff --git a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c index 9158320..e1073ca 100644 --- a/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c +++ b/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c @@ -22,16 +22,21 @@ static void hw_enumeration_fix_force_ls_j(void); static void hw_enumeration_fix_finish(void); void rp2040_usb_device_enumeration_fix(void) { - // After coming out of reset, the hardware expects 800us of LS_J (linestate J) time - // before it will move to the connected state. However on a hub that broadcasts packets - // for other devices this isn't the case. The plan here is to wait for the end of the bus - // reset, force an LS_J for 1ms and then switch control back to the USB phy. Unfortunately - // this requires us to use GPIO15 as there is no other way to force the input path. - // We only need to force DP as DM can be left at zero. It will be gated off by GPIO - // logic if it isn't func selected. +#if PICO_RP2040_B0_SUPPORTED || PICO_RP2040_B1_SUPPORTED + // Actually check for B0/B1 h/w + if (rp2040_chip_version() == 1) { + // After coming out of reset, the hardware expects 800us of LS_J (linestate J) time + // before it will move to the connected state. However on a hub that broadcasts packets + // for other devices this isn't the case. The plan here is to wait for the end of the bus + // reset, force an LS_J for 1ms and then switch control back to the USB phy. Unfortunately + // this requires us to use GPIO15 as there is no other way to force the input path. + // We only need to force DP as DM can be left at zero. It will be gated off by GPIO + // logic if it isn't func selected. - // Wait SE0 phase will call force ls_j phase which will call finish phase - hw_enumeration_fix_wait_se0(); + // Wait SE0 phase will call force ls_j phase which will call finish phase + hw_enumeration_fix_wait_se0(); + } +#endif } static inline uint8_t hw_line_state(void) { diff --git a/src/rp2_common/pico_float/float_aeabi.S b/src/rp2_common/pico_float/float_aeabi.S index b901d30..db393df 100644 --- a/src/rp2_common/pico_float/float_aeabi.S +++ b/src/rp2_common/pico_float/float_aeabi.S @@ -80,7 +80,7 @@ __check_nan_f2: #endif .macro table_tail_call SF_TABLE_OFFSET -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED #ifndef NDEBUG movs r3, #0 mov ip, r3 @@ -94,11 +94,11 @@ __check_nan_f2: .macro shimmable_table_tail_call SF_TABLE_OFFSET shim ldr r3, =sf_table ldr r3, [r3, #\SF_TABLE_OFFSET] -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED mov ip, pc #endif bx r3 -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED .byte \SF_TABLE_OFFSET, 0xdf .word \shim #endif @@ -584,13 +584,13 @@ wrapper_func __aeabi_f2d float_wrapper_section srqtf wrapper_func_f1 sqrtf -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED // check for negative asrs r1, r0, #23 bmi 1f #endif table_tail_call SF_TABLE_FSQRT -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED 1: mvns r0, r1 cmp r0, #255 diff --git a/src/rp2_common/pico_float/float_init_rom.c b/src/rp2_common/pico_float/float_init_rom.c index b9a350a..646c0e9 100644 --- a/src/rp2_common/pico_float/float_init_rom.c +++ b/src/rp2_common/pico_float/float_init_rom.c @@ -13,7 +13,7 @@ uint32_t sf_table[SF_TABLE_V2_SIZE / 2]; void __attribute__((weak)) *sf_clz_func; -#if !PICO_FLOAT_SUPPORT_ROM_V1 +#if !(PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED) static __attribute__((noreturn)) void missing_float_func_shim(void) { panic(""); } @@ -22,7 +22,7 @@ static __attribute__((noreturn)) void missing_float_func_shim(void) { void __aeabi_float_init(void) { int rom_version = rp2040_rom_version(); void *rom_table = rom_data_lookup(rom_table_code('S', 'F')); -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED if (rom_version == 1) { memcpy(&sf_table, rom_table, SF_TABLE_V1_SIZE); extern void float_table_shim_on_use_helper(void); diff --git a/src/rp2_common/pico_float/float_v1_rom_shim.S b/src/rp2_common/pico_float/float_v1_rom_shim.S index a29925e..d7541a4 100644 --- a/src/rp2_common/pico_float/float_v1_rom_shim.S +++ b/src/rp2_common/pico_float/float_v1_rom_shim.S @@ -6,7 +6,7 @@ #include "pico/asm_helper.S" -#if PICO_FLOAT_SUPPORT_ROM_V1 +#if PICO_FLOAT_SUPPORT_ROM_V1 && PICO_RP2040_B0_SUPPORTED .syntax unified .cpu cortex-m0plus .thumb diff --git a/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S b/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S index e07a9fe..e52e188 100644 --- a/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S +++ b/src/rp2_common/pico_mem_ops/mem_ops_aeabi.S @@ -9,6 +9,7 @@ .thumb #include "pico/asm_helper.S" +#include "pico/bootrom.h" __pre_init __aeabi_mem_init, 00001 @@ -34,10 +35,10 @@ __pre_init __aeabi_mem_init, 00001 .align 2 aeabi_mem_funcs: - .word rom_table_code('M','S') - .word rom_table_code('M','C') - .word rom_table_code('S','4') - .word rom_table_code('C','4') + .word ROM_FUNC_MEMSET + .word ROM_FUNC_MEMCPY + .word ROM_FUNC_MEMSET4 + .word ROM_FUNC_MEMCPY44 aeabi_mem_funcs_end: .section .text diff --git a/src/rp2_common/pico_platform/include/pico/asm_helper.S b/src/rp2_common/pico_platform/include/pico/asm_helper.S index 050e6a5..3e01c66 100644 --- a/src/rp2_common/pico_platform/include/pico/asm_helper.S +++ b/src/rp2_common/pico_platform/include/pico/asm_helper.S @@ -4,13 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "hardware/platform_defs.h" -#include "pico/config.h" - -#define WRAPPER_FUNC_NAME(x) __wrap_##x -#define SECTION_NAME(x) .text.##x -#define RAM_SECTION_NAME(x) .time_critical.##x -#define rom_table_code(c1, c2) ((c1) | ((c2) << 8)) +#include "pico.h" // do not put align in here as it is used mid function sometimes .macro regular_func x diff --git a/src/rp2_common/pico_platform/include/pico/platform.h b/src/rp2_common/pico_platform/include/pico/platform.h index d625790..ee1d360 100644 --- a/src/rp2_common/pico_platform/include/pico/platform.h +++ b/src/rp2_common/pico_platform/include/pico/platform.h @@ -7,91 +7,304 @@ #ifndef _PICO_PLATFORM_H_ #define _PICO_PLATFORM_H_ +/** \file platform.h + * \defgroup pico_platform pico_platform + * + * Macros and definitions (and functions when included by non assembly code) for the RP2 family device / architecture + * to provide a common abstraction over low level compiler / platform specifics. + * + * This header may be included by assembly code + */ + +#include "hardware/platform_defs.h" + +// Marker for builds targeting the RP2040 +#define PICO_RP2040 1 + +// PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_platform +#ifndef PICO_STACK_SIZE +#define PICO_STACK_SIZE _u(0x800) +#endif + +// PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_platform +#ifndef PICO_HEAP_SIZE +#define PICO_HEAP_SIZE _u(0x800) +#endif + +// PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_platform +#ifndef PICO_NO_RAM_VECTOR_TABLE +#define PICO_NO_RAM_VECTOR_TABLE 0 +#endif + +// PICO_CONFIG: PICO_RP2040_B0_SUPPORTED, Whether to include any specific software support for RP2040 B0 revision, type=bool, default=1, advanced=true, group=pico_platform +#ifndef PICO_RP2040_B0_SUPPORTED +#define PICO_RP2040_B0_SUPPORTED 1 +#endif + +// PICO_CONFIG: PICO_FLOAT_SUPPORT_ROM_V1, Include float support code for RP2040 B0 when that chip revision is supported , type=bool, default=1, advanced=true, group=pico_platform +#ifndef PICO_FLOAT_SUPPORT_ROM_V1 +#define PICO_FLOAT_SUPPORT_ROM_V1 1 +#endif + +// PICO_CONFIG: PICO_DOUBLE_SUPPORT_ROM_V1, Include double support code for RP2040 B0 when that chip revision is supported , type=bool, default=1, advanced=true, group=pico_platform +#ifndef PICO_DOUBLE_SUPPORT_ROM_V1 +#define PICO_DOUBLE_SUPPORT_ROM_V1 1 +#endif + + +// PICO_CONFIG: PICO_RP2040_B1_SUPPORTED, Whether to include any specific software support for RP2040 B1 revision, type=bool, default=1, advanced=true, group=pico_platform +#ifndef PICO_RP2040_B1_SUPPORTED +#define PICO_RP2040_B1_SUPPORTED 1 +#endif + +// PICO_CONFIG: PICO_RP2040_B2_SUPPORTED, Whether to include any specific software support for RP2040 B2 revision, type=bool, default=1, advanced=true, group=pico_platform +#ifndef PICO_RP2040_B2_SUPPORTED +#define PICO_RP2040_B2_SUPPORTED 1 +#endif + +// --- remainder of file is not included by assembly code --- + +#ifndef __ASSEMBLER__ + #include #include "pico/types.h" -#include "hardware/platform_defs.h" #ifdef __cplusplus extern "C" { #endif -/** \file platform.h -* \defgroup pico_platform pico_platform -* Compiler definitions for the selected PICO_PLATFORM -*/ - +/*! \brief Marker for an interrupt handler + * \ingroup pico_platform + * For example an IRQ handler function called my_interrupt_handler: + * + * void __isr my_interrupt_handler(void) { + */ #define __isr -// Section naming macros +/*! \brief Section attribute macro for placement in RAM after the `.data` section + * \ingroup pico_platform + * + * For example a 400 element `uint32_t` array placed after the .data section + * + * uint32_t __after_data("my_group_name") a_big_array[400]; + * + * The section attribute is `.after_data.` + * + * \param group a string suffix to use in the section name to distinguish groups that can be linker + * garbage-collected independently + */ #define __after_data(group) __attribute__((section(".after_data." group))) + +/*! \brief Section attribute macro for placement not in flash (i.e in RAM) + * \ingroup pico_platform + * + * For example a 3 element `uint32_t` array placed in RAM (even though it is `static const`) + * + * static const uint32_t __not_in_flash("my_group_name") an_array[3]; + * + * The section attribute is `.time_critical.` + * + * \param group a string suffix to use in the section name to distinguish groups that can be linker + * garbage-collected independently + */ #define __not_in_flash(group) __attribute__((section(".time_critical." group))) + +/*! \brief Section attribute macro for placement in the SRAM bank 4 (known as "scratch X") + * \ingroup pico_platform + * + * Scratch X is commonly used for critical data and functions accessed only by one core (when only + * one core is accessing the RAM bank, there is no opportunity for stalls) + * + * For example a `uint32_t` variable placed in "scratch X" + * + * uint32_t __scratch_x("my_group_name") foo = 23; + * + * The section attribute is `.scratch_x.` + * + * \param group a string suffix to use in the section name to distinguish groups that can be linker + * garbage-collected independently + */ #define __scratch_x(group) __attribute__((section(".scratch_x." group))) + +/*! \brief Section attribute macro for placement in the SRAM bank 5 (known as "scratch Y") + * \ingroup pico_platform + * + * Scratch Y is commonly used for critical data and functions accessed only by one core (when only + * one core is accessing the RAM bank, there is no opportunity for stalls) + * + * For example a `uint32_t` variable placed in "scratch Y" + * + * uint32_t __scratch_y("my_group_name") foo = 23; + * + * The section attribute is `.scratch_y.` + * + * \param group a string suffix to use in the section name to distinguish groups that can be linker + * garbage-collected independently + */ #define __scratch_y(group) __attribute__((section(".scratch_y." group))) + +/*! \brief Section attribute macro for data that is to be left uninitialized + * \ingroup pico_platform + * + * Data marked this way will retain its value across a reset (normally uninitialized data - in the .bss + * section) is initialized to zero during runtime initialization + * + * For example a `uint32_t` foo that will retain its value if the program is restarted by reset. + * + * uint32_t __uninitialized_ram("my_group_name") foo; + * + * The section attribute is `.uninitialized_ram.` + * + * \param group a string suffix to use in the section name to distinguish groups that can be linker + * garbage-collected independently + */ #define __uninitialized_ram(group) __attribute__((section(".uninitialized_ram." #group))) group -// For use with PICO_COPY_TO_RAM: + +/*! \brief Section attribute macro for placement in flash even in a COPY_TO_RAM binary + * \ingroup pico_platform + * + * For example a `uint32_t` variable explicitly placed in flash (it will hard fault if you attempt to write it!) + * + * uint32_t __in_flash("my_group_name") foo = 23; + * + * The section attribute is `.flashdata.` + * + * \param group a string suffix to use in the section name to distinguish groups that can be linker + * garbage-collected independently + */ #define __in_flash(group) __attribute__((section(".flashdata" group))) -/** +/*! \brief Indicates a function should not be stored in flash + * \ingroup pico_platform + * * Decorates a function name, such that the function will execute from RAM (assuming it is not inlined * into a flash function by the compiler) + * + * For example a function called my_func taking an int parameter: + * + * void __not_in_flash_func(my_func)(int some_arg) { + * + * The function is placed in the `.time_critical.` linker section + * + * \see __no_inline_not_in_flash_func */ #define __not_in_flash_func(func_name) __not_in_flash(__STRING(func_name)) func_name -/** - * Historical synonym for __not_in_flash_func() + +/*! \brief Indicates a function is time/latency critical and should not run from flash + * \ingroup pico_platform + * + * Decorates a function name, such that the function will execute from RAM (assuming it is not inlined + * into a flash function by the compiler) to avoid possible flash latency. Currently this macro is identical + * in implementation to `__not_in_flash_func`, however the semantics are distinct and a `__time_critical_func` + * may in the future be treated more specially to reduce the overhead when calling such function from a flash + * function. + * + * For example a function called my_func taking an int parameter: + * + * void __time_critical(my_func)(int some_arg) { + * + * The function is placed in the `.time_critical.` linker section + * + * \see __not_in_flash_func */ #define __time_critical_func(func_name) __not_in_flash_func(func_name) -/** +/*! \brief Indicate a function should not be stored in flash and should not be inlined + * \ingroup pico_platform + * * Decorates a function name, such that the function will execute from RAM, explicitly marking it as * noinline to prevent it being inlined into a flash function by the compiler + * + * For example a function called my_func taking an int parameter: + * + * void __no_inline_not_in_flash_func(my_func)(int some_arg) { + * + * The function is placed in the `.time_critical.` linker section */ #define __no_inline_not_in_flash_func(func_name) __noinline __not_in_flash_func(func_name) #define __packed_aligned __packed __aligned(4) +/*! \brief Attribute to force inlining of a function regardless of optimization level + * \ingroup pico_platform + * + * For example my_function here will always be inlined: + * + * int __force_inline my_function(int x) { + * + */ #if defined(__GNUC__) && __GNUC__ <= 7 #define __force_inline inline __always_inline #else #define __force_inline __always_inline #endif + +/*! \brief Macro to determine the number of elements in an array + * \ingroup pico_platform + */ #ifndef count_of #define count_of(a) (sizeof(a)/sizeof((a)[0])) #endif +/*! \brief Macro to return the maximum of two comparable values + * \ingroup pico_platform + */ #ifndef MAX #define MAX(a, b) ((a)>(b)?(a):(b)) #endif +/*! \brief Macro to return the minimum of two comparable values + * \ingroup pico_platform + */ #ifndef MIN #define MIN(a, b) ((b)>(a)?(a):(b)) #endif -/** - * Execute a breakpoint instruction +/*! \brief Execute a breakpoint instruction + * \ingroup pico_platform */ static inline void __breakpoint(void) { __asm__("bkpt #0"); } -/** - * Ensure that the compiler does not move memory access across this method call +/*! \brief Ensure that the compiler does not move memory access across this method call + * \ingroup pico_platform + * + * For example in the following code: + * + * *some_memory_location = var_a; + * __compiler_memory_barrier(); + * uint32_t var_b = *some_other_memory_location + * + * The compiler will not move the load from `some_other_memory_location` above the memory barrier (which it otherwise + * might - even above the memory store!) */ __force_inline static void __compiler_memory_barrier(void) { __asm__ volatile ("" : : : "memory"); } -// return a 32 bit handle for a raw ptr; DMA chaining for example embeds pointers in 32 bit values -// which of course does not work if we're running the code natively on a 64 bit platforms. Therefore -// we provide this macro which allows that code to provide a 64->32 bit mapping in host mode +/*! \brief Macro for converting memory addresses to 32 bit addresses suitable for DMA + * \ingroup pico_platform + * + * This is just a cast to `uintptr_t` on the RP2040, however you may want to use this when developing code + * that also runs in "host" mode. If the host mode is 64 bit and you are embedding data pointers + * in other data (e.g. DMA chaining), then there is a need in "host" mode to convert a 64 bit native + * pointer to a 32 bit value for storage, which can be done using this macro. + */ #define host_safe_hw_ptr(x) ((uintptr_t)(x)) +#define native_safe_hw_ptr(x) host_safe_hw_ptr(x) -/** - * Panic (see panic()) with the message "Unsupported". + +/*! \brief Panics with the message "Unsupported" + * \ingroup pico_platform + * \see panic */ void __attribute__((noreturn)) panic_unsupported(void); -/** - * Panic with a message. An attempt is made to output the message to all registered STDOUT drivers +/*! \brief Displays a panic message and halts execution + * \ingroup pico_platform + * + * An attempt is made to output the message to all registered STDOUT drivers * after which this method executes a BKPT instruction. * * @param fmt format string (printf-like) @@ -110,36 +323,34 @@ static inline bool running_on_fpga(void) {return false;} bool running_on_fpga(void); #endif -/** - * @return the RP2040 chip revision number +/*! \brief Returns the RP2040 chip revision number + * \ingroup pico_platform + * @return the RP2040 chip revision number (1 for B0/B1, 2 for B2) */ uint8_t rp2040_chip_version(void); -/** - * @return the RP2040 rom version number +/*! \brief Returns the RP2040 rom version number + * \ingroup pico_platform + * @return the RP2040 rom version number (1 for RP2040-B0, 2 for RP2040-B1, 3 for RP2040-B2) */ static inline uint8_t rp2040_rom_version(void) { return *(uint8_t*)0x13; } -/** - * Empty function intended to be called by any tight hardware polling loop. using this ubiquitously +/*! \brief No-op function for the body of tight loops + * \ingroup pico_platform + * + * Np-op function intended to be called by any tight hardware polling loop. Using this ubiquitously * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup * debugging might be added */ -static inline void tight_loop_contents(void) {} +static __force_inline void tight_loop_contents(void) {} -/** - * Helper macro for making chain DMA code portable to PICO_PLATFORM=host. The problem here is - * that embedded pointers in the data are only 32 bit, which is a problem if the host - * system is 64 bit. This macro is zero cost on the actual device, but in host mode - * it provides a 64->32 bit mapping - */ -#define native_safe_hw_ptr(x) ((uintptr_t)(x)) - -/** - * Multiplies a by b using multiply instruction using the ARM mul instruction regardless of values; - * i.e. this is a 1 cycle operation. +/*! \brief Multiply two integers using an assembly `MUL` instruction + * \ingroup pico_platform + * + * This multiplies a by b using multiply instruction using the ARM mul instruction regardless of values (the compiler + * might otherwise choose to perform shifts/adds), i.e. this is a 1 cycle operation. * * \param a the first operand * \param b the second operand @@ -150,10 +361,14 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { return a; } -/** - * Efficiently Multiplies value a by possibly constant value b. +/*! \brief multiply two integer values using the fastest method possible + * \ingroup pico_platform + * + * Efficiently multiplies value a by possibly constant value b. + * * If b is known to be constant and not zero or a power of 2, then a mul instruction is used rather than gcc's default - * which is often a slow combination of shifts and adds + * which is often a slow combination of shifts and adds. If b is a power of 2 then a single shift is of course preferable + * and will be used * * \param a the first operand * \param b the second operand @@ -163,18 +378,34 @@ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { (__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \ (a)*(b)) -#define WRAPPER_FUNC(x) __wrap_ ## x -#define REAL_FUNC(x) __real_ ## x - +/*! \brief Utility macro to assert two types are equivalent. + * \ingroup pico_platform + * + * This macro can be useful in other macros along with `typeof` to assert that two parameters are of equivalent type + * (or that a single parameter is of an expected type) + */ #define __check_type_compatible(type_a, type_b) static_assert(__builtin_types_compatible_p(type_a, type_b), __STRING(type_a) " is not compatible with " __STRING(type_b)); -/** - * Get the current exception level on this core +/*! \brief Get the current exception level on this core + * \ingroup pico_platform + * * \return the exception number if the CPU is handling an exception, or 0 otherwise */ uint __get_current_exception(void); +#define WRAPPER_FUNC(x) __wrap_ ## x +#define REAL_FUNC(x) __real_ ## x + #ifdef __cplusplus } #endif + +#else // __ASSEMBLER__ + +#define WRAPPER_FUNC_NAME(x) __wrap_##x +#define SECTION_NAME(x) .text.##x +#define RAM_SECTION_NAME(x) .time_critical.##x + +#endif // !__ASSEMBLER__ + #endif diff --git a/src/rp2_common/pico_runtime/runtime.c b/src/rp2_common/pico_runtime/runtime.c index 400f6cb..8b91d62 100644 --- a/src/rp2_common/pico_runtime/runtime.c +++ b/src/rp2_common/pico_runtime/runtime.c @@ -32,10 +32,6 @@ #include "pico/bootrom.h" #endif -#ifndef PICO_NO_RAM_VECTOR_TABLE -#define PICO_NO_RAM_VECTOR_TABLE 0 -#endif - extern char __StackLimit; /* Set by linker. */ uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[48]; diff --git a/src/rp2_common/pico_standard_link/crt0.S b/src/rp2_common/pico_standard_link/crt0.S index 4134f0b..f57ddfd 100644 --- a/src/rp2_common/pico_standard_link/crt0.S +++ b/src/rp2_common/pico_standard_link/crt0.S @@ -4,12 +4,11 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include "pico.h" #include "hardware/regs/m0plus.h" -#include "hardware/platform_defs.h" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" #include "pico/binary_info/defs.h" -#include "pico/config.h" #ifdef NDEBUG #ifndef COLLAPSE_IRQS