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 
7 #ifndef _PICO_PLATFORM_H
8 #define _PICO_PLATFORM_H
9 
19 #include "hardware/platform_defs.h"
20 #include "hardware/regs/addressmap.h"
21 #include "hardware/regs/sio.h"
22 
23 // Marker for builds targeting the RP2040
24 #define PICO_RP2040 1
25 
26 // PICO_CONFIG: PICO_STACK_SIZE, Stack Size, min=0x100, default=0x800, advanced=true, group=pico_platform
27 #ifndef PICO_STACK_SIZE
28 #define PICO_STACK_SIZE _u(0x800)
29 #endif
30 
31 // PICO_CONFIG: PICO_HEAP_SIZE, Heap size to reserve, min=0x100, default=0x800, advanced=true, group=pico_platform
32 #ifndef PICO_HEAP_SIZE
33 #define PICO_HEAP_SIZE _u(0x800)
34 #endif
35 
36 // PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_platform
37 #ifndef PICO_NO_RAM_VECTOR_TABLE
38 #define PICO_NO_RAM_VECTOR_TABLE 0
39 #endif
40 
41 // 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
42 #ifndef PICO_RP2040_B0_SUPPORTED
43 #define PICO_RP2040_B0_SUPPORTED 1
44 #endif
45 
46 // 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
47 #ifndef PICO_FLOAT_SUPPORT_ROM_V1
48 #define PICO_FLOAT_SUPPORT_ROM_V1 1
49 #endif
50 
51 // 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
52 #ifndef PICO_DOUBLE_SUPPORT_ROM_V1
53 #define PICO_DOUBLE_SUPPORT_ROM_V1 1
54 #endif
55 
56 
57 // 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
58 #ifndef PICO_RP2040_B1_SUPPORTED
59 #define PICO_RP2040_B1_SUPPORTED 1
60 #endif
61 
62 // 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
63 #ifndef PICO_RP2040_B2_SUPPORTED
64 #define PICO_RP2040_B2_SUPPORTED 1
65 #endif
66 
67 // --- remainder of file is not included by assembly code ---
68 
69 #ifndef __ASSEMBLER__
70 
71 #include <sys/cdefs.h>
72 #include "pico/types.h"
73 
74 #ifdef __cplusplus
75 extern "C" {
76 #endif
77 
84 #define __isr
85 
98 #define __after_data(group) __attribute__((section(".after_data." group)))
99 
112 #define __not_in_flash(group) __attribute__((section(".time_critical." group)))
113 
129 #define __scratch_x(group) __attribute__((section(".scratch_x." group)))
130 
146 #define __scratch_y(group) __attribute__((section(".scratch_y." group)))
147 
163 #define __uninitialized_ram(group) __attribute__((section(".uninitialized_data." #group))) group
164 
177 #define __in_flash(group) __attribute__((section(".flashdata." group)))
178 
193 #define __not_in_flash_func(func_name) __not_in_flash(__STRING(func_name)) func_name
194 
212 #define __time_critical_func(func_name) __not_in_flash_func(func_name)
213 
226 #define __no_inline_not_in_flash_func(func_name) __noinline __not_in_flash_func(func_name)
227 
228 #define __packed_aligned __packed __aligned(4)
229 
238 #if defined(__GNUC__) && (__GNUC__ <= 6 || (__GNUC__ == 7 && (__GNUC_MINOR__ < 3 || !defined(__cplusplus))))
239 #define __force_inline inline __always_inline
240 #else
241 #define __force_inline __always_inline
242 #endif
243 
247 #ifndef count_of
248 #define count_of(a) (sizeof(a)/sizeof((a)[0]))
249 #endif
250 
254 #ifndef MAX
255 #define MAX(a, b) ((a)>(b)?(a):(b))
256 #endif
257 
261 #ifndef MIN
262 #define MIN(a, b) ((b)>(a)?(a):(b))
263 #endif
264 
268 static inline void __breakpoint(void) {
269  __asm__("bkpt #0");
270 }
271 
285  __asm__ volatile ("" : : : "memory");
286 }
287 
296 #define host_safe_hw_ptr(x) ((uintptr_t)(x))
297 #define native_safe_hw_ptr(x) host_safe_hw_ptr(x)
298 
299 
304 void __attribute__((noreturn)) panic_unsupported(void);
305 
315 void __attribute__((noreturn)) panic(const char *fmt, ...);
316 
317 #ifdef NDEBUG
318 #define panic_compact(...) panic(__VA_ARGS__)
319 #else
320 #define panic_compact(...) panic("")
321 #endif
322 
323 // PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=0, advanced=true, group=pico_runtime
324 #ifndef PICO_NO_FPGA_CHECK
325 #define PICO_NO_FPGA_CHECK 0
326 #endif
327 
328 #if PICO_NO_FPGA_CHECK
329 static inline bool running_on_fpga(void) {return false;}
330 #else
331 bool running_on_fpga(void);
332 #endif
333 
338 uint8_t rp2040_chip_version(void);
339 
344 static inline uint8_t rp2040_rom_version(void) {
345 #pragma GCC diagnostic push
346 #pragma GCC diagnostic ignored "-Warray-bounds"
347  return *(uint8_t*)0x13;
348 #pragma GCC diagnostic pop
349 }
350 
359 
370 __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) {
371  asm ("mul %0, %1" : "+l" (a) : "l" (b) : );
372  return a;
373 }
374 
388 #define __fast_mul(a, b) __builtin_choose_expr(__builtin_constant_p(b) && !__builtin_constant_p(a), \
389 (__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \
390 (a)*(b))
391 
398 #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));
399 
405 static inline uint __get_current_exception(void) {
406  uint exception;
407  asm ("mrs %0, ipsr" : "=l" (exception));
408  return exception;
409 }
410 
411 #define WRAPPER_FUNC(x) __wrap_ ## x
412 #define REAL_FUNC(x) __real_ ## x
413 
414 #ifdef __cplusplus
415 }
416 #endif
417 
432 static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) {
433  __asm volatile (
434  ".syntax unified\n"
435  "1: subs %0, #3\n"
436  "bcs 1b\n"
437  : "+r" (minimum_cycles) : : "memory"
438  );
439 }
440 
446 __force_inline static uint get_core_num(void) {
447  return (*(uint32_t *) (SIO_BASE + SIO_CPUID_OFFSET));
448 }
449 
450 #else // __ASSEMBLER__
451 
452 #define WRAPPER_FUNC_NAME(x) __wrap_##x
453 #define SECTION_NAME(x) .text.##x
454 #define RAM_SECTION_NAME(x) .time_critical.##x
455 
456 #endif // !__ASSEMBLER__
457 
458 #endif
__force_inline
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition: platform.h:241
__breakpoint
static void __breakpoint(void)
Execute a breakpoint instruction.
Definition: platform.h:268
panic
void panic(const char *fmt,...)
Displays a panic message and halts execution.
panic_unsupported
void panic_unsupported(void)
Panics with the message "Unsupported".
Definition: runtime.c:275
busy_wait_at_least_cycles
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:432
rp2040_chip_version
uint8_t rp2040_chip_version(void)
Returns the RP2040 chip revision number.
Definition: platform.c:29
get_core_num
static __always_inline uint get_core_num(void)
Get the current core number.
Definition: platform.h:446
tight_loop_contents
static __always_inline void tight_loop_contents(void)
No-op function for the body of tight loops.
Definition: platform.h:358
__compiler_memory_barrier
static __always_inline void __compiler_memory_barrier(void)
Ensure that the compiler does not move memory access across this method call.
Definition: platform.h:284
__get_current_exception
static uint __get_current_exception(void)
Get the current exception level on this core.
Definition: platform.h:405
__mul_instruction
static __always_inline int32_t __mul_instruction(int32_t a, int32_t b)
Multiply two integers using an assembly MUL instruction.
Definition: platform.h:370
rp2040_rom_version
static uint8_t rp2040_rom_version(void)
Returns the RP2040 rom version number.
Definition: platform.h:344