@web-font-path: "roboto-debian.css";
v2.2.0 (RP2040)
Loading...
Searching...
No Matches
bootrom.h
Go to the documentation of this file.
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _PICO_BOOTROM_H
#define _PICO_BOOTROM_H
#include "pico.h"
#include "pico/bootrom_constants.h"
#ifndef __ASSEMBLER__
#include <string.h>
#include "pico/bootrom/lock.h"
#include "pico/flash.h"
// ROM FUNCTION SIGNATURES
#if PICO_RP2040
typedef uint32_t (*rom_popcount32_fn)(uint32_t);
typedef uint32_t (*rom_reverse32_fn)(uint32_t);
typedef uint32_t (*rom_clz32_fn)(uint32_t);
typedef uint32_t (*rom_ctz32_fn)(uint32_t);
typedef uint8_t *(*rom_memset_fn)(uint8_t *, uint8_t, uint32_t);
typedef uint32_t *(*rom_memset4_fn)(uint32_t *, uint8_t, uint32_t);
typedef uint32_t *(*rom_memcpy_fn)(uint8_t *, const uint8_t *, uint32_t);
typedef uint32_t *(*rom_memcpy44_fn)(uint32_t *, const uint32_t *, uint32_t);
#endif
typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t);
typedef int (*rom_reboot_fn)(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1);
typedef rom_reset_usb_boot_fn reset_usb_boot_fn; // kept for backwards compatibility
typedef void (*rom_connect_internal_flash_fn)(void);
typedef void (*rom_flash_exit_xip_fn)(void);
typedef void (*rom_flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint8_t);
typedef void (*rom_flash_range_program_fn)(uint32_t, const uint8_t*, size_t);
typedef void (*rom_flash_flush_cache_fn)(void);
typedef void (*rom_flash_enter_cmd_xip_fn)(void);
#if !PICO_RP2040
typedef void (*rom_bootrom_state_reset_fn)(uint32_t flags);
typedef void (*rom_flash_reset_address_trans_fn)(void);
typedef void (*rom_flash_select_xip_read_mode_fn)(bootrom_xip_mode_t mode, uint8_t clkdiv);
typedef int (*rom_get_sys_info_fn)(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t flags);
typedef int (*rom_get_partition_table_info_fn)(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t partition_and_flags);
typedef int (*rom_explicit_buy_fn)(uint8_t *buffer, uint32_t buffer_size);
typedef void* (*rom_validate_ns_buffer_fn)(const void *addr, uint32_t size, uint32_t write, uint32_t *ok);
typedef intptr_t (*rom_set_rom_callback_fn)(uint callback_num, bootrom_api_callback_generic_t funcptr);
typedef int (*rom_chain_image_fn)(uint8_t *workarea_base, uint32_t workarea_size, uint32_t window_base, uint32_t window_size);
typedef int (*rom_load_partition_table_fn)(uint8_t *workarea_base, uint32_t workarea_size, bool force_reload);
typedef 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);
typedef int (*rom_get_b_partition_fn)(uint pi_a);
typedef int (*rom_get_uf2_target_partition_fn)(uint8_t *workarea_base, uint32_t workarea_size, uint32_t family_id, resident_partition_t *partition_out);
typedef int (*rom_func_otp_access_fn)(uint8_t *buf, uint32_t buf_len, otp_cmd_t cmd);
// Apply the address translation currently specified in QMI_ATRANSx ("rolling window" hardware
// translation). Need to take care using this on the boot path, as the QMI may not yet have been
// set up, but this should be suitable for translating system bus addresses into flash storage
// addresses in user callbacks. Returns all-ones for an invalid address, which is also an invalid
// flash storage address, so invalidity is propagated.
typedef intptr_t (*rom_flash_runtime_to_storage_addr_fn)(uintptr_t flash_runtime_addr);
// Perform the specified erase/program/read operation, translating addresses according to
// QMI_ATRANSx if necessary, and checking flash permissions based on the resident partition table
// and the specified effective security level. `addr` may be either a flash runtime address or a
// flash storage address, depending on the ASPACE given in `flags`.
//
// NOTE: This function does not validate the buffer for NS access. This must be validated before
// calling if the caller is reachable from a Secure Gateway.
typedef int (*rom_flash_op_fn)(cflash_flags_t flags, uintptr_t addr, uint32_t size_bytes, uint8_t *buf);
#ifndef __riscv
typedef int (*rom_set_ns_api_permission_fn)(uint ns_api_num, bool allowed);
typedef int (*rom_func_secure_call)(uintptr_t a0, ...);
#endif
#ifdef __riscv
typedef struct {
uint32_t *base;
uint32_t size;
} bootrom_stack_t;
// passed in, and out.
typedef int (*rom_set_bootrom_stack_fn)(bootrom_stack_t *stack);
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t rom_table_code(uint8_t c1, uint8_t c2) {
return ROM_TABLE_CODE((uint32_t) c1, (uint32_t) c2);
}
void *rom_func_lookup(uint32_t code);
void *rom_data_lookup(uint32_t code);
bool rom_funcs_lookup(uint32_t *table, unsigned int count);
// Bootrom function: rom_table_lookup
// Returns the 32 bit pointer into the ROM if found or NULL otherwise.
#if PICO_RP2040
typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code);
#else
typedef void *(*rom_table_lookup_fn)(uint32_t code, uint32_t mask);
#endif
#if PICO_C_COMPILER_IS_GNU && (__GNUC__ >= 12)
// Convert a 16 bit pointer stored at the given rom address into a 32 bit pointer
__force_inline static void *rom_hword_as_ptr(uint16_t rom_address) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
return (void *)(uintptr_t)*(uint16_t *)(uintptr_t)rom_address;
#pragma GCC diagnostic pop
}
#else
// Convert a 16 bit pointer stored at the given rom address into a 32 bit pointer
#define rom_hword_as_ptr(rom_address) (void *)(uintptr_t)(*(uint16_t *)(uintptr_t)(rom_address))
#endif
#ifdef __riscv
static __force_inline bool rom_size_is_64k(void) {
#ifdef RASPBERRYPI_AMETHYST_FPGA
return *(uint16_t*)0x14 >= 0x8000;
#else
return false;
#endif
}
#endif
#pragma GCC diagnostic push
// diagnostic: GCC thinks near-zero value is a null pointer member access, but it's not
#pragma GCC diagnostic ignored "-Warray-bounds"
static __force_inline void *rom_func_lookup_inline(uint32_t code) {
#if PICO_RP2040
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET);
uint16_t *func_table = (uint16_t *) rom_hword_as_ptr(BOOTROM_FUNC_TABLE_OFFSET);
return rom_table_lookup(func_table, code);
#else
#ifdef __riscv
uint32_t rom_offset_adjust = rom_size_is_64k() ? 32 * 1024 : 0;
// on RISC-V the code (a jmp) is actually embedded in the table
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_ENTRY_OFFSET + rom_offset_adjust);
return rom_table_lookup(code, RT_FLAG_FUNC_RISCV);
#else
// on ARM the function pointer is stored in the table, so we dereference it
// via lookup() rather than lookup_entry()
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET);
if (pico_processor_state_is_nonsecure()) {
return rom_table_lookup(code, RT_FLAG_FUNC_ARM_NONSEC);
} else {
return rom_table_lookup(code, RT_FLAG_FUNC_ARM_SEC);
}
#endif
#endif
}
#pragma GCC diagnostic pop
#pragma GCC diagnostic push
// diagnostic: GCC thinks near-zero value is a null pointer member access, but it's not
#pragma GCC diagnostic ignored "-Warray-bounds"
static __force_inline void *rom_data_lookup_inline(uint32_t code) {
#if PICO_RP2040
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(BOOTROM_TABLE_LOOKUP_OFFSET);
uint16_t *data_table = (uint16_t *) rom_hword_as_ptr(BOOTROM_DATA_TABLE_OFFSET);
return rom_table_lookup(data_table, code);
#else
#ifdef __riscv
uint32_t rom_offset_adjust = rom_size_is_64k() ? 32 * 1024 : 0;
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET + rom_offset_adjust);
#else
rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET);
#endif
return rom_table_lookup(code, RT_FLAG_DATA);
#endif
}
#pragma GCC diagnostic pop
void __attribute__((noreturn)) rom_reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask);
static inline void __attribute__((noreturn)) reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) {
rom_reset_usb_boot(usb_activity_gpio_pin_mask, disable_interface_mask);
}
void __attribute__((noreturn)) rom_reset_usb_boot_extra(int usb_activity_gpio_pin, uint32_t disable_interface_mask, bool usb_activity_gpio_pin_active_low);
static inline void rom_connect_internal_flash(void) {
rom_connect_internal_flash_fn func = (rom_connect_internal_flash_fn) rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH);
func();
}
static inline void rom_flash_exit_xip(void) {
rom_flash_exit_xip_fn func = (rom_flash_exit_xip_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP);
func();
}
static inline void rom_flash_range_erase(uint32_t addr, size_t count, uint32_t block_size, uint8_t block_cmd) {
rom_flash_range_erase_fn func = (rom_flash_range_erase_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_ERASE);
func(addr, count, block_size, block_cmd);
}
static inline void rom_flash_range_program(uint32_t addr, const uint8_t *data, size_t count) {
rom_flash_range_program_fn func = (rom_flash_range_program_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_PROGRAM);
func(addr, data, count);
}
static inline void rom_flash_flush_cache(void) {
rom_flash_flush_cache_fn func = (rom_flash_flush_cache_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE);
func();
}
static inline void rom_flash_enter_cmd_xip(void) {
rom_flash_enter_cmd_xip_fn func = (rom_flash_enter_cmd_xip_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_ENTER_CMD_XIP);
func();
}
#if !PICO_RP2040 || PICO_COMBINED_DOCS
#ifdef __riscv
static inline int rom_set_bootrom_stack(bootrom_stack_t *stack) {
rom_set_bootrom_stack_fn func = (rom_set_bootrom_stack_fn) rom_func_lookup_inline(ROM_FUNC_SET_BOOTROM_STACK);
return func(stack);
}
#endif
static inline int rom_reboot(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1) {
rom_reboot_fn func = (rom_reboot_fn) rom_func_lookup_inline(ROM_FUNC_REBOOT);
return func(flags, delay_ms, p0, p1);
}
bool rom_get_boot_random(uint32_t out[4]);
static inline void rom_bootrom_state_reset(uint32_t flags) {
rom_bootrom_state_reset_fn func = (rom_bootrom_state_reset_fn) rom_func_lookup_inline(ROM_FUNC_BOOTROM_STATE_RESET);
return func(flags);
}
static inline void rom_flash_reset_address_trans(void) {
rom_flash_reset_address_trans_fn func = (rom_flash_reset_address_trans_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_RESET_ADDRESS_TRANS);
func();
}
static inline void rom_flash_select_xip_read_mode(bootrom_xip_mode_t mode, uint8_t clkdiv) {
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);
func(mode, clkdiv);
}
typedef struct {
cflash_flags_t flags;
uintptr_t addr;
uint32_t size_bytes;
uint8_t *buf;
int *res;
} rom_helper_flash_op_params_t;
static inline void rom_helper_flash_op(void *param) {
const rom_helper_flash_op_params_t *op = (const rom_helper_flash_op_params_t *)param;
rom_flash_op_fn func = (rom_flash_op_fn) rom_func_lookup_inline(ROM_FUNC_FLASH_OP);
*(op->res) = func(op->flags, op->addr, op->size_bytes, op->buf);
}
static inline int rom_flash_op(cflash_flags_t flags, uintptr_t addr, uint32_t size_bytes, uint8_t *buf) {
if (!bootrom_try_acquire_lock(BOOTROM_LOCK_FLASH_OP))
return BOOTROM_ERROR_LOCK_REQUIRED;
int rc = 0;
rom_helper_flash_op_params_t params = {
.flags = flags,
.addr = addr,
.size_bytes = size_bytes,
.buf = buf,
.res = &rc
};
int flash_rc = flash_safe_execute(rom_helper_flash_op, &params, UINT32_MAX);
bootrom_release_lock(BOOTROM_LOCK_FLASH_OP);
if (flash_rc != PICO_OK) {
return flash_rc;
} else {
return rc;
}
}
static inline int rom_func_otp_access(uint8_t *buf, uint32_t buf_len, otp_cmd_t cmd) {
rom_func_otp_access_fn func = (rom_func_otp_access_fn) rom_func_lookup_inline(ROM_FUNC_OTP_ACCESS);
if (!bootrom_try_acquire_lock(BOOTROM_LOCK_OTP))
return BOOTROM_ERROR_LOCK_REQUIRED;
int rc = func(buf, buf_len, cmd);
bootrom_release_lock(BOOTROM_LOCK_OTP);
return rc;
}
static inline int rom_get_partition_table_info(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t partition_and_flags) {
rom_get_partition_table_info_fn func = (rom_get_partition_table_info_fn) rom_func_lookup_inline(ROM_FUNC_GET_PARTITION_TABLE_INFO);
if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
return BOOTROM_ERROR_LOCK_REQUIRED;
int rc = func(out_buffer, out_buffer_word_size, partition_and_flags);
bootrom_release_lock(BOOTROM_LOCK_SHA_256);
return rc;
}
// todo SECURE only
static inline int rom_load_partition_table(uint8_t *workarea_base, uint32_t workarea_size, bool force_reload) {
rom_load_partition_table_fn func = (rom_load_partition_table_fn) rom_func_lookup_inline(ROM_FUNC_LOAD_PARTITION_TABLE);
if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
return BOOTROM_ERROR_LOCK_REQUIRED;
int rc = func(workarea_base, workarea_size, force_reload);
bootrom_release_lock(BOOTROM_LOCK_SHA_256);
return rc;
}
// todo SECURE only
static 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) {
rom_pick_ab_partition_fn func = (rom_pick_ab_partition_fn) rom_func_lookup_inline(ROM_FUNC_PICK_AB_PARTITION);
if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
return BOOTROM_ERROR_LOCK_REQUIRED;
int rc = func(workarea_base, workarea_size, partition_a_num, flash_update_boot_window_base);
bootrom_release_lock(BOOTROM_LOCK_SHA_256);
return rc;
}
int rom_pick_ab_partition_during_update(uint32_t *workarea_base, uint32_t workarea_size, uint partition_a_num);
static inline int rom_get_b_partition(uint pi_a) {
rom_get_b_partition_fn func = (rom_get_b_partition_fn) rom_func_lookup_inline(ROM_FUNC_GET_B_PARTITION);
return func(pi_a);
}
// todo SECURE only
static inline int rom_get_uf2_target_partition(uint8_t *workarea_base, uint32_t workarea_size, uint32_t family_id, resident_partition_t *partition_out) {
rom_get_uf2_target_partition_fn func = (rom_get_uf2_target_partition_fn) rom_func_lookup_inline(ROM_FUNC_GET_UF2_TARGET_PARTITION);
if (!bootrom_try_acquire_lock(BOOTROM_LOCK_SHA_256))
return BOOTROM_ERROR_LOCK_REQUIRED;
int rc = func(workarea_base, workarea_size, family_id, partition_out);
bootrom_release_lock(BOOTROM_LOCK_SHA_256);
return rc;
}
static inline intptr_t rom_flash_runtime_to_storage_addr(uintptr_t flash_runtime_addr) {
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);
return func(flash_runtime_addr);
}
// todo SECURE only
static inline int rom_chain_image(uint8_t *workarea_base, uint32_t workarea_size, uint32_t region_base, uint32_t region_size) {
rom_chain_image_fn func = (rom_chain_image_fn) rom_func_lookup_inline(ROM_FUNC_CHAIN_IMAGE);
bootrom_release_lock(BOOTROM_LOCK_ENABLE);
uint32_t interrupt_flags = save_and_disable_interrupts();
int rc = func(workarea_base, workarea_size, region_base, region_size);
restore_interrupts_from_disabled(interrupt_flags);
bootrom_acquire_lock_blocking(BOOTROM_LOCK_ENABLE);
return rc;
}
typedef struct {
uint8_t *buffer;
uint32_t buffer_size;
int *res;
} rom_helper_explicit_buy_params_t;
static inline void rom_helper_explicit_buy(void *param) {
const rom_helper_explicit_buy_params_t *op = (const rom_helper_explicit_buy_params_t *)param;
rom_explicit_buy_fn func = (rom_explicit_buy_fn) rom_func_lookup_inline(ROM_FUNC_EXPLICIT_BUY);
*(op->res) = func(op->buffer, op->buffer_size);
}
// todo SECURE only
static inline int rom_explicit_buy(uint8_t *buffer, uint32_t buffer_size) {
int rc = 0;
rom_helper_explicit_buy_params_t params = {
.buffer = buffer,
.buffer_size = buffer_size,
.res = &rc
};
int flash_rc = flash_safe_execute(rom_helper_explicit_buy, &params, UINT32_MAX);
if (flash_rc != PICO_OK) {
return flash_rc;
} else {
return rc;
}
}
#ifndef __riscv
static inline int rom_set_ns_api_permission(uint ns_api_num, bool allowed) {
rom_set_ns_api_permission_fn func = (rom_set_ns_api_permission_fn) rom_func_lookup_inline(ROM_FUNC_SET_NS_API_PERMISSION);
return func(ns_api_num, allowed);
}
#endif
// todo SECURE only
static inline void* rom_validate_ns_buffer(const void *addr, uint32_t size, uint32_t write, uint32_t *ok) {
rom_validate_ns_buffer_fn func = (rom_validate_ns_buffer_fn) rom_func_lookup_inline(ROM_FUNC_VALIDATE_NS_BUFFER);
return func(addr, size, write, ok);
}
static inline intptr_t rom_set_rom_callback(uint callback_num, bootrom_api_callback_generic_t funcptr) {
rom_set_rom_callback_fn func = (rom_set_rom_callback_fn) rom_func_lookup_inline(ROM_FUNC_SET_ROM_CALLBACK);
return func(callback_num, funcptr);
}
#define BOOT_TYPE_NORMAL 0
#define BOOT_TYPE_BOOTSEL 2
#define BOOT_TYPE_RAM_IMAGE 3
#define BOOT_TYPE_FLASH_UPDATE 4
// values 8-15 are secure only
#define BOOT_TYPE_PC_SP 0xd
// ORed in if a bootloader chained into the image
#define BOOT_TYPE_CHAINED_FLAG 0x80
static inline int rom_get_sys_info(uint32_t *out_buffer, uint32_t out_buffer_word_size, uint32_t flags) {
rom_get_sys_info_fn func = (rom_get_sys_info_fn)rom_func_lookup_inline(ROM_FUNC_GET_SYS_INFO);
return func(out_buffer, out_buffer_word_size, flags);
}
typedef struct {
union {
struct __packed {
int8_t diagnostic_partition_index; // used BOOT_PARTITION constants
uint8_t boot_type;
int8_t partition;
uint8_t tbyb_and_update_info;
};
uint32_t boot_word;
};
uint32_t boot_diagnostic;
uint32_t reboot_params[2];
} boot_info_t;
static inline int rom_get_boot_info(boot_info_t *info) {
uint32_t result[5];
int words_returned = rom_get_sys_info(result, 5, SYS_INFO_BOOT_INFO);
if (words_returned == (sizeof(result)/sizeof(result[0])) && result[0] == SYS_INFO_BOOT_INFO) {
memcpy(info, &result[1], sizeof(boot_info_t));
return true;
} else {
return false;
}
}
static inline int rom_get_last_boot_type_with_chained_flag(void) {
uint32_t result[5];
int words_returned = rom_get_sys_info(result, 5, SYS_INFO_BOOT_INFO);
if (words_returned == count_of(result) && result[0] == SYS_INFO_BOOT_INFO) {
// todo use struct
return (int)((result[1] & 0xff00u) >> 8);
} else {
return PICO_ERROR_INVALID_DATA;
}
}
// BOOT_TYPE_NORMAL 0x0
// BOOT_TYPE_BOOTSEL 0x2
// BOOT_TYPE_RAM_IMAGE 0x3
// BOOT_TYPE_FLASH_UPDATE 0x4
// BOOT_TYPE_PC_SP 0xd
static inline int rom_get_last_boot_type(void) {
int rc = rom_get_last_boot_type_with_chained_flag();
if (rc >= 0) rc &= ~BOOT_TYPE_CHAINED_FLAG;
return rc;
}
int rom_add_flash_runtime_partition(uint32_t start_offset, uint32_t size, uint32_t permissions);
#endif
#ifdef __cplusplus
}
#endif
#endif // !__ASSEMBLER__
#endif
save_and_disable_interrupts
static __force_inline uint32_t save_and_disable_interrupts(void)
Disable interrupts on the calling core, returning the previous interrupt state.
Definition sync.h:237
restore_interrupts_from_disabled
static __force_inline void restore_interrupts_from_disabled(uint32_t status)
Restore interrupts to a specified state on the calling core with restricted transitions.
Definition sync.h:280
PICO_OK
@ PICO_OK
No error; the operation succeeded.
Definition error.h:23
PICO_ERROR_INVALID_DATA
@ PICO_ERROR_INVALID_DATA
A data structure failed to validate.
Definition error.h:40
rom_flash_flush_cache
static void rom_flash_flush_cache(void)
Flush the XIP cache.
Definition bootrom.h:411
rom_reset_usb_boot
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:35
rom_table_code
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:120
rom_funcs_lookup
bool rom_funcs_lookup(uint32_t *table, unsigned int count)
Helper function to lookup the addresses of multiple bootrom functions.
Definition bootrom.c:25
rom_connect_internal_flash
static void rom_connect_internal_flash(void)
Connect the SSI/QMI to the QSPI pads.
Definition bootrom.h:297
rom_flash_exit_xip
static void rom_flash_exit_xip(void)
Return the QSPI device from its XIP state to a serial command state.
Definition bootrom.h:328
rom_flash_enter_cmd_xip
static void rom_flash_enter_cmd_xip(void)
Configure the SSI/QMI with a standard command.
Definition bootrom.h:427
ROM_TABLE_CODE
#define ROM_TABLE_CODE(c1, c2)
Return a bootrom lookup code based on two ASCII characters.
Definition bootrom_constants.h:155
rom_flash_range_program
static void rom_flash_range_program(uint32_t addr, const uint8_t *data, size_t count)
Program bytes in flash.
Definition bootrom.h:389
rom_func_lookup_inline
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:193
rom_func_lookup
void * rom_func_lookup(uint32_t code)
Lookup a bootrom function by its code.
Definition bootrom.c:16
rom_data_lookup_inline
static __force_inline void * rom_data_lookup_inline(uint32_t code)
Lookup a bootrom data address by its code. This method is forcibly inlined into the caller for FLASH/...
Definition bootrom.h:227
rom_flash_range_erase
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:364
rom_data_lookup
void * rom_data_lookup(uint32_t code)
Lookup a bootrom data address by its code.
Definition bootrom.c:20
rom_reset_usb_boot_extra
void rom_reset_usb_boot_extra(int usb_activity_gpio_pin, uint32_t disable_interface_mask, bool usb_activity_gpio_pin_active_low)
Reboot the device into BOOTSEL mode.
Definition bootrom.c:53
flash_safe_execute
int flash_safe_execute(void(*func)(void *), void *param, uint32_t enter_exit_timeout_ms)
Execute a function with IRQs disabled and with the other core also not executing/reading flash.
Definition flash.c:75
__force_inline
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition compiler.h:128
count_of
#define count_of(a)
Macro to determine the number of elements in an array.
Definition compiler.h:135
pico.h
flash.h
resident_partition_t
Definition bootrom_constants.h:269