Skip to content

Commit

Permalink
Merge pull request #18 from rp-rs/update-rustc
Browse files Browse the repository at this point in the history
Now builds on stable.
  • Loading branch information
thejpster authored Dec 12, 2023
2 parents 7bb71a0 + 1d215be commit 0c2ac40
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 55 deletions.
5 changes: 0 additions & 5 deletions .cargo/config
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
[unstable]
build-std = ["core"]
build-std-features = ["panic_immediate_abort"]

[target.'cfg(all(target_arch = "arm", target_os = "none"))']

rustflags = [
"-C", "link-arg=--nmagic",
"-C", "link-arg=-Tlink.x",

# Code-size optimizations.
"-Z", "trap-unreachable=no",
"-C", "inline-threshold=5",
"-C", "no-vectorize-loops",
"-C", "force-frame-pointers=no",
Expand Down
5 changes: 0 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,12 @@ env:

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: |
sudo apt update
rustup component add rust-src
cargo install cargo-binutils
rustup component add llvm-tools-preview
- name: Build
run: |
./build.sh
Expand Down
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,27 @@ It implements the CMSIS-Pack ABI, so it's compatible with any tools that use it,

## Dependencies

Run the following requirements:
Run the following to install the requirements:

```bash
cargo install cargo-binutils && rustup component add llvm-tools-preview rust-src
cargo install cargo-binutils
```
## Building

Building requires nightly Rust.
The `rust-toolchain` file will get you the targets and components you need.

## Building

Just run `build.sh`. It spits out the flash algo in the probe-rs YAML format:

flash-algo$ ./build.sh
```console
flash-algo$ ./build.sh
instructions: sLUUIACIGUoBRguI...wRwAgcEc=
pc_init: 0x00000000
pc_uninit: 0x0000007c
pc_program_page: 0x00000088
pc_erase_sector: 0x00000084
pc_erase_all: 0x00000080
```

## Hacking

Expand All @@ -30,7 +34,7 @@ the glue functions for a given struct implementing it. This is generic for all c

`main.rs` has the actual implementation for RP2040.

# License
## License

This thingy is licensed under either of

Expand Down
6 changes: 5 additions & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
nightly
[toolchain]
channel = "stable"
components = [ "llvm-tools" ]
profile = "minimal"
targets = ["thumbv6m-none-eabi"]
41 changes: 31 additions & 10 deletions src/algo.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![macro_use]


use core::arch::asm;
use core::num::NonZeroU32;

Expand All @@ -12,10 +11,6 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
}
}

pub const FUNCTION_ERASE: u32 = 1;
pub const FUNCTION_PROGRAM: u32 = 2;
pub const FUNCTION_VERIFY: u32 = 3;

pub type ErrorCode = NonZeroU32;

pub trait FlashAlgo: Sized + 'static {
Expand All @@ -38,6 +33,12 @@ macro_rules! algo {
static mut _IS_INIT: bool = false;
static mut _ALGO_INSTANCE: MaybeUninit<$type> = MaybeUninit::uninit();

/// Initialise the Flash Algorithm
///
/// # Safety
///
/// Will disable execution from Flash. Ensure you are running from SRAM
/// and do not call any flash-based based functions.
#[no_mangle]
#[link_section = ".entry"]
pub unsafe extern "C" fn Init(addr: u32, clock: u32, function: u32) -> u32 {
Expand All @@ -53,16 +54,25 @@ macro_rules! algo {
Err(e) => e.get(),
}
}
/// Uninitialise the Flash Algorithm
#[no_mangle]
#[link_section = ".entry"]
pub unsafe extern "C" fn UnInit() -> u32 {
if !_IS_INIT {
return 1;
pub extern "C" fn UnInit() -> u32 {
unsafe {
if !_IS_INIT {
return 1;
}
_ALGO_INSTANCE.as_mut_ptr().drop_in_place();
_IS_INIT = false;
}
_ALGO_INSTANCE.as_mut_ptr().drop_in_place();
_IS_INIT = false;
0
}
/// Erase the flash chip.
///
/// # Safety
///
/// Will erase the flash chip. Ensure you really want to erase the
/// flash chip.
#[no_mangle]
#[link_section = ".entry"]
pub unsafe extern "C" fn EraseChip() -> u32 {
Expand All @@ -75,6 +85,11 @@ macro_rules! algo {
Err(e) => e.get(),
}
}
/// Erase the a sector on the flash chip.
///
/// # Safety
///
/// Will erase the given sector. Pass a valid sector address.
#[no_mangle]
#[link_section = ".entry"]
pub unsafe extern "C" fn EraseSector(addr: u32) -> u32 {
Expand All @@ -87,6 +102,12 @@ macro_rules! algo {
Err(e) => e.get(),
}
}
/// Write to a page on the flash chip.
///
/// # Safety
///
/// Will program the given page. Pass a valid page address, and a
/// valid pointer to at least `size` bytes of data.
#[no_mangle]
#[link_section = ".entry"]
pub unsafe extern "C" fn ProgramPage(addr: u32, size: u32, data: *const u8) -> u32 {
Expand Down
55 changes: 27 additions & 28 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,27 @@

mod algo;

use core::mem;
use core::mem::MaybeUninit;

use self::algo::*;

fn find_func<T>(tag: [u8; 2]) -> T {
let tag = u16::from_le_bytes(tag);

fn find_func<T>(tag: [u8; 2]) -> Option<T> {
let tag = u16::from_le_bytes(tag) as u32;
type RomTableLookupFn = unsafe extern "C" fn(table: *const u16, code: u32) -> usize;
/// This location in flash holds a 16-bit truncated pointer for the ROM lookup function
const ROM_TABLE_LOOKUP_PTR: *const u16 = 0x0000_0018 as _;
/// This location in flash holds a 16-bit truncated pointer for the ROM function table
/// (there's also a ROM data table which we don't need)
const FUNC_TABLE: *const u16 = 0x0000_0014 as _;
unsafe {
let mut entry = *(0x00000014 as *const u16) as *const u16;
loop {
let entry_tag = entry.read();
if entry_tag == 0 {
panic!("Func not found");
}
entry = entry.add(1);
let entry_addr = entry.read();
entry = entry.add(1);
if entry_tag == tag {
return mem::transmute_copy(&(entry_addr as u32));
}
let lookup_func = ROM_TABLE_LOOKUP_PTR.read() as usize;
let lookup_func: RomTableLookupFn = core::mem::transmute(lookup_func);
let table = FUNC_TABLE.read() as usize;
let result = lookup_func(table as *const u16, tag);
if result == 0 {
return None;
}
Some(core::mem::transmute_copy(&result))
}
}

Expand All @@ -38,15 +37,15 @@ struct ROMFuncs {
}

impl ROMFuncs {
fn load() -> Self {
ROMFuncs {
connect_internal_flash: find_func(*b"IF"),
flash_exit_xip: find_func(*b"EX"),
flash_range_erase: find_func(*b"RE"),
flash_range_program: find_func(*b"RP"),
flash_flush_cache: find_func(*b"FC"),
flash_enter_cmd_xip: find_func(*b"CX"),
}
fn load() -> Option<Self> {
Some(ROMFuncs {
connect_internal_flash: find_func(*b"IF")?,
flash_exit_xip: find_func(*b"EX")?,
flash_range_erase: find_func(*b"RE")?,
flash_range_program: find_func(*b"RP")?,
flash_flush_cache: find_func(*b"FC")?,
flash_enter_cmd_xip: find_func(*b"CX")?,
})
}
}

Expand All @@ -58,14 +57,14 @@ algo!(RP2040Algo);

const BLOCK_SIZE: u32 = 65536;
const SECTOR_SIZE: u32 = 4096;
const PAGE_SIZE: u32 = 256;
const BLOCK_ERASE_CMD: u8 = 0xd8;
const FLASH_BASE: u32 = 0x1000_0000;

impl FlashAlgo for RP2040Algo {
fn new(_address: u32, _clock: u32, _function: u32) -> Result<Self, ErrorCode> {
let funcs = ROMFuncs::load();

let Some(funcs) = ROMFuncs::load() else {
return Err(ErrorCode::new(1).unwrap());
};
(funcs.connect_internal_flash)();
(funcs.flash_exit_xip)();
Ok(Self { funcs })
Expand Down

0 comments on commit 0c2ac40

Please sign in to comment.