Skip to content

Commit

Permalink
Add rom_data_lookup_inline function (#2116)
Browse files Browse the repository at this point in the history
* Move rom_data_lookup code into rom_data_lookup_inline

Allows ROM data lookup from FLASH/RAM sensitive code

* Use rom_data_lookup_inline in flash_devinfo_ptr

Fixes bug introduced by #2082 where flash_devinfo_get_cs_size would use rom_data_lookup from flash during a __no_inline_not_in_flash_func
  • Loading branch information
will-v-pi authored Dec 2, 2024
1 parent fe81780 commit 54784f8
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/rp2_common/hardware_flash/flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ void flash_get_unique_id(uint8_t *id_out) {
// device, so fields must have getters/setters.
static io_rw_16 * flash_devinfo_ptr(void) {
// Note the lookup returns a pointer to a 32-bit pointer literal in the ROM
io_rw_16 **p = (io_rw_16 **) rom_data_lookup(ROM_DATA_FLASH_DEVINFO16_PTR);
io_rw_16 **p = (io_rw_16 **) rom_data_lookup_inline(ROM_DATA_FLASH_DEVINFO16_PTR);
assert(p);
return *p;
}
Expand Down
18 changes: 1 addition & 17 deletions src/rp2_common/pico_bootrom/bootrom.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,9 @@ void *rom_func_lookup(uint32_t code) {
return rom_func_lookup_inline(code);
}

#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"
void *rom_data_lookup(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
return rom_data_lookup_inline(code);
}
#pragma GCC diagnostic pop
/// \end::table_lookup[]

bool rom_funcs_lookup(uint32_t *table, unsigned int count) {
Expand Down
26 changes: 26 additions & 0 deletions src/rp2_common/pico_bootrom/include/pico/bootrom.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,32 @@ static __force_inline void *rom_func_lookup_inline(uint32_t code) {
}
#pragma GCC diagnostic pop

/*!
* \brief Lookup a bootrom data address by its code. This method is forcibly inlined into the caller for FLASH/RAM sensitive code usage
* \ingroup pico_bootrom
* \param code the code
* \return a pointer to the data, or NULL if the code does not match any bootrom data
*/
#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

/*!
* \brief Reboot the device into BOOTSEL mode
* \ingroup pico_bootrom
Expand Down

0 comments on commit 54784f8

Please sign in to comment.