YAHAL
Yet Another Hardware Abstraction Library
Loading...
Searching...
No Matches
bootrom_rp2040.h
1//
2// Created by andreas on 01.01.26.
3//
4
5#ifndef _BOOTROM_RP2040_H
6#define _BOOTROM_RP2040_H
7
8#include <array>
9#include <cstdint>
10#include <functional>
11#include "board.h"
12
13#pragma GCC diagnostic push
14#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
15
17public:
18
19 static uint32_t popcount(uint32_t val) {
20 using T = uint32_t (*) (uint32_t);
21 return ((T) find_function(rom_code('P', '3')))(val);
22 }
23
24 static uint32_t reverse(uint32_t val) {
25 using T = uint32_t (*) (uint32_t);
26 return ((T) find_function(rom_code('R', '3')))(val);
27 }
28
29 // Flash access functions
31 // These functions are typically called from methods in RAM,
32 // because the code to handle e.g. flash programming must not
33 // be located in the FLASH. This is why these methods are all
34 // forced to be inline!
35
36 static void FORCE_INLINE connect_internal_flash() {
37 using T = void (*) ();
38 return ((T) find_function(rom_code('I', 'F')))();
39 }
40
41 static void FORCE_INLINE flash_exit_xip() {
42 using T = void (*) ();
43 return ((T) find_function(rom_code('E', 'X')))();
44 }
45
46 static void FORCE_INLINE flash_range_erase(uint32_t addr,
47 size_t count,
48 uint32_t block_size,
49 uint8_t block_cmd) {
50 using T = void (*) (uint32_t, size_t, uint32_t, uint8_t);
51 return ((T) find_function(rom_code('R', 'E')))(addr, count, block_size, block_cmd);
52 }
53
54 static void FORCE_INLINE flash_range_program(uint32_t addr,
55 uint8_t * data,
56 size_t count) {
57 using T = void (*) (uint32_t, uint8_t *, size_t);
58 return ((T) find_function(rom_code('R', 'P')))(addr, data, count);
59 }
60
61 static void FORCE_INLINE flash_flush_cache() {
62 using T = void (*) ();
63 return ((T) find_function(rom_code('F','C')))();
64 }
65
66 static void FORCE_INLINE flash_enter_cmd_xip() {
67 using T = void (*) ();
68 return ((T) find_function(rom_code('C','X')))();
69 }
70
71 static std::array<uint8_t, 8> read_unique_id();
72 static std::array<char, 17> read_unique_id_string();
73
74private:
75
76 static constexpr uint32_t rom_code(char c1, char c2) {
77 return (c2 << 8) | c1;
78 }
79
80 static inline void * find_function(uint32_t code) {
81 using T = void * (*)(uint16_t * table, uint32_t code);
82 auto func = (T)(_rom_header->lookup_function);
83 auto table = (uint16_t *)(_rom_header->function_table);
84 return func(table, code);
85 }
86
87 // RP2040 ROM layout for the first 26 bytes
88 static struct __attribute__((__packed__)) rom_header_t {
89 uint32_t * intial_sp;
90 void (*reset_handler)();
91 void (*nmi_handler)();
92 void (*hard_fault_handler)();
93 uint8_t magic[3];
94 uint8_t version;
95 uint16_t function_table;
96 uint16_t data_table;
97 uint16_t lookup_function;
98 } * _rom_header;
99 static_assert(sizeof(rom_header_t) == 26);
100
101 static uint8_t _tx_buffer[13];
102 static uint8_t _rx_buffer[13];
103
104 static uint32_t _boot2_copy[64];
105};
106
107#pragma GCC diagnostic push
108
109#endif // _BOOTROM_RP2040_H
void __attribute__((noreturn))(*rom_reset_usb_boot_fn)(uint32_t
Reboot the device into BOOTSEL mode.
Definition bootrom.h:66