From d6231bd3ecde9de064beaf9c3b05e05e6bbabbe0 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Mon, 15 Feb 2021 22:16:43 +0000 Subject: [PATCH 1/2] fix rom_table_lookup It seems like the rom_table_lookup missed one level of pointer dereferencing. After comparing it to the working call to reset_usb_boot() in https://github.com/jannic/rp-microcontroller-rs/blob/master/util/rp2040-panic-usb-boot/src/lib.rs, I changed the code until it generated basically the same assembly. With that change, I was able to successfully call rom_data::reset_to_usb_boot() I still don't like the type RomTableLookupFn, which just returns some generic T without any checks, and I think rom_table_lookup should be unsafe. But as none of those are pub, it doesn't matter too much. So I just made the changes necessary to make the code work. --- rp2040-hal/src/rom_data.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/rp2040-hal/src/rom_data.rs b/rp2040-hal/src/rom_data.rs index 9f46297..64e0c3f 100644 --- a/rp2040-hal/src/rom_data.rs +++ b/rp2040-hal/src/rom_data.rs @@ -11,19 +11,25 @@ type RomTableLookupFn = unsafe extern "C" fn(*const u16, u32) -> T; const ROM_TABLE_LOOKUP_PTR: *const u16 = 0x18 as _; /// Pointer to helper functions lookup table. -const FUNC_TABLE: *const *const u16 = 0x14 as _; +const FUNC_TABLE: *const u16 = 0x14 as _; /// Pointer to the public data lookup table. -const DATA_TABLE: *const *const u16 = 0x16 as _; +const DATA_TABLE: *const u16 = 0x16 as _; /// Retrive rom content from a table using a code. -fn rom_table_lookup(table: *const *const u16, tag: RomFnTableCode) -> T { +fn rom_table_lookup(table: *const u16, tag: RomFnTableCode) -> T { unsafe { - let rom_table_lookup: RomTableLookupFn = core::mem::transmute(ROM_TABLE_LOOKUP_PTR); - rom_table_lookup(*table, u16::from_le_bytes(tag) as u32) + let rom_table_lookup_ptr: *const u32 = rom_hword_as_ptr(ROM_TABLE_LOOKUP_PTR); + let rom_table_lookup: RomTableLookupFn = core::mem::transmute(rom_table_lookup_ptr); + rom_table_lookup(rom_hword_as_ptr(table) as *const u16, u16::from_le_bytes(tag) as u32) } } +unsafe fn rom_hword_as_ptr(rom_address: *const u16) -> *const u32 { + let ptr: u16 = *rom_address; + ptr as *const u32 +} + macro_rules! rom_funcs { ( $( From 5494ce753922b4b996a6d7a664c4dbda1c880652 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Mon, 15 Feb 2021 23:28:13 +0000 Subject: [PATCH 2/2] rom function git_revision() does return an u32, not a &str --- rp2040-hal/src/rom_data.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rp2040-hal/src/rom_data.rs b/rp2040-hal/src/rom_data.rs index 64e0c3f..cbf99ef 100644 --- a/rp2040-hal/src/rom_data.rs +++ b/rp2040-hal/src/rom_data.rs @@ -144,9 +144,9 @@ pub fn copyright_string() -> &'static str { } /// The 8 most significant hex digits of the Bootrom git revision. -pub fn git_revision() -> &'static str { - let s: *const u8 = rom_table_lookup(DATA_TABLE, *b"GR"); - unsafe { convert_str(s) } +pub fn git_revision() -> u32 { + let s: *const u32 = rom_table_lookup(DATA_TABLE, *b"GR"); + unsafe { *s } } /// The start address of the floating point library code and data. This and fplib_end along with the individual