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
This commit is contained in:
Graham Sanderson 2021-10-25 12:26:06 -05:00 committed by GitHub
parent 723dfd04ff
commit e850214938
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 431 additions and 277 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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
// -------------

View File

@ -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

View File

@ -7,6 +7,8 @@
#ifndef _PICO_TYPES_H
#define _PICO_TYPES_H
#ifndef __ASSEMBLER__
#include "pico/assert.h"
#include <stdint.h>
@ -89,3 +91,4 @@ typedef struct {
#define bool_to_bit(x) ((uint)!!(x))
#endif
#endif

View File

@ -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)

View File

@ -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

View File

@ -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 $<TARGET_FILE:${TARGET}> "${PICO_SYMLINK_ELF_AS_FILENAME}"
COMMENT "Symlinking from ${PICO_SYMLINK_ELF_AS_FILENAME} to $<TARGET_FILE:${TARGET}>"
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <sys/cdefs.h>
#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.<group>`
*
* \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.<group>`
*
* \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.<group>`
*
* \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.<group>`
*
* \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.<group>`
*
* \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.<group>`
*
* \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.<func_name>` 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.<func_name>` 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.<func_name>` 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

View File

@ -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];

View File

@ -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