11#include "pico/bootrom_constants.h"
22#include "pico/bootrom/lock.h"
26typedef uint32_t (*rom_popcount32_fn)(uint32_t);
27typedef uint32_t (*rom_reverse32_fn)(uint32_t);
28typedef uint32_t (*rom_clz32_fn)(uint32_t);
29typedef uint32_t (*rom_ctz32_fn)(uint32_t);
30typedef uint8_t *(*rom_memset_fn)(uint8_t *, uint8_t, uint32_t);
31typedef uint32_t *(*rom_memset4_fn)(uint32_t *, uint8_t, uint32_t);
32typedef uint32_t *(*rom_memcpy_fn)(uint8_t *,
const uint8_t *, uint32_t);
33typedef uint32_t *(*rom_memcpy44_fn)(uint32_t *,
const uint32_t *, uint32_t);
35typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t);
36typedef int (*rom_reboot_fn)(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1);
37typedef rom_reset_usb_boot_fn reset_usb_boot_fn;
38typedef void (*rom_connect_internal_flash_fn)(void);
39typedef void (*rom_flash_exit_xip_fn)(void);
40typedef void (*rom_flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint8_t);
41typedef void (*rom_flash_range_program_fn)(uint32_t,
const uint8_t*, size_t);
42typedef void (*rom_flash_flush_cache_fn)(void);
43typedef void (*rom_flash_enter_cmd_xip_fn)(void);
45typedef void (*rom_bootrom_state_reset_fn)(uint32_t flags);
46typedef void (*rom_flash_reset_address_trans_fn)(void);
47typedef void (*rom_flash_select_xip_read_mode_fn)(bootrom_xip_mode_t mode, uint8_t clkdiv);
48typedef int (*rom_get_sys_info_fn)(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t flags);
49typedef int (*rom_get_partition_table_info_fn)(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t partition_and_flags);
50typedef int (*rom_explicit_buy_fn)(uint8_t *buffer, uint32_t buffer_size);
51typedef void* (*rom_validate_ns_buffer_fn)(
const void *addr, uint32_t size, uint32_t write, uint32_t *ok);
56typedef intptr_t (*rom_set_rom_callback_fn)(uint callback_num, bootrom_api_callback_generic_t funcptr);
57typedef int (*rom_chain_image_fn)(uint8_t *workarea_base, uint32_t workarea_size, uint32_t window_base, uint32_t window_size);
58typedef int (*rom_load_partition_table_fn)(uint8_t *workarea_base, uint32_t workarea_size,
bool force_reload);
59typedef int (*rom_pick_ab_partition_fn)(uint8_t *workarea_base, uint32_t workarea_size, uint partition_a_num, uint32_t flash_update_boot_window_base);
60typedef int (*rom_get_b_partition_fn)(uint pi_a);
61typedef int (*rom_get_uf2_target_partition_fn)(uint8_t *workarea_base, uint32_t workarea_size, uint32_t family_id,
resident_partition_t *partition_out);
62typedef int (*rom_func_otp_access_fn)(uint8_t *buf, uint32_t buf_len,
otp_cmd_t cmd);
68typedef intptr_t (*rom_flash_runtime_to_storage_addr_fn)(uintptr_t flash_runtime_addr);
77typedef int (*rom_flash_op_fn)(
cflash_flags_t flags, uintptr_t addr, uint32_t size_bytes, uint8_t *buf);
80typedef int (*rom_set_ns_api_permission_fn)(uint ns_api_num,
bool allowed);
93typedef int (*rom_func_secure_call)(uintptr_t a0, ...);
102typedef int (*rom_set_bootrom_stack_fn)(bootrom_stack_t *stack);
155typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code);
157typedef void *(*rom_table_lookup_fn)(uint32_t code, uint32_t mask);
160#if PICO_C_COMPILER_IS_GNU && (__GNUC__ >= 12)
162__force_inline static void *rom_hword_as_ptr(uint16_t rom_address) {
163#pragma GCC diagnostic push
164#pragma GCC diagnostic ignored "-Warray-bounds"
165 return (
void *)(uintptr_t)*(uint16_t *)(uintptr_t)rom_address;
166#pragma GCC diagnostic pop
170#define rom_hword_as_ptr(rom_address) (void *)(uintptr_t)(*(uint16_t *)(uintptr_t)(rom_address))
175#ifdef RASPBERRYPI_AMETHYST_FPGA
178 pico_default_asm_volatile (
182 "csrci mstatus, 0x8\n"
185 "csrrw t0, mtvec, t0\n"
214#pragma GCC diagnostic push
216#pragma GCC diagnostic ignored "-Warray-bounds"
219 rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET);
220 uint16_t *func_table = (uint16_t *) rom_hword_as_ptr(BOOTROM_FUNC_TABLE_OFFSET);
221 return rom_table_lookup(func_table, code);
224 uint32_t rom_offset_adjust = rom_size_is_64k() ? 32 * 1024 : 0;
226 rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_ENTRY_OFFSET + rom_offset_adjust);
227 return rom_table_lookup(code, RT_FLAG_FUNC_RISCV);
231 rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET);
232 if (pico_processor_state_is_nonsecure()) {
233 return rom_table_lookup(code, RT_FLAG_FUNC_ARM_NONSEC);
235 return rom_table_lookup(code, RT_FLAG_FUNC_ARM_SEC);
240#pragma GCC diagnostic pop
259void __attribute__((noreturn))
rom_reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask);
260static inline void __attribute__((noreturn)) reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) {
277 rom_connect_internal_flash_fn func = (rom_connect_internal_flash_fn)
rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH);
344 rom_flash_range_erase_fn func = (rom_flash_range_erase_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_ERASE);
345 func(addr, count, block_size, block_cmd);
369 rom_flash_range_program_fn func = (rom_flash_range_program_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_PROGRAM);
370 func(addr, data, count);
391 rom_flash_flush_cache_fn func = (rom_flash_flush_cache_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE);
407 rom_flash_enter_cmd_xip_fn func = (rom_flash_enter_cmd_xip_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_ENTER_CMD_XIP);
429static inline int rom_set_bootrom_stack(bootrom_stack_t *stack) {
430 rom_set_bootrom_stack_fn func = (rom_set_bootrom_stack_fn)
rom_func_lookup_inline(ROM_FUNC_SET_BOOTROM_STACK);
481static inline int rom_reboot(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1) {
483 return func(flags, delay_ms, p0, p1);
486bool rom_get_boot_random(uint32_t out[4]);
512static inline void rom_bootrom_state_reset(uint32_t flags) {
513 rom_bootrom_state_reset_fn func = (rom_bootrom_state_reset_fn)
rom_func_lookup_inline(ROM_FUNC_BOOTROM_STATE_RESET);
525static inline void rom_flash_reset_address_trans(
void) {
526 rom_flash_reset_address_trans_fn func = (rom_flash_reset_address_trans_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_RESET_ADDRESS_TRANS);
540static inline void rom_flash_select_xip_read_mode(bootrom_xip_mode_t mode, uint8_t clkdiv) {
541 rom_flash_select_xip_read_mode_fn func = (rom_flash_select_xip_read_mode_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_SELECT_XIP_READ_MODE);
584static inline int rom_flash_op(
cflash_flags_t flags, uintptr_t addr, uint32_t size_bytes, uint8_t *buf) {
586 if (!bootrom_try_acquire_lock(BOOTROM_LOCK_FLASH_OP))
587 return BOOTROM_ERROR_LOCK_REQUIRED;
588 int rc = func(flags, addr, size_bytes, buf);
589 bootrom_release_lock(BOOTROM_LOCK_FLASH_OP);
617static inline int rom_func_otp_access(uint8_t *buf, uint32_t buf_len,
otp_cmd_t cmd) {
619 if (!bootrom_try_acquire_lock(BOOTROM_LOCK_OTP))
620 return BOOTROM_ERROR_LOCK_REQUIRED;
621 int rc = func(buf, buf_len, cmd);
622 bootrom_release_lock(BOOTROM_LOCK_OTP);
654static inline int rom_get_partition_table_info(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t partition_and_flags) {
655 rom_get_partition_table_info_fn func = (rom_get_partition_table_info_fn)
rom_func_lookup_inline(ROM_FUNC_GET_PARTITION_TABLE_INFO);
656 if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
657 return BOOTROM_ERROR_LOCK_REQUIRED;
658 int rc = func(out_buffer, out_buffer_word_size, partition_and_flags);
659 bootrom_release_lock(BOOTROM_LOCK_SHA_256);
679static inline int rom_load_partition_table(uint8_t *workarea_base, uint32_t workarea_size,
bool force_reload) {
680 rom_load_partition_table_fn func = (rom_load_partition_table_fn)
rom_func_lookup_inline(ROM_FUNC_LOAD_PARTITION_TABLE);
681 if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
682 return BOOTROM_ERROR_LOCK_REQUIRED;
683 int rc = func(workarea_base, workarea_size, force_reload);
684 bootrom_release_lock(BOOTROM_LOCK_SHA_256);
711static inline int rom_pick_ab_partition(uint8_t *workarea_base, uint32_t workarea_size, uint partition_a_num, uint32_t flash_update_boot_window_base) {
712 rom_pick_ab_partition_fn func = (rom_pick_ab_partition_fn)
rom_func_lookup_inline(ROM_FUNC_PICK_AB_PARTITION);
713 if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
714 return BOOTROM_ERROR_LOCK_REQUIRED;
715 int rc = func(workarea_base, workarea_size, partition_a_num, flash_update_boot_window_base);
716 bootrom_release_lock(BOOTROM_LOCK_SHA_256);
729static inline int rom_get_b_partition(uint pi_a) {
755static inline int rom_get_uf2_target_partition(uint8_t *workarea_base, uint32_t workarea_size, uint32_t family_id,
resident_partition_t *partition_out) {
756 rom_get_uf2_target_partition_fn func = (rom_get_uf2_target_partition_fn)
rom_func_lookup_inline(ROM_FUNC_GET_UF2_TARGET_PARTITION);
757 if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
758 return BOOTROM_ERROR_LOCK_REQUIRED;
759 int rc = func(workarea_base, workarea_size, family_id, partition_out);
760 bootrom_release_lock(BOOTROM_LOCK_SHA_256);
776static inline intptr_t rom_flash_runtime_to_storage_addr(uintptr_t flash_runtime_addr) {
777 rom_flash_runtime_to_storage_addr_fn func = (rom_flash_runtime_to_storage_addr_fn)
rom_func_lookup_inline(ROM_FUNC_FLASH_RUNTIME_TO_STORAGE_ADDR);
778 return func(flash_runtime_addr);
809static inline int rom_chain_image(uint8_t *workarea_base, uint32_t workarea_size, uint32_t region_base, uint32_t region_size) {
811 bootrom_release_lock(BOOTROM_LOCK_ENABLE);
812 int rc = func(workarea_base, workarea_size, region_base, region_size);
813 bootrom_acquire_lock_blocking(BOOTROM_LOCK_ENABLE);
843static inline int rom_explicit_buy(uint8_t *buffer, uint32_t buffer_size) {
845 return func(buffer, buffer_size);
863static inline int rom_set_ns_api_permission(uint ns_api_num,
bool allowed) {
864 rom_set_ns_api_permission_fn func = (rom_set_ns_api_permission_fn)
rom_func_lookup_inline(ROM_FUNC_SET_NS_API_PERMISSION);
865 return func(ns_api_num, allowed);
889static inline void* rom_validate_ns_buffer(
const void *addr, uint32_t size, uint32_t write, uint32_t *ok) {
890 rom_validate_ns_buffer_fn func = (rom_validate_ns_buffer_fn)
rom_func_lookup_inline(ROM_FUNC_VALIDATE_NS_BUFFER);
891 return func(addr, size, write, ok);
908static inline intptr_t rom_set_rom_callback(uint callback_num, bootrom_api_callback_generic_t funcptr) {
909 rom_set_rom_callback_fn func = (rom_set_rom_callback_fn)
rom_func_lookup_inline(ROM_FUNC_SET_ROM_CALLBACK);
910 return func(callback_num, funcptr);
913#define BOOT_TYPE_NORMAL 0
914#define BOOT_TYPE_BOOTSEL 2
915#define BOOT_TYPE_RAM_IMAGE 3
916#define BOOT_TYPE_FLASH_UPDATE 4
919#define BOOT_TYPE_PC_SP 0xd
922#define BOOT_TYPE_CHAINED_FLAG 0x80
956static inline int rom_get_sys_info(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t flags) {
958 return func(out_buffer, out_buffer_word_size, flags);
964 int8_t diagnostic_partition_index;
967 uint8_t tbyb_and_update_info;
971 uint32_t boot_diagnostic;
972 uint32_t reboot_params[2];
975static inline int rom_get_boot_info(boot_info_t *info) {
977 int words_returned = rom_get_sys_info(result, 5, SYS_INFO_BOOT_INFO);
978 if (words_returned == (
sizeof(result)/
sizeof(result[0])) && result[0] == SYS_INFO_BOOT_INFO) {
979 memcpy(info, &result[1],
sizeof(boot_info_t));
986static inline int rom_get_last_boot_type_with_chained_flag(
void) {
988 int words_returned = rom_get_sys_info(result, 5, SYS_INFO_BOOT_INFO);
989 if (words_returned ==
count_of(result) && result[0] == SYS_INFO_BOOT_INFO) {
991 return (
int)((result[1] & 0xff00u) >> 8);
1002static inline int rom_get_last_boot_type(
void) {
1003 int rc = rom_get_last_boot_type_with_chained_flag();
1004 if (rc >= 0) rc &= ~BOOT_TYPE_CHAINED_FLAG;
1022int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32_t permissions);
@ PICO_ERROR_INVALID_DATA
A data structure failed to validate.
Definition error.h:40
void rom_reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask)
Reboot the device into BOOTSEL mode.
Definition bootrom.c:43
static uint32_t rom_table_code(uint8_t c1, uint8_t c2)
Return a bootrom lookup code based on two ASCII characters.
Definition bootrom.h:119
bool rom_funcs_lookup(uint32_t *table, unsigned int count)
Helper function to lookup the addresses of multiple bootrom functions.
Definition bootrom.c:33
static void rom_flash_exit_xip()
Return the QSPI device from its XIP state to a serial command state.
Definition bootrom.h:307
#define ROM_TABLE_CODE(c1, c2)
Return a bootrom lookup code based on two ASCII characters.
Definition bootrom_constants.h:157
static void rom_flash_range_program(uint32_t addr, const uint8_t *data, size_t count)
Program bytes in flash.
Definition bootrom.h:368
static __force_inline void * rom_func_lookup_inline(uint32_t code)
Lookup a bootrom function by code. This method is forcibly inlined into the caller for FLASH/RAM sens...
Definition bootrom.h:217
static void rom_connect_internal_flash()
Connect the SSI/QMI to the QSPI pads.
Definition bootrom.h:276
void * rom_func_lookup(uint32_t code)
Lookup a bootrom function by its code.
Definition bootrom.c:13
static void rom_flash_flush_cache()
Flush the XIP cache.
Definition bootrom.h:390
static void rom_flash_range_erase(uint32_t addr, size_t count, uint32_t block_size, uint8_t block_cmd)
Erase bytes in flash.
Definition bootrom.h:343
void * rom_data_lookup(uint32_t code)
Lookup a bootrom data address by its code.
Definition bootrom.c:20
static void rom_flash_enter_cmd_xip()
Configure the SSI/QMI with a standard command.
Definition bootrom.h:406
Definition bootrom_constants.h:305
Definition bootrom_constants.h:273
Definition bootrom_constants.h:262