Loading...
Searching...
No Matches
platform.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
15
16#ifndef _PICO_PLATFORM_H
17#define _PICO_PLATFORM_H
18
19#ifndef _PICO_H
20#error pico/platform.h should not be included directly; include pico.h instead
21#endif
22
23// this is used by sections.h, so comes before the includes
24// PICO_CONFIG: PICO_USE_XIP_CACHE_AS_RAM, Whether to use xip cache as ram, default=0, type=bool, group=pico_platform
25#ifndef PICO_USE_XIP_CACHE_AS_RAM
26#define PICO_USE_XIP_CACHE_AS_RAM 0
27#endif
28
30#include "pico/platform/sections.h"
31#include "pico/platform/panic.h"
33#include "hardware/regs/addressmap.h"
34#include "hardware/regs/sio.h"
35#ifdef __riscv
36#include "hardware/regs/rvcsr.h"
37#endif
38
39// 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
40#if 0 // make tooling checks happy
41#define PICO_RP2350A 0
42#endif
43
44// PICO_CONFIG: PICO_RP2350_A2_SUPPORTED, Whether to include any specific software support for RP2350 A2 revision, type=bool, default=1, advanced=true, group=pico_platform
45#ifndef PICO_RP2350_A2_SUPPORTED
46#define PICO_RP2350_A2_SUPPORTED 1
47#endif
48
49// PICO_CONFIG: PICO_STACK_SIZE, Minimum amount of stack space reserved in the linker script for each core. See also PICO_CORE1_STACK_SIZE, min=0x100, default=0x800, advanced=true, group=pico_platform
50#ifndef PICO_STACK_SIZE
51#define PICO_STACK_SIZE _u(0x800)
52#endif
53
54// PICO_CONFIG: PICO_HEAP_SIZE, Minimum amount of heap space reserved by the linker script, min=0x100, default=0x800, advanced=true, group=pico_platform
55#ifndef PICO_HEAP_SIZE
56#define PICO_HEAP_SIZE _u(0x800)
57#endif
58
59// PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_platform
60#ifndef PICO_NO_RAM_VECTOR_TABLE
61#define PICO_NO_RAM_VECTOR_TABLE 0
62#endif
63
64// PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform
65#ifndef PICO_USE_STACK_GUARDS
66#define PICO_USE_STACK_GUARDS 0
67#endif
68
69// 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
70#ifndef PICO_CLKDIV_ROUND_NEAREST
71#define PICO_CLKDIV_ROUND_NEAREST 1
72#endif
73
74#ifndef __ASSEMBLER__
75
76#ifdef __cplusplus
77extern "C" {
78#endif
93static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) {
94 pico_default_asm_volatile (
95#ifdef __riscv
96 // Note the range is halved on RISC-V due to signed comparison (no carry flag)
97 ".option push\n"
98 ".option norvc\n" // force 32 bit addi, so branch prediction guaranteed
99 ".p2align 2\n"
100 "1: \n"
101 "addi %0, %0, -2 \n"
102 "bgez %0, 1b\n"
103 ".option pop"
104#else
105 "1: subs %0, #3\n"
106 "bcs 1b\n"
107#endif
108 : "+r" (minimum_cycles) : : "cc", "memory"
109 );
110}
111
115static __force_inline void __breakpoint(void) {
116#ifdef __riscv
117 __asm ("ebreak");
118#else
119 pico_default_asm_volatile ("bkpt #0" : : : "memory");
120#endif
121}
122
128__force_inline static uint get_core_num(void) {
129 return (*(uint32_t *) (SIO_BASE + SIO_CPUID_OFFSET));
130}
131
146#ifdef __riscv
147 uint32_t meicontext;
148 pico_default_asm_volatile (
149 "csrr %0, %1\n"
150 : "=r" (meicontext) : "i" (RVCSR_MEICONTEXT_OFFSET)
151 );
152 if (meicontext & RVCSR_MEICONTEXT_NOIRQ_BITS) {
153 return 0;
154 } else {
155 return VTABLE_FIRST_IRQ + (
156 (meicontext & RVCSR_MEICONTEXT_IRQ_BITS) >> RVCSR_MEICONTEXT_IRQ_LSB
157 );
158 }
159#else
160 uint exception;
161 pico_default_asm_volatile (
162 "mrs %0, ipsr\n"
163 "uxtb %0, %0\n"
164 : "=l" (exception)
165 );
166 return exception;
167#endif
168}
169
176#ifndef __riscv
177 // todo add a define to disable NS checking at all?
178 // IDAU-Exempt addresses return S=1 when tested in the Secure state,
179 // whereas executing a tt in the NonSecure state will always return S=0.
180 uint32_t tt;
181 pico_default_asm_volatile (
182 "movs %0, #0\n"
183 "tt %0, %0\n"
184 : "=r" (tt) : : "cc"
185 );
186 return !(tt & (1u << 22));
187#else
188 // NonSecure is an Arm concept, there is nothing meaningful to return
189 // here. Note it's not possible in general to detect whether you are
190 // executing in U-mode as, for example, M-mode is classically
191 // virtualisable in U-mode.
192 return false;
193#endif
194}
195
200uint8_t rp2350_chip_version(void);
201
206static inline uint8_t rp2040_chip_version(void) {
207 return 2;
208}
209
214static inline uint8_t rp2350_rom_version(void) {
215 GCC_Pragma("GCC diagnostic push")
216 GCC_Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
217 return *(uint8_t*)0x13;
218 GCC_Pragma("GCC diagnostic pop")
219}
220
231__force_inline static int32_t __mul_instruction(int32_t a, int32_t b) {
232#ifdef __riscv
233 __asm ("mul %0, %0, %1" : "+r" (a) : "r" (b) : );
234#else
235 pico_default_asm ("muls %0, %1" : "+l" (a) : "l" (b) : "cc");
236#endif
237 return a;
238}
239
253#define __fast_mul(a, b) (__builtin_constant_p(b) && !__builtin_constant_p(a) && __builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b))
254
255#ifdef __cplusplus
256}
257#endif
258
259#endif // __ASSEMBLER__
260
261#endif
262
Macros and definitions common to all rp2 platforms but not specific to any library.
Macros and definitions (and functions when included by non assembly code) to adapt for different comp...
static __force_inline uint __get_current_exception(void)
Get the current exception level on this core.
Definition platform.h:145
uint8_t rp2350_chip_version(void)
Returns the RP2350 chip revision number.
Definition platform.c:14
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition compiler.h:128
static void busy_wait_at_least_cycles(uint32_t minimum_cycles)
Helper method to busy-wait for at least the given number of cycles.
Definition platform.h:93
static __force_inline uint get_core_num(void)
Get the current core number.
Definition platform.h:128
static __force_inline bool pico_processor_state_is_nonsecure(void)
Return true if executing in the NonSecure state (Arm-only).
Definition platform.h:175
static __force_inline void __breakpoint(void)
Execute a breakpoint instruction.
Definition platform.h:115
static __force_inline int32_t __mul_instruction(int32_t a, int32_t b)
Multiply two integers using an assembly MUL instruction.
Definition platform.h:231
static uint8_t rp2040_chip_version(void)
Returns the RP2040 chip revision number for compatibility.
Definition platform.h:206
static uint8_t rp2350_rom_version(void)
Returns the RP2350 rom version number.
Definition platform.h:214