Skip to content

Commit 35fd979

Browse files
committed
Fail if ROM funcs are missing.
Belt-and-braces in case we ever get a different RP2040 ROM with missing functions. Also use constants for the ROM addresses.
1 parent d8b90c0 commit 35fd979

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

src/main.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,23 @@ use core::mem::MaybeUninit;
77

88
use self::algo::*;
99

10-
fn find_func<T>(tag: [u8; 2]) -> T {
10+
fn find_func<T>(tag: [u8; 2]) -> Option<T> {
1111
let tag = u16::from_le_bytes(tag) as u32;
1212
type RomTableLookupFn = unsafe extern "C" fn(table: *const u16, code: u32) -> usize;
13+
/// This location in flash holds a 16-bit truncated pointer for the ROM lookup function
14+
const ROM_TABLE_LOOKUP_PTR: *const u16 = 0x0000_0018 as _;
15+
/// This location in flash holds a 16-bit truncated pointer for the ROM function table
16+
/// (there's also a ROM data table which we don't need)
17+
const FUNC_TABLE: *const u16 = 0x0000_0014 as _;
1318
unsafe {
14-
let lookup_func = core::ptr::read(0x0000_0018 as *const u16) as usize;
19+
let lookup_func = ROM_TABLE_LOOKUP_PTR.read() as usize;
1520
let lookup_func: RomTableLookupFn = core::mem::transmute(lookup_func);
16-
let table = core::ptr::read(0x0000_00014 as *const u16) as usize;
21+
let table = FUNC_TABLE.read() as usize;
1722
let result = lookup_func(table as *const u16, tag);
18-
core::mem::transmute_copy(&result)
23+
if result == 0 {
24+
return None;
25+
}
26+
Some(core::mem::transmute_copy(&result))
1927
}
2028
}
2129

@@ -29,15 +37,15 @@ struct ROMFuncs {
2937
}
3038

3139
impl ROMFuncs {
32-
fn load() -> Self {
33-
ROMFuncs {
34-
connect_internal_flash: find_func(*b"IF"),
35-
flash_exit_xip: find_func(*b"EX"),
36-
flash_range_erase: find_func(*b"RE"),
37-
flash_range_program: find_func(*b"RP"),
38-
flash_flush_cache: find_func(*b"FC"),
39-
flash_enter_cmd_xip: find_func(*b"CX"),
40-
}
40+
fn load() -> Option<Self> {
41+
Some(ROMFuncs {
42+
connect_internal_flash: find_func(*b"IF")?,
43+
flash_exit_xip: find_func(*b"EX")?,
44+
flash_range_erase: find_func(*b"RE")?,
45+
flash_range_program: find_func(*b"RP")?,
46+
flash_flush_cache: find_func(*b"FC")?,
47+
flash_enter_cmd_xip: find_func(*b"CX")?,
48+
})
4149
}
4250
}
4351

@@ -54,8 +62,9 @@ const FLASH_BASE: u32 = 0x1000_0000;
5462

5563
impl FlashAlgo for RP2040Algo {
5664
fn new(_address: u32, _clock: u32, _function: u32) -> Result<Self, ErrorCode> {
57-
let funcs = ROMFuncs::load();
58-
65+
let Some(funcs) = ROMFuncs::load() else {
66+
return Err(ErrorCode::new(1).unwrap());
67+
};
5968
(funcs.connect_internal_flash)();
6069
(funcs.flash_exit_xip)();
6170
Ok(Self { funcs })

0 commit comments

Comments
 (0)