mirror of
https://github.com/raspberrypi/pico-sdk.git
synced 2025-12-10 07:14:36 +01:00
Initial commit pulled in a bunch of stuff - see description
* Add `PICO_MINIMAL_STORED_VECTOR_TABLE` config replacing (`PICO_NO_STORED_VECTOR_TABLE` which was a lie * Add `PICO_NUM_VTABLE_IRQS`` which allows you to limit the number of IRQs included in both the STORED or RAM vector tables, and make the rest of the SDK behave properly based on that * Because these new variables in `pico_crt0` are circularly dependent somewhat with variables in `hardware_irq` hoist all the interdependent variables into a new `pico_platform_common` which is common to all `rp2` platforms * Move some previously duplicated `pico_platform` code into `pico_platform_common` Net effect: 1. if you set PICO_MINIMAL_STORED_VECTOR_TABLE=1, you get a 4 word VTABLE on Arm.. you still get a RAM vector table with up to PICO_NUM_VTABLE_IRQs (defaults to NUM_IRQs) but everything - including things like `isr_pendsv` point to `__unhandled_user_irq`. 2. PICO_NUM_VTABLE_IRQs (default NUM_IRQS) sets the number of IRQs that have handlers in the VTABLE (this affects the space reserved, and what the irq APIs let you touch - at least as far as invalid_params_if!) 3. If you set PICO_MINIMAL_STORED_VECTOR_TABLE=1 for a no flash binary, then PICO_NUM_VTABLE_IRQs is forced to 0 as there is no reserved space for the handlers. Co-authored-by: graham sanderson <graham.sanderson@raspberrypi.com>
This commit is contained in:
parent
39fafaa434
commit
a5ba689cb5
23 changed files with 287 additions and 268 deletions
|
|
@ -82,6 +82,7 @@ endif()
|
||||||
|
|
||||||
# Basic bootrom headers
|
# Basic bootrom headers
|
||||||
pico_add_subdirectory(rp2_common/boot_bootrom_headers)
|
pico_add_subdirectory(rp2_common/boot_bootrom_headers)
|
||||||
|
pico_add_subdirectory(rp2_common/pico_platform_common)
|
||||||
pico_add_subdirectory(rp2_common/pico_platform_compiler)
|
pico_add_subdirectory(rp2_common/pico_platform_compiler)
|
||||||
pico_add_subdirectory(rp2_common/pico_platform_sections)
|
pico_add_subdirectory(rp2_common/pico_platform_sections)
|
||||||
pico_add_subdirectory(rp2_common/pico_platform_panic)
|
pico_add_subdirectory(rp2_common/pico_platform_panic)
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ cc_library(
|
||||||
"//src/rp2_common/hardware_watchdog:__pkg__",
|
"//src/rp2_common/hardware_watchdog:__pkg__",
|
||||||
"//src/rp2_common/hardware_xosc:__pkg__",
|
"//src/rp2_common/hardware_xosc:__pkg__",
|
||||||
"//src/rp2_common/pico_crt0:__pkg__",
|
"//src/rp2_common/pico_crt0:__pkg__",
|
||||||
|
"//src/rp2_common/pico_platform_common:__pkg__",
|
||||||
"//src/rp2_common/pico_printf:__pkg__",
|
"//src/rp2_common/pico_printf:__pkg__",
|
||||||
"//src/rp2_common/pico_runtime:__pkg__",
|
"//src/rp2_common/pico_runtime:__pkg__",
|
||||||
"//src/rp2_common/pico_runtime_init:__pkg__",
|
"//src/rp2_common/pico_runtime_init:__pkg__",
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ extern "C" {
|
||||||
typedef void (*irq_handler_t)(void);
|
typedef void (*irq_handler_t)(void);
|
||||||
|
|
||||||
static inline void check_irq_param(__unused uint num) {
|
static inline void check_irq_param(__unused uint num) {
|
||||||
invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS);
|
invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Set specified interrupt's priority
|
/*! \brief Set specified interrupt's priority
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ void PICO_WEAK_FUNCTION_IMPL_NAME(irq_init_priorities)() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint get_user_irq_claim_index(uint irq_num) {
|
static uint get_user_irq_claim_index(uint irq_num) {
|
||||||
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS);
|
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS);
|
||||||
// we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
|
// we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
|
||||||
static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
|
static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
|
||||||
return NUM_IRQS - irq_num - 1u;
|
return NUM_IRQS - irq_num - 1u;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ cc_library(
|
||||||
deps = [
|
deps = [
|
||||||
"//src/rp2040/hardware_regs",
|
"//src/rp2040/hardware_regs",
|
||||||
"//src/rp2040/hardware_regs:platform_defs",
|
"//src/rp2040/hardware_regs:platform_defs",
|
||||||
|
"//src/rp2_common/pico_platform_common:pico_platform_common_headers",
|
||||||
"//src/rp2_common/pico_platform_compiler",
|
"//src/rp2_common/pico_platform_compiler",
|
||||||
"//src/rp2_common/pico_platform_panic:pico_platform_panic_headers",
|
"//src/rp2_common/pico_platform_panic:pico_platform_panic_headers",
|
||||||
"//src/rp2_common/pico_platform_sections",
|
"//src/rp2_common/pico_platform_sections",
|
||||||
|
|
@ -44,6 +45,7 @@ cc_library(
|
||||||
"//src/rp2040/hardware_regs",
|
"//src/rp2040/hardware_regs",
|
||||||
"//src/rp2040/hardware_regs:platform_defs",
|
"//src/rp2040/hardware_regs:platform_defs",
|
||||||
"//src/rp2_common/hardware_base",
|
"//src/rp2_common/hardware_base",
|
||||||
|
"//src/rp2_common/pico_platform_common",
|
||||||
"//src/rp2_common/pico_platform_compiler",
|
"//src/rp2_common/pico_platform_compiler",
|
||||||
"//src/rp2_common/pico_platform_panic",
|
"//src/rp2_common/pico_platform_panic",
|
||||||
"//src/rp2_common/pico_platform_sections",
|
"//src/rp2_common/pico_platform_sections",
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ if (NOT TARGET pico_platform)
|
||||||
|
|
||||||
target_link_libraries(pico_platform_headers INTERFACE hardware_regs)
|
target_link_libraries(pico_platform_headers INTERFACE hardware_regs)
|
||||||
pico_mirrored_target_link_libraries(pico_platform INTERFACE
|
pico_mirrored_target_link_libraries(pico_platform INTERFACE
|
||||||
|
pico_platform_common
|
||||||
pico_platform_compiler
|
pico_platform_compiler
|
||||||
pico_platform_panic
|
pico_platform_panic
|
||||||
pico_platform_sections
|
pico_platform_sections
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "pico/platform/compiler.h"
|
#include "pico/platform/compiler.h"
|
||||||
#include "pico/platform/sections.h"
|
#include "pico/platform/sections.h"
|
||||||
#include "pico/platform/panic.h"
|
#include "pico/platform/panic.h"
|
||||||
|
#include "pico/platform/common.h"
|
||||||
#include "hardware/regs/addressmap.h"
|
#include "hardware/regs/addressmap.h"
|
||||||
#include "hardware/regs/sio.h"
|
#include "hardware/regs/sio.h"
|
||||||
|
|
||||||
|
|
@ -66,10 +67,6 @@
|
||||||
#define PICO_RP2040_B2_SUPPORTED 1
|
#define PICO_RP2040_B2_SUPPORTED 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PICO_RAM_VECTOR_TABLE_SIZE
|
|
||||||
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group=pico_platform
|
// PICO_CONFIG: PICO_CLKDIV_ROUND_NEAREST, True if floating point clock divisors should be rounded to the nearest possible clock divisor by default rather than rounding down, type=bool, default=1, group=pico_platform
|
||||||
#ifndef PICO_CLKDIV_ROUND_NEAREST
|
#ifndef PICO_CLKDIV_ROUND_NEAREST
|
||||||
#define PICO_CLKDIV_ROUND_NEAREST 1
|
#define PICO_CLKDIV_ROUND_NEAREST 1
|
||||||
|
|
@ -80,16 +77,6 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \brief No-op function for the body of tight loops
|
|
||||||
* \ingroup pico_platform
|
|
||||||
*
|
|
||||||
* No-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 __force_inline void tight_loop_contents(void) {}
|
|
||||||
|
|
||||||
/*! \brief Helper method to busy-wait for at least the given number of cycles
|
/*! \brief Helper method to busy-wait for at least the given number of cycles
|
||||||
* \ingroup pico_platform
|
* \ingroup pico_platform
|
||||||
*
|
*
|
||||||
|
|
@ -112,17 +99,6 @@ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime
|
|
||||||
#ifndef PICO_NO_FPGA_CHECK
|
|
||||||
#define PICO_NO_FPGA_CHECK 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PICO_NO_FPGA_CHECK
|
|
||||||
static inline bool running_on_fpga(void) {return false;}
|
|
||||||
#else
|
|
||||||
bool running_on_fpga(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief Execute a breakpoint instruction
|
/*! \brief Execute a breakpoint instruction
|
||||||
* \ingroup pico_platform
|
* \ingroup pico_platform
|
||||||
*/
|
*/
|
||||||
|
|
@ -158,9 +134,6 @@ static __force_inline uint __get_current_exception(void) {
|
||||||
return exception;
|
return exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define host_safe_hw_ptr(x) ((uintptr_t)(x))
|
|
||||||
#define native_safe_hw_ptr(x) host_safe_hw_ptr(x)
|
|
||||||
|
|
||||||
/*! \brief Returns the RP2040 chip revision number
|
/*! \brief Returns the RP2040 chip revision number
|
||||||
* \ingroup pico_platform
|
* \ingroup pico_platform
|
||||||
* @return the RP2040 chip revision number (1 for B0/B1, 2 for B2)
|
* @return the RP2040 chip revision number (1 for B0/B1, 2 for B2)
|
||||||
|
|
|
||||||
|
|
@ -6,23 +6,8 @@
|
||||||
|
|
||||||
#include "pico.h"
|
#include "pico.h"
|
||||||
#include "hardware/address_mapped.h"
|
#include "hardware/address_mapped.h"
|
||||||
#include "hardware/regs/tbman.h"
|
|
||||||
#include "hardware/regs/sysinfo.h"
|
#include "hardware/regs/sysinfo.h"
|
||||||
|
|
||||||
// Note we leave the FPGA check in by default so that we can run bug repro
|
|
||||||
// binaries coming in from the wild on the FPGA platform. It takes up around
|
|
||||||
// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1
|
|
||||||
// to remove it. The FPGA check is used to skip initialisation of hardware
|
|
||||||
// (mainly clock generators and oscillators) that aren't present on FPGA.
|
|
||||||
|
|
||||||
#if !PICO_NO_FPGA_CHECK
|
|
||||||
// Inline stub provided in header if this code is unused (so folding can be
|
|
||||||
// done in each TU instead of relying on LTO)
|
|
||||||
bool running_on_fpga(void) {
|
|
||||||
return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MANUFACTURER_RPI 0x927
|
#define MANUFACTURER_RPI 0x927
|
||||||
#define PART_RP2 0x2
|
#define PART_RP2 0x2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ cc_library(
|
||||||
deps = [
|
deps = [
|
||||||
"//src/rp2350/hardware_regs",
|
"//src/rp2350/hardware_regs",
|
||||||
"//src/rp2350/hardware_regs:platform_defs",
|
"//src/rp2350/hardware_regs:platform_defs",
|
||||||
|
"//src/rp2_common/pico_platform_common:pico_platform_common_headers",
|
||||||
"//src/rp2_common/pico_platform_compiler",
|
"//src/rp2_common/pico_platform_compiler",
|
||||||
"//src/rp2_common/pico_platform_panic:pico_platform_panic_headers",
|
"//src/rp2_common/pico_platform_panic:pico_platform_panic_headers",
|
||||||
"//src/rp2_common/pico_platform_sections",
|
"//src/rp2_common/pico_platform_sections",
|
||||||
|
|
@ -44,6 +45,7 @@ cc_library(
|
||||||
"//src/rp2350/hardware_regs",
|
"//src/rp2350/hardware_regs",
|
||||||
"//src/rp2350/hardware_regs:platform_defs",
|
"//src/rp2350/hardware_regs:platform_defs",
|
||||||
"//src/rp2_common/hardware_base",
|
"//src/rp2_common/hardware_base",
|
||||||
|
"//src/rp2_common/pico_platform_common",
|
||||||
"//src/rp2_common/pico_platform_compiler",
|
"//src/rp2_common/pico_platform_compiler",
|
||||||
"//src/rp2_common/pico_platform_panic",
|
"//src/rp2_common/pico_platform_panic",
|
||||||
"//src/rp2_common/pico_platform_sections",
|
"//src/rp2_common/pico_platform_sections",
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ if (NOT TARGET pico_platform)
|
||||||
hardware_regs
|
hardware_regs
|
||||||
)
|
)
|
||||||
pico_mirrored_target_link_libraries(pico_platform INTERFACE
|
pico_mirrored_target_link_libraries(pico_platform INTERFACE
|
||||||
|
pico_platform_common
|
||||||
pico_platform_compiler
|
pico_platform_compiler
|
||||||
pico_platform_panic
|
pico_platform_panic
|
||||||
pico_platform_sections
|
pico_platform_sections
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,14 @@
|
||||||
#include "pico/platform/compiler.h"
|
#include "pico/platform/compiler.h"
|
||||||
#include "pico/platform/sections.h"
|
#include "pico/platform/sections.h"
|
||||||
#include "pico/platform/panic.h"
|
#include "pico/platform/panic.h"
|
||||||
|
#include "pico/platform/common.h"
|
||||||
#include "hardware/regs/addressmap.h"
|
#include "hardware/regs/addressmap.h"
|
||||||
#include "hardware/regs/sio.h"
|
#include "hardware/regs/sio.h"
|
||||||
#ifdef __riscv
|
#ifdef __riscv
|
||||||
#include "hardware/regs/rvcsr.h"
|
#include "hardware/regs/rvcsr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform
|
// PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package - set to 0 for RP2350 in a B (48 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform
|
||||||
#if 0 // make tooling checks happy
|
#if 0 // make tooling checks happy
|
||||||
#define PICO_RP2350A 0
|
#define PICO_RP2350A 0
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -54,10 +55,6 @@
|
||||||
#define PICO_NO_RAM_VECTOR_TABLE 0
|
#define PICO_NO_RAM_VECTOR_TABLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PICO_RAM_VECTOR_TABLE_SIZE
|
|
||||||
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform
|
// PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform
|
||||||
#ifndef PICO_USE_STACK_GUARDS
|
#ifndef PICO_USE_STACK_GUARDS
|
||||||
#define PICO_USE_STACK_GUARDS 0
|
#define PICO_USE_STACK_GUARDS 0
|
||||||
|
|
@ -73,16 +70,6 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \brief No-op function for the body of tight loops
|
|
||||||
* \ingroup pico_platform
|
|
||||||
*
|
|
||||||
* No-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 __force_inline void tight_loop_contents(void) {}
|
|
||||||
|
|
||||||
/*! \brief Helper method to busy-wait for at least the given number of cycles
|
/*! \brief Helper method to busy-wait for at least the given number of cycles
|
||||||
* \ingroup pico_platform
|
* \ingroup pico_platform
|
||||||
*
|
*
|
||||||
|
|
@ -116,27 +103,6 @@ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime
|
|
||||||
#ifndef PICO_NO_FPGA_CHECK
|
|
||||||
#define PICO_NO_FPGA_CHECK 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime
|
|
||||||
#ifndef PICO_NO_SIM_CHECK
|
|
||||||
#define PICO_NO_SIM_CHECK 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PICO_NO_FPGA_CHECK
|
|
||||||
static inline bool running_on_fpga(void) {return false;}
|
|
||||||
#else
|
|
||||||
bool running_on_fpga(void);
|
|
||||||
#endif
|
|
||||||
#if PICO_NO_SIM_CHECK
|
|
||||||
static inline bool running_in_sim(void) {return false;}
|
|
||||||
#else
|
|
||||||
bool running_in_sim(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*! \brief Execute a breakpoint instruction
|
/*! \brief Execute a breakpoint instruction
|
||||||
* \ingroup pico_platform
|
* \ingroup pico_platform
|
||||||
*/
|
*/
|
||||||
|
|
@ -221,9 +187,6 @@ __force_inline static bool pico_processor_state_is_nonsecure(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define host_safe_hw_ptr(x) ((uintptr_t)(x))
|
|
||||||
#define native_safe_hw_ptr(x) host_safe_hw_ptr(x)
|
|
||||||
|
|
||||||
/*! \brief Returns the RP2350 chip revision number
|
/*! \brief Returns the RP2350 chip revision number
|
||||||
* \ingroup pico_platform
|
* \ingroup pico_platform
|
||||||
* @return the RP2350 chip revision number (1 for B0/B1, 2 for B2)
|
* @return the RP2350 chip revision number (1 for B0/B1, 2 for B2)
|
||||||
|
|
|
||||||
|
|
@ -6,28 +6,8 @@
|
||||||
|
|
||||||
#include "pico.h"
|
#include "pico.h"
|
||||||
#include "hardware/address_mapped.h"
|
#include "hardware/address_mapped.h"
|
||||||
#include "hardware/regs/tbman.h"
|
|
||||||
#include "hardware/regs/sysinfo.h"
|
#include "hardware/regs/sysinfo.h"
|
||||||
|
|
||||||
// Note we leave the FPGA check in by default so that we can run bug repro
|
|
||||||
// binaries coming in from the wild on the FPGA platform. It takes up around
|
|
||||||
// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1
|
|
||||||
// to remove it. The FPGA check is used to skip initialisation of hardware
|
|
||||||
// (mainly clock generators and oscillators) that aren't present on FPGA.
|
|
||||||
|
|
||||||
#if !PICO_NO_FPGA_CHECK
|
|
||||||
// Inline stub provided in header if this code is unused (so folding can be
|
|
||||||
// done in each TU instead of relying on LTO)
|
|
||||||
bool __attribute__((weak)) running_on_fpga(void) {
|
|
||||||
return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if !PICO_NO_SIM_CHECK
|
|
||||||
bool __attribute__((weak)) running_in_sim(void) {
|
|
||||||
return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_HDLSIM_BITS;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MANUFACTURER_RPI 0x926
|
#define MANUFACTURER_RPI 0x926
|
||||||
#define PART_RP4 0x4
|
#define PART_RP4 0x4
|
||||||
|
|
||||||
|
|
@ -36,9 +16,9 @@ uint8_t rp2350_chip_version(void) {
|
||||||
uint32_t chip_id = *((io_ro_32*)(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET));
|
uint32_t chip_id = *((io_ro_32*)(SYSINFO_BASE + SYSINFO_CHIP_ID_OFFSET));
|
||||||
uint32_t __unused manufacturer = chip_id & SYSINFO_CHIP_ID_MANUFACTURER_BITS;
|
uint32_t __unused manufacturer = chip_id & SYSINFO_CHIP_ID_MANUFACTURER_BITS;
|
||||||
uint32_t __unused part = (chip_id & SYSINFO_CHIP_ID_PART_BITS) >> SYSINFO_CHIP_ID_PART_LSB;
|
uint32_t __unused part = (chip_id & SYSINFO_CHIP_ID_PART_BITS) >> SYSINFO_CHIP_ID_PART_LSB;
|
||||||
assert(manufacturer == MANUFACTURER_RPI);
|
assert(manufacturer == MANUFACTURER_RPI && part == PART_RP4);
|
||||||
assert(part == PART_RP4);
|
|
||||||
// 0 == A0, 1 == A1, 2 == A2
|
// 0 == A0, 1 == A1, 2 == A2
|
||||||
uint version = (chip_id & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB;
|
uint32_t version = (chip_id & SYSINFO_CHIP_ID_REVISION_BITS) >> SYSINFO_CHIP_ID_REVISION_LSB;
|
||||||
|
version = (version & 3u) | ((version & 8u) >> 1);
|
||||||
return (uint8_t)version;
|
return (uint8_t)version;
|
||||||
}
|
}
|
||||||
|
|
@ -31,12 +31,14 @@ static inline exception_handler_t *get_exception_table(void) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !PICO_NO_RAM_VECTOR_TABLE
|
||||||
static void set_raw_exception_handler_and_restore_interrupts(enum exception_number num, exception_handler_t handler, uint32_t save) {
|
static void set_raw_exception_handler_and_restore_interrupts(enum exception_number num, exception_handler_t handler, uint32_t save) {
|
||||||
// update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness)
|
// update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness)
|
||||||
get_exception_table()[num] = handler;
|
get_exception_table()[num] = handler;
|
||||||
__dmb();
|
__dmb();
|
||||||
restore_interrupts_from_disabled(save);
|
restore_interrupts_from_disabled(save);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void check_exception_param(__unused enum exception_number num) {
|
static inline void check_exception_param(__unused enum exception_number num) {
|
||||||
invalid_params_if(HARDWARE_EXCEPTION, num < MIN_EXCEPTION_NUM || num > MAX_EXCEPTION_NUM);
|
invalid_params_if(HARDWARE_EXCEPTION, num < MIN_EXCEPTION_NUM || num > MAX_EXCEPTION_NUM);
|
||||||
|
|
@ -54,10 +56,12 @@ exception_handler_t exception_set_exclusive_handler(enum exception_number num, e
|
||||||
exception_handler_t current = exception_get_vtable_handler(num);
|
exception_handler_t current = exception_get_vtable_handler(num);
|
||||||
hard_assert(handler == current || exception_is_compile_time_default(current));
|
hard_assert(handler == current || exception_is_compile_time_default(current));
|
||||||
set_raw_exception_handler_and_restore_interrupts(num, handler, save);
|
set_raw_exception_handler_and_restore_interrupts(num, handler, save);
|
||||||
|
return current;
|
||||||
#else
|
#else
|
||||||
|
((void)num);
|
||||||
|
((void)handler);
|
||||||
panic_unsupported();
|
panic_unsupported();
|
||||||
#endif
|
#endif
|
||||||
return current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void exception_restore_handler(enum exception_number num, exception_handler_t original_handler) {
|
void exception_restore_handler(enum exception_number num, exception_handler_t original_handler) {
|
||||||
|
|
@ -66,6 +70,8 @@ void exception_restore_handler(enum exception_number num, exception_handler_t or
|
||||||
uint32_t save = save_and_disable_interrupts();
|
uint32_t save = save_and_disable_interrupts();
|
||||||
set_raw_exception_handler_and_restore_interrupts(num, original_handler, save);
|
set_raw_exception_handler_and_restore_interrupts(num, original_handler, save);
|
||||||
#else
|
#else
|
||||||
|
((void)num);
|
||||||
|
((void)original_handler);
|
||||||
panic_unsupported();
|
panic_unsupported();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ extern "C" {
|
||||||
typedef void (*irq_handler_t)(void);
|
typedef void (*irq_handler_t)(void);
|
||||||
|
|
||||||
static inline void check_irq_param(__unused uint num) {
|
static inline void check_irq_param(__unused uint num) {
|
||||||
invalid_params_if(HARDWARE_IRQ, num >= NUM_IRQS);
|
invalid_params_if(HARDWARE_IRQ, num >= PICO_NUM_VTABLE_IRQS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Set specified interrupt's priority
|
/*! \brief Set specified interrupt's priority
|
||||||
|
|
|
||||||
|
|
@ -57,13 +57,6 @@ static inline void *remove_thumb_bit(void *addr) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) {
|
|
||||||
// update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness)
|
|
||||||
get_vtable()[VTABLE_FIRST_IRQ + num] = handler;
|
|
||||||
__dmb();
|
|
||||||
spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save);
|
|
||||||
}
|
|
||||||
|
|
||||||
void irq_set_enabled(uint num, bool enabled) {
|
void irq_set_enabled(uint num, bool enabled) {
|
||||||
check_irq_param(num);
|
check_irq_param(num);
|
||||||
// really should update irq_set_mask_enabled?
|
// really should update irq_set_mask_enabled?
|
||||||
|
|
@ -82,7 +75,7 @@ bool irq_is_enabled(uint num) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void irq_set_mask_n_enabled_internal(uint n, uint32_t mask, bool enabled) {
|
static inline void irq_set_mask_n_enabled_internal(uint n, uint32_t mask, bool enabled) {
|
||||||
invalid_params_if(HARDWARE_IRQ, n * 32u >= ((NUM_IRQS + 31u) & ~31u));
|
invalid_params_if(HARDWARE_IRQ, n * 32u >= ((PICO_NUM_VTABLE_IRQS + 31u) & ~31u));
|
||||||
#if defined(__riscv)
|
#if defined(__riscv)
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, 2 * n, mask & 0xffffu);
|
hazard3_irqarray_clear(RVCSR_MEIFA_OFFSET, 2 * n, mask & 0xffffu);
|
||||||
|
|
@ -135,7 +128,7 @@ void irq_set_pending(uint num) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE
|
||||||
// limited by 8 bit relative links (and reality)
|
// limited by 8 bit relative links (and reality)
|
||||||
static_assert(PICO_MAX_SHARED_IRQ_HANDLERS >= 1 && PICO_MAX_SHARED_IRQ_HANDLERS < 0x7f, "");
|
static_assert(PICO_MAX_SHARED_IRQ_HANDLERS >= 1 && PICO_MAX_SHARED_IRQ_HANDLERS < 0x7f, "");
|
||||||
|
|
||||||
|
|
@ -215,9 +208,17 @@ bool irq_has_shared_handler(uint irq_num) {
|
||||||
return is_shared_irq_raw_handler(handler);
|
return is_shared_irq_raw_handler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // PICO_DISABLE_SHARED_IRQ_HANDLERS
|
static void set_raw_irq_handler_and_unlock(uint num, irq_handler_t handler, uint32_t save) {
|
||||||
|
// update vtable (vtable_handler may be same or updated depending on cases, but we do it anyway for compactness)
|
||||||
|
get_vtable()[VTABLE_FIRST_IRQ + num] = handler;
|
||||||
|
__dmb();
|
||||||
|
spin_unlock(spin_lock_instance(PICO_SPINLOCK_ID_IRQ), save);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // PICO_DISABLE_SHARED_IRQ_HANDLERS && PICO_NO_RAM_VECTOR_TABLE
|
||||||
#define is_shared_irq_raw_handler(h) false
|
#define is_shared_irq_raw_handler(h) false
|
||||||
bool irq_has_shared_handler(uint irq_num) {
|
bool irq_has_shared_handler(uint irq_num) {
|
||||||
|
((void)irq_num);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -237,6 +238,7 @@ void irq_set_exclusive_handler(uint num, irq_handler_t handler) {
|
||||||
hard_assert(current == __unhandled_user_irq || current == handler);
|
hard_assert(current == __unhandled_user_irq || current == handler);
|
||||||
set_raw_irq_handler_and_unlock(num, handler, save);
|
set_raw_irq_handler_and_unlock(num, handler, save);
|
||||||
#else
|
#else
|
||||||
|
((void)handler);
|
||||||
panic_unsupported();
|
panic_unsupported();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -258,7 +260,7 @@ irq_handler_t irq_get_exclusive_handler(uint num) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE
|
||||||
|
|
||||||
#ifndef __riscv
|
#ifndef __riscv
|
||||||
|
|
||||||
|
|
@ -368,6 +370,8 @@ static inline int8_t get_slot_index(struct irq_handler_chain_slot *slot) {
|
||||||
void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority) {
|
void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_priority) {
|
||||||
check_irq_param(num);
|
check_irq_param(num);
|
||||||
#if PICO_NO_RAM_VECTOR_TABLE
|
#if PICO_NO_RAM_VECTOR_TABLE
|
||||||
|
((void)handler);
|
||||||
|
((void)order_priority);
|
||||||
panic_unsupported();
|
panic_unsupported();
|
||||||
#elif PICO_DISABLE_SHARED_IRQ_HANDLERS
|
#elif PICO_DISABLE_SHARED_IRQ_HANDLERS
|
||||||
irq_set_exclusive_handler(num, handler);
|
irq_set_exclusive_handler(num, handler);
|
||||||
|
|
@ -461,7 +465,7 @@ void irq_add_shared_handler(uint num, irq_handler_t handler, uint8_t order_prior
|
||||||
#endif // !PICO_NO_RAM_VECTOR_TABLE && !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
#endif // !PICO_NO_RAM_VECTOR_TABLE && !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE
|
||||||
static inline irq_handler_t handler_from_slot(struct irq_handler_chain_slot *slot) {
|
static inline irq_handler_t handler_from_slot(struct irq_handler_chain_slot *slot) {
|
||||||
#ifndef __riscv
|
#ifndef __riscv
|
||||||
return slot->handler;
|
return slot->handler;
|
||||||
|
|
@ -586,6 +590,8 @@ void irq_remove_handler(uint num, irq_handler_t handler) {
|
||||||
}
|
}
|
||||||
set_raw_irq_handler_and_unlock(num, vtable_handler, save);
|
set_raw_irq_handler_and_unlock(num, vtable_handler, save);
|
||||||
#else
|
#else
|
||||||
|
((void)num);
|
||||||
|
((void)handler);
|
||||||
panic_unsupported();
|
panic_unsupported();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -626,7 +632,7 @@ uint irq_get_priority(uint num) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS
|
#if !PICO_DISABLE_SHARED_IRQ_HANDLERS && !PICO_NO_RAM_VECTOR_TABLE
|
||||||
// used by irq_handler_chain.S to remove the last link in a handler chain after it executes
|
// used by irq_handler_chain.S to remove the last link in a handler chain after it executes
|
||||||
// note this must be called only with the last slot in a chain (and during the exception)
|
// note this must be called only with the last slot in a chain (and during the exception)
|
||||||
void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) {
|
void irq_add_tail_to_free_list(struct irq_handler_chain_slot *slot) {
|
||||||
|
|
@ -670,7 +676,7 @@ __weak void runtime_init_per_core_irq_priorities(void) {
|
||||||
*p++ = prio4;
|
*p++ = prio4;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (uint i = 0; i < NUM_IRQS; ++i) {
|
for (uint i = 0; i < PICO_NUM_VTABLE_IRQS; ++i) {
|
||||||
irq_set_priority(i, PICO_DEFAULT_IRQ_PRIORITY);
|
irq_set_priority(i, PICO_DEFAULT_IRQ_PRIORITY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -678,7 +684,7 @@ __weak void runtime_init_per_core_irq_priorities(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint get_user_irq_claim_index(uint irq_num) {
|
static uint get_user_irq_claim_index(uint irq_num) {
|
||||||
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= NUM_IRQS);
|
invalid_params_if(HARDWARE_IRQ, irq_num < FIRST_USER_IRQ || irq_num >= PICO_NUM_VTABLE_IRQS);
|
||||||
// we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
|
// we count backwards from the last, to match the existing hard coded uses of user IRQs in the SDK which were previously using 31
|
||||||
static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
|
static_assert(NUM_IRQS - FIRST_USER_IRQ <= 8, ""); // we only use a single byte's worth of claim bits today.
|
||||||
return NUM_IRQS - irq_num - 1u;
|
return NUM_IRQS - irq_num - 1u;
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,23 @@
|
||||||
|
|
||||||
pico_default_asm_setup
|
pico_default_asm_setup
|
||||||
|
|
||||||
|
#ifdef PICO_NO_STORED_VECTOR_TABLE
|
||||||
|
#warning PICO_NO_STORED_VECTOR_TABLE is no longer used. PICO_MINIMAL_STORED_VECTOR_TABLE is not identical but usually serves the same purpose
|
||||||
|
#endif
|
||||||
|
|
||||||
.section .vectors, "ax"
|
.section .vectors, "ax"
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
.global __vectors, __VECTOR_TABLE
|
.global __vectors, __VECTOR_TABLE, __vectors_end
|
||||||
__VECTOR_TABLE:
|
__VECTOR_TABLE:
|
||||||
__vectors:
|
__vectors:
|
||||||
.word __StackTop
|
.word __StackTop
|
||||||
.word _reset_handler
|
.word _reset_handler
|
||||||
|
|
||||||
|
#if PICO_MINIMAL_STORED_VECTOR_TABLE
|
||||||
|
.word isr_invalid // NMI
|
||||||
|
.word isr_invalid // HardFault
|
||||||
|
#else
|
||||||
.word isr_nmi
|
.word isr_nmi
|
||||||
.word isr_hardfault
|
.word isr_hardfault
|
||||||
.word isr_invalid // Reserved, should never fire
|
.word isr_invalid // Reserved, should never fire
|
||||||
|
|
@ -45,15 +54,9 @@ __vectors:
|
||||||
.word isr_invalid // Reserved, should never fire
|
.word isr_invalid // Reserved, should never fire
|
||||||
.word isr_pendsv
|
.word isr_pendsv
|
||||||
.word isr_systick
|
.word isr_systick
|
||||||
#if PICO_NO_STORED_VECTOR_TABLE && !PICO_NO_FLASH // note in no flash binary, we only have the single RAM vector table anyway
|
|
||||||
#if PICO_NO_RAM_VECTOR_TABLE
|
|
||||||
#error Can't specify PICO_NO_STORED_VECTOR_TABLE and PICO_NO_RAM_VECTOR_TABLE
|
|
||||||
#endif
|
|
||||||
// we don't include any IRQ vectors; we will initialize them during runtime_init in the RAM vector table
|
|
||||||
#else
|
|
||||||
|
|
||||||
.macro if_irq_word num func
|
.macro if_irq_word num func
|
||||||
.if \num < NUM_IRQS
|
.if \num < PICO_NUM_VTABLE_IRQS
|
||||||
.word \func
|
.word \func
|
||||||
.endif
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
@ -142,10 +145,11 @@ if_irq_word 76 isr_irq76
|
||||||
if_irq_word 77 isr_irq77
|
if_irq_word 77 isr_irq77
|
||||||
if_irq_word 78 isr_irq78
|
if_irq_word 78 isr_irq78
|
||||||
if_irq_word 79 isr_irq79
|
if_irq_word 79 isr_irq79
|
||||||
#if NUM_IRQS > 80
|
#if PICO_NUM_VTABLE_IRQS > 80
|
||||||
#error more IRQ entries required
|
#error more IRQ entries required
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif // #if !PICO_MINIMAL_STORED_VECTOR_TABLE
|
||||||
|
__vectors_end:
|
||||||
|
|
||||||
// all default exception handlers do nothing, and we can check for them being set to our
|
// all default exception handlers do nothing, and we can check for them being set to our
|
||||||
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
|
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
|
||||||
|
|
@ -164,24 +168,14 @@ __default_isrs_start:
|
||||||
bkpt #0
|
bkpt #0
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
// these are separated out for clarity
|
|
||||||
decl_isr_bkpt isr_invalid
|
|
||||||
decl_isr_bkpt isr_nmi
|
|
||||||
decl_isr_bkpt isr_hardfault
|
|
||||||
decl_isr_bkpt isr_svcall
|
|
||||||
decl_isr_bkpt isr_pendsv
|
|
||||||
decl_isr_bkpt isr_systick
|
|
||||||
|
|
||||||
.global __default_isrs_end
|
|
||||||
__default_isrs_end:
|
|
||||||
|
|
||||||
.altmacro
|
.altmacro
|
||||||
.macro decl_isr name
|
.macro decl_isr name
|
||||||
#if !PICO_NO_STORED_VECTOR_TABLE | PICO_NO_FLASH
|
#if !PICO_MINIMAL_STORED_VECTOR_TABLE | PICO_NO_FLASH
|
||||||
// We declare a weak label, so user can override
|
// We declare a weak label, so user can override
|
||||||
.weak \name
|
.weak \name
|
||||||
#else
|
#else
|
||||||
// We declare a strong label, so user can't override (their version would not automatically be used)
|
// We declare a strong global label, so user can't override (their version would not automatically be used)
|
||||||
|
.global \name
|
||||||
#endif
|
#endif
|
||||||
.type \name,%function
|
.type \name,%function
|
||||||
.thumb_func
|
.thumb_func
|
||||||
|
|
@ -189,8 +183,14 @@ __default_isrs_end:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro if_irq_decl num func
|
.macro if_irq_decl num func
|
||||||
.if \num < NUM_IRQS
|
.if \num < PICO_NUM_VTABLE_IRQS
|
||||||
decl_isr \func
|
decl_isr \func
|
||||||
|
.elseif \num < NUM_IRQS
|
||||||
|
// We declare a strong global label, so user can't override (their version would not automatically be used)
|
||||||
|
.global \func
|
||||||
|
.type \func,%function
|
||||||
|
.thumb_func
|
||||||
|
\func:
|
||||||
.endif
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
|
@ -274,7 +274,7 @@ if_irq_decl 76 isr_irq76
|
||||||
if_irq_decl 77 isr_irq77
|
if_irq_decl 77 isr_irq77
|
||||||
if_irq_decl 78 isr_irq78
|
if_irq_decl 78 isr_irq78
|
||||||
if_irq_decl 79 isr_irq79
|
if_irq_decl 79 isr_irq79
|
||||||
#if NUM_IRQS > 80
|
#if PICO_NUM_VTABLE_IRQS > 80
|
||||||
#error more IRQ entries required
|
#error more IRQ entries required
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -282,12 +282,30 @@ if_irq_decl 79 isr_irq79
|
||||||
.global __unhandled_user_irq
|
.global __unhandled_user_irq
|
||||||
.thumb_func
|
.thumb_func
|
||||||
__unhandled_user_irq:
|
__unhandled_user_irq:
|
||||||
|
// if we include the implementation if there could be a valid IRQ hanler in the vtable that uses it
|
||||||
|
#if !(PICO_NO_RAM_VECTOR_TABLE && PICO_MINIMAL_STORED_VECTOR_TABLE)
|
||||||
mrs r0, ipsr
|
mrs r0, ipsr
|
||||||
subs r0, #16
|
subs r0, #16
|
||||||
.global unhandled_user_irq_num_in_r0
|
.global unhandled_user_irq_num_in_r0
|
||||||
unhandled_user_irq_num_in_r0:
|
unhandled_user_irq_num_in_r0:
|
||||||
|
#endif
|
||||||
|
// note the next instruction is a breakpoint too, however we have a 2 byte alignment hole
|
||||||
|
// and it is preferrable to have distinct labels, to inform the user what has happened in the debugger.
|
||||||
bkpt #0
|
bkpt #0
|
||||||
|
|
||||||
|
decl_isr_bkpt isr_invalid
|
||||||
|
#if !PICO_MINIMAL_STORED_VECTOR_TABLE
|
||||||
|
// these are separated out for clarity
|
||||||
|
decl_isr_bkpt isr_nmi
|
||||||
|
decl_isr_bkpt isr_hardfault
|
||||||
|
decl_isr_bkpt isr_svcall
|
||||||
|
decl_isr_bkpt isr_pendsv
|
||||||
|
decl_isr_bkpt isr_systick
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.global __default_isrs_end
|
||||||
|
__default_isrs_end:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
.section .binary_info_header, "a"
|
.section .binary_info_header, "a"
|
||||||
|
|
|
||||||
|
|
@ -160,64 +160,22 @@ check_irq_before_exit:
|
||||||
addi sp, sp, 80
|
addi sp, sp, 80
|
||||||
mret
|
mret
|
||||||
|
|
||||||
|
|
||||||
// Default software vector table for system interrupts, routed through
|
// Default software vector table for system interrupts, routed through
|
||||||
// mip.meip. Note this is assumed in e.g. hardware_irq to begin exactly 0x34
|
// mip.meip. Note this is assumed in e.g. hardware_irq to begin exactly 0x34
|
||||||
// words after the hardware vector table indicated by mtvec (defined above).
|
// words after the hardware vector table indicated by mtvec (defined above).
|
||||||
.p2align 4
|
.p2align 4
|
||||||
.global __soft_vector_table
|
.global __soft_vector_table
|
||||||
__soft_vector_table:
|
__soft_vector_table:
|
||||||
.word isr_irq0
|
.macro vtable_irq_n n
|
||||||
.word isr_irq1
|
.word isr_irq\n
|
||||||
.word isr_irq2
|
.endm
|
||||||
.word isr_irq3
|
|
||||||
.word isr_irq4
|
.set IRQN, 0
|
||||||
.word isr_irq5
|
.rept PICO_NUM_VTABLE_IRQS
|
||||||
.word isr_irq6
|
vtable_irq_n IRQN
|
||||||
.word isr_irq7
|
.set IRQN, IRQN + 1
|
||||||
.word isr_irq8
|
.endr
|
||||||
.word isr_irq9
|
|
||||||
.word isr_irq10
|
|
||||||
.word isr_irq11
|
|
||||||
.word isr_irq12
|
|
||||||
.word isr_irq13
|
|
||||||
.word isr_irq14
|
|
||||||
.word isr_irq15
|
|
||||||
.word isr_irq16
|
|
||||||
.word isr_irq17
|
|
||||||
.word isr_irq18
|
|
||||||
.word isr_irq19
|
|
||||||
.word isr_irq20
|
|
||||||
.word isr_irq21
|
|
||||||
.word isr_irq22
|
|
||||||
.word isr_irq23
|
|
||||||
.word isr_irq24
|
|
||||||
.word isr_irq25
|
|
||||||
.word isr_irq26
|
|
||||||
.word isr_irq27
|
|
||||||
.word isr_irq28
|
|
||||||
.word isr_irq29
|
|
||||||
.word isr_irq30
|
|
||||||
.word isr_irq31
|
|
||||||
.word isr_irq32
|
|
||||||
.word isr_irq33
|
|
||||||
.word isr_irq34
|
|
||||||
.word isr_irq35
|
|
||||||
.word isr_irq36
|
|
||||||
.word isr_irq37
|
|
||||||
.word isr_irq38
|
|
||||||
.word isr_irq39
|
|
||||||
.word isr_irq40
|
|
||||||
.word isr_irq41
|
|
||||||
.word isr_irq42
|
|
||||||
.word isr_irq43
|
|
||||||
.word isr_irq44
|
|
||||||
.word isr_irq45
|
|
||||||
.word isr_irq46
|
|
||||||
.word isr_irq47
|
|
||||||
.word isr_irq48
|
|
||||||
.word isr_irq49
|
|
||||||
.word isr_irq50
|
|
||||||
.word isr_irq51
|
|
||||||
|
|
||||||
// all default trap handlers do nothing, and we can check for them being set to our
|
// all default trap handlers do nothing, and we can check for them being set to our
|
||||||
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
|
// default values by seeing if they point to somewhere between __defaults_isrs_start and __default_isrs_end
|
||||||
|
|
@ -252,58 +210,23 @@ decl_isr isr_riscv_machine_exception
|
||||||
decl_isr_bkpt isr_riscv_machine_timer
|
decl_isr_bkpt isr_riscv_machine_timer
|
||||||
decl_isr_bkpt isr_riscv_machine_soft_irq
|
decl_isr_bkpt isr_riscv_machine_soft_irq
|
||||||
|
|
||||||
decl_isr isr_irq0
|
// Declare all the ISR labels
|
||||||
decl_isr isr_irq1
|
.macro decl_isr_n n
|
||||||
decl_isr isr_irq2
|
.if \n < PICO_NUM_VTABLE_IRQS
|
||||||
decl_isr isr_irq3
|
decl_isr isr_irq\n
|
||||||
decl_isr isr_irq4
|
.elseif \n < NUM_IRQS
|
||||||
decl_isr isr_irq5
|
// We declare a strong label, so user can't override, since there is no vtable entry
|
||||||
decl_isr isr_irq6
|
.type isr_irq\n,%function
|
||||||
decl_isr isr_irq7
|
.thumb_func
|
||||||
decl_isr isr_irq8
|
isr_irq\n:
|
||||||
decl_isr isr_irq9
|
.endif
|
||||||
decl_isr isr_irq10
|
.endm
|
||||||
decl_isr isr_irq11
|
|
||||||
decl_isr isr_irq12
|
.set IRQN, 0
|
||||||
decl_isr isr_irq13
|
.rept PICO_NUM_VTABLE_IRQS
|
||||||
decl_isr isr_irq14
|
decl_isr_n IRQN
|
||||||
decl_isr isr_irq15
|
.set IRQN, IRQN + 1
|
||||||
decl_isr isr_irq16
|
.endr
|
||||||
decl_isr isr_irq17
|
|
||||||
decl_isr isr_irq18
|
|
||||||
decl_isr isr_irq19
|
|
||||||
decl_isr isr_irq20
|
|
||||||
decl_isr isr_irq21
|
|
||||||
decl_isr isr_irq22
|
|
||||||
decl_isr isr_irq23
|
|
||||||
decl_isr isr_irq24
|
|
||||||
decl_isr isr_irq25
|
|
||||||
decl_isr isr_irq26
|
|
||||||
decl_isr isr_irq27
|
|
||||||
decl_isr isr_irq28
|
|
||||||
decl_isr isr_irq29
|
|
||||||
decl_isr isr_irq30
|
|
||||||
decl_isr isr_irq31
|
|
||||||
decl_isr isr_irq32
|
|
||||||
decl_isr isr_irq33
|
|
||||||
decl_isr isr_irq34
|
|
||||||
decl_isr isr_irq35
|
|
||||||
decl_isr isr_irq36
|
|
||||||
decl_isr isr_irq37
|
|
||||||
decl_isr isr_irq38
|
|
||||||
decl_isr isr_irq39
|
|
||||||
decl_isr isr_irq40
|
|
||||||
decl_isr isr_irq41
|
|
||||||
decl_isr isr_irq42
|
|
||||||
decl_isr isr_irq43
|
|
||||||
decl_isr isr_irq44
|
|
||||||
decl_isr isr_irq45
|
|
||||||
decl_isr isr_irq46
|
|
||||||
decl_isr isr_irq47
|
|
||||||
decl_isr isr_irq48
|
|
||||||
decl_isr isr_irq49
|
|
||||||
decl_isr isr_irq50
|
|
||||||
decl_isr isr_irq51
|
|
||||||
// fall through
|
// fall through
|
||||||
|
|
||||||
// All unhandled USER IRQs fall through to here. Note there is no way to get
|
// All unhandled USER IRQs fall through to here. Note there is no way to get
|
||||||
|
|
|
||||||
25
src/rp2_common/pico_platform_common/BUILD.bazel
Normal file
25
src/rp2_common/pico_platform_common/BUILD.bazel
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
load("//bazel:defs.bzl", "compatible_with_rp2")
|
||||||
|
|
||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "pico_platform_common_headers",
|
||||||
|
hdrs = ["include/pico/platform/common.h"],
|
||||||
|
includes = ["include"],
|
||||||
|
visibility = [
|
||||||
|
"//src/rp2040/pico_platform:__pkg__",
|
||||||
|
"//src/rp2350/pico_platform:__pkg__",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "pico_platform_common",
|
||||||
|
srcs = ["common.c"],
|
||||||
|
target_compatible_with = compatible_with_rp2(),
|
||||||
|
deps = [
|
||||||
|
":pico_platform_common_headers",
|
||||||
|
"//src/rp2_common:platform_defs",
|
||||||
|
"//src/rp2_common/hardware_base",
|
||||||
|
"//src/common/pico_base_headers",
|
||||||
|
],
|
||||||
|
)
|
||||||
8
src/rp2_common/pico_platform_common/CMakeLists.txt
Normal file
8
src/rp2_common/pico_platform_common/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
if (NOT TARGET pico_platform_common)
|
||||||
|
pico_add_library(pico_platform_common)
|
||||||
|
target_sources(pico_platform_common INTERFACE ${CMAKE_CURRENT_LIST_DIR}/common.c)
|
||||||
|
|
||||||
|
target_include_directories(pico_platform_common_headers SYSTEM INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||||
|
|
||||||
|
target_link_libraries(pico_platform_common_headers INTERFACE hardware_regs)
|
||||||
|
endif()
|
||||||
30
src/rp2_common/pico_platform_common/common.c
Normal file
30
src/rp2_common/pico_platform_common/common.c
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pico.h"
|
||||||
|
#include "hardware/address_mapped.h"
|
||||||
|
#include "hardware/regs/tbman.h"
|
||||||
|
|
||||||
|
// Note we leave the FPGA check in by default so that we can run bug repro
|
||||||
|
// binaries coming in from the wild on the FPGA platform. It takes up around
|
||||||
|
// 48 bytes if you include all the calls, so you can pass PICO_NO_FPGA_CHECK=1
|
||||||
|
// to remove it. The FPGA check is used to skip initialisation of hardware
|
||||||
|
// (mainly clock generators and oscillators) that aren't present on FPGA.
|
||||||
|
|
||||||
|
#if !PICO_NO_FPGA_CHECK
|
||||||
|
// Inline stub provided in header if this code is unused (so folding can be
|
||||||
|
// done in each TU instead of relying on LTO)
|
||||||
|
bool __attribute__((weak)) running_on_fpga(void) {
|
||||||
|
return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_FPGA_BITS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !PICO_NO_SIM_CHECK
|
||||||
|
bool __attribute__((weak)) running_in_sim(void) {
|
||||||
|
return (*(io_ro_32 *)TBMAN_BASE) & TBMAN_PLATFORM_HDLSIM_BITS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2025 Raspberry Pi (Trading) Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PICO_PLATFORM_COMMON_H
|
||||||
|
#define _PICO_PLATFORM_COMMON_H
|
||||||
|
|
||||||
|
/** \file pico/platform/common.h
|
||||||
|
* \ingroup pico_platform
|
||||||
|
*
|
||||||
|
* \brief Macros and definitions common to all rp2 platforms but not specific to any library
|
||||||
|
*
|
||||||
|
* This header may be included by assembly code
|
||||||
|
*
|
||||||
|
* Note certain library specific defines are defined here when they are interdpedent across libraries,
|
||||||
|
* but making an explicit library dependency does not make sense.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// PICO_CONFIG: PICO_MINIMAL_STORED_VECTOR_TABLE, Only store a very minimal vector table in the binary on Arm, type=bool, default=0, advanced=true, group=pico_crt0
|
||||||
|
#ifndef PICO_MINIMAL_STORED_VECTOR_TABLE
|
||||||
|
#define PICO_MINIMAL_STORED_VECTOR_TABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PICO_MINIMAL_STORED_VECTOR_TABLE && (PICO_NO_FLASH && !defined(__riscv))
|
||||||
|
#if PICO_NUM_VTABLE_IRQS
|
||||||
|
#warning PICO_NUM_VTABLE_IRQS is specied with PICO_MINIMAL_STORED_VECTOR_TABLE for NO_FLASH Arm binary; ignored
|
||||||
|
#undef PICO_NUM_VTABLE_IRQS
|
||||||
|
#endif
|
||||||
|
#define PICO_NUM_VTABLE_IRQS 0
|
||||||
|
#else
|
||||||
|
// PICO_CONFIG: PICO_NUM_VTABLE_IRQS, Number of IRQ handlers in the vector table - can be lowered to save space if you aren't using some higher IRQs, type=int, default=NUM_IRQS, group=hardware_irq
|
||||||
|
#ifndef PICO_NUM_VTABLE_IRQS
|
||||||
|
#define PICO_NUM_VTABLE_IRQS NUM_IRQS
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
// PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime
|
||||||
|
#ifndef PICO_NO_FPGA_CHECK
|
||||||
|
#define PICO_NO_FPGA_CHECK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime
|
||||||
|
#ifndef PICO_NO_SIM_CHECK
|
||||||
|
#define PICO_NO_SIM_CHECK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PICO_NO_FPGA_CHECK
|
||||||
|
static inline bool running_on_fpga(void) {return false;}
|
||||||
|
#else
|
||||||
|
bool running_on_fpga(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if PICO_NO_SIM_CHECK
|
||||||
|
static inline bool running_in_sim(void) {return false;}
|
||||||
|
#else
|
||||||
|
bool running_in_sim(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*! \brief No-op function for the body of tight loops
|
||||||
|
* \ingroup pico_platform
|
||||||
|
*
|
||||||
|
* No-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 __force_inline void tight_loop_contents(void) {}
|
||||||
|
|
||||||
|
#define host_safe_hw_ptr(x) ((uintptr_t)(x))
|
||||||
|
#define native_safe_hw_ptr(x) host_safe_hw_ptr(x)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif // __ASSEMBLER__
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
#ifndef _PICO_PLATFORM_COMPILER_H
|
#ifndef _PICO_PLATFORM_COMPILER_H
|
||||||
#define _PICO_PLATFORM_COMPILER_H
|
#define _PICO_PLATFORM_COMPILER_H
|
||||||
|
|
||||||
/** \file platform_compiler.h
|
/** \file pico/platform/compiler.h
|
||||||
* \defgroup pico_platform pico_platform
|
* \ingroup pico_platform
|
||||||
*
|
*
|
||||||
* \brief Macros and definitions (and functions when included by non assembly code) to adapt for different compilers
|
* \brief Macros and definitions (and functions when included by non assembly code) to adapt for different compilers
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -195,23 +195,32 @@ PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_spin_locks_reset, PICO_RUNTIME_INIT_
|
||||||
// RISC-V to have an initial flash-resident vector table at a well-known
|
// RISC-V to have an initial flash-resident vector table at a well-known
|
||||||
// location, unlike Cortex-M which can take an NMI on cycle 0.
|
// location, unlike Cortex-M which can take an NMI on cycle 0.
|
||||||
#ifndef __riscv
|
#ifndef __riscv
|
||||||
|
#include "hardware/structs/scb.h"
|
||||||
|
#include "hardware/irq.h"
|
||||||
|
|
||||||
#if !PICO_RUNTIME_NO_INIT_INSTALL_RAM_VECTOR_TABLE
|
#if !PICO_RUNTIME_NO_INIT_INSTALL_RAM_VECTOR_TABLE
|
||||||
uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[PICO_RAM_VECTOR_TABLE_SIZE];
|
// note that this is not a safely overridable value, you should use override PICO_NUM_VTABLE_IRQs instead.
|
||||||
|
// keeping around as a #define though as it used to be supported
|
||||||
#include "hardware/structs/scb.h"
|
#ifdef PICO_RAM_VECTOR_TABLE_SIZE
|
||||||
void runtime_init_install_ram_vector_table(void) {
|
#warning Overriding PICO_RAM_VECTOR_TABLE_SIZE is deprecated; specify PICO_NUM_VTABLE_IRQS instead
|
||||||
// Note on RISC-V the RAM vector table is initialised during crt0
|
#endif
|
||||||
#if !(PICO_NO_RAM_VECTOR_TABLE || PICO_NO_FLASH) && !defined(__riscv)
|
#ifndef PICO_RAM_VECTOR_TABLE_SIZE
|
||||||
#if !PICO_NO_STORED_VECTOR_TABLE
|
#define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + PICO_NUM_VTABLE_IRQS)
|
||||||
__builtin_memcpy(ram_vector_table, (uint32_t *) scb_hw->vtor, sizeof(ram_vector_table));
|
|
||||||
#else
|
|
||||||
__builtin_memcpy(ram_vector_table, (uint32_t *) scb_hw->vtor, MIN(VTABLE_FIRST_IRQ, sizeof(ram_vector_table)));
|
|
||||||
for(uint i = VTABLE_FIRST_IRQ; i<count_of(ram_vector_table); i++) {
|
|
||||||
ram_vector_table[i] = (uintptr_t)__unhandled_user_irq;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t __attribute__((section(".ram_vector_table"))) ram_vector_table[PICO_RAM_VECTOR_TABLE_SIZE];
|
||||||
|
|
||||||
|
void runtime_init_install_ram_vector_table(void) {
|
||||||
|
// Note on RISC-V the RAM vector table is initialised during crt0
|
||||||
|
#if !(PICO_NO_RAM_VECTOR_TABLE || PICO_NO_FLASH)
|
||||||
|
extern uint32_t __vectors;
|
||||||
|
extern uint32_t __vectors_end;
|
||||||
|
uint32_t stored_words = &__vectors_end - &__vectors;
|
||||||
|
__builtin_memcpy(ram_vector_table, &__vectors, 4 * MIN(stored_words, PICO_RAM_VECTOR_TABLE_SIZE));
|
||||||
|
for(uint i = stored_words; i<count_of(ram_vector_table); i++) {
|
||||||
|
ram_vector_table[i] = (uintptr_t)__unhandled_user_irq;
|
||||||
|
}
|
||||||
scb_hw->vtor = (uintptr_t) ram_vector_table;
|
scb_hw->vtor = (uintptr_t) ram_vector_table;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue