Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ stm32h7 = { version = "0.14", default-features = false }
stm32g0 = { version = "0.15.1", default-features = false }
strsim = { version = "0.10.0", default-features = false }
syn = { version = "2", default-features = false, features = ["derive", "parsing", "proc-macro", "extra-traits", "full", "printing"] }
rp235x-pac = { version = "0.1.0", default-features = false }
toml = { version = "0.7", default-features = false, features = ["parse", "display"] }
toml_edit = { version = "0.19", default-features = false }
vcell = { version = "0.1.2", default-features = false }
Expand Down
26 changes: 26 additions & 0 deletions app/demo-pi-pico-2/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
edition = "2021"
readme = "README.md"
name = "demo-pi-pico-2"
version = "0.1.0"

[dependencies]
cortex-m = { workspace = true }
cortex-m-rt = { workspace = true }
cfg-if = { workspace = true }
rp235x-pac = { workspace = true, features = ["rt"] }

kern = { path = "../../sys/kern", default-features = false }

[build-dependencies]
build-util = {path = "../../build/util"}

# this lets you use `cargo fix`!
[[bin]]
name = "demo-pi-pico-2"
test = false
doctest = false
bench = false

[lints]
workspace = true
3 changes: 3 additions & 0 deletions app/demo-pi-pico-2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Raspberry Pi Pico 2 demo application

This is a minimal application to demonstrate support for the Raspberry Pi Pico 2.
26 changes: 26 additions & 0 deletions app/demo-pi-pico-2/app.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name = "demo-pi-pico-2"
target = "thumbv8m.main-none-eabihf"
chip = "../../chips/rp235x"
board = "pi-pico-2"
memory = "memory-pico-2.toml"
stacksize = 944

[kernel]
name = "demo-pi-pico-2"
requires = {flash = 20000, ram = 1136}
stacksize = 640

[tasks.jefe]
name = "task-jefe"
priority = 0
max-sizes = {flash = 4096, ram = 512}
start = true
stacksize = 352
notifications = ["fault", "timer"]

[tasks.idle]
name = "task-idle"
priority = 5
max-sizes = {flash = 128, ram = 256}
stacksize = 256
start = true
7 changes: 7 additions & 0 deletions app/demo-pi-pico-2/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

fn main() {
build_util::expose_target_board();
}
48 changes: 48 additions & 0 deletions app/demo-pi-pico-2/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#![no_std]
#![no_main]

// We have to do this if we don't otherwise use it to ensure its vector table
// gets linked in.
use rp235x_pac as _;

use cortex_m_rt::entry;

/// Image definition to set up the chip for booting
///
/// See datasheet 5.1.4 Image Definitions for more. These specific values come from
/// section 5.9.5. Minimum viable image metadata.
#[link_section = ".image_def"]
#[used]
pub static RP235X_IMAGE_DEF_ARM_MIN: [u32; 5] = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: This seems like it should rather be a repr(C) struct with named fields instead of an array with commented indexes.

nitpick: I'd personally go with usize types since these seem to be addresses, though the Hubris codebase does use u32 for addresses very often. It makes sense in the APIs but (IMO) less so inside the services / tasks.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, this should eventually be a repr(C) struct since it encodes fields with values and flags (in 5.9.3.1). For now I've gone with the raw bytes described in the datasheet (5.9.5.1) since it's an MVP and I'm not even sure Oxide wants this in their repo 😆 If I get any sort of encouragement from them, I expect I'll expand on this and other aspects of the PR.

As for u32 vs usize, in the ultimate structure, it'd be a mix of types, with u8/u16/u32 for values and usize for the address, as noted. For now, it's just u32 bytes straight out of the datasheet.

0xFFFF_DED3, // START
0x1021_0142, // PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE, (EXE | S-mode | ARM | RP2350)
0x0000_01FF, // PICOBIN_BLOCK_ITEM_2BS_LAST, (size=1 word)
0x0000_0000, // next = self
0xAB12_3579, // END
];

#[entry]
fn main() -> ! {
let p = unsafe { rp235x_pac::Peripherals::steal() };

p.RESETS.reset().modify(|_, w| w.io_bank0().clear_bit());
while !p.RESETS.reset_done().read().io_bank0().bit() {}

// TODO fix/update this for RP2350
let cycles_per_ms = if p.CLOCKS.clk_sys_ctrl().read().src().is_clk_ref() {
// This is the reset state, so we'll assume we launched directly from
// flash running on the ROSC.
6_000 // ish
} else {
// This is _not_ the reset state, so we'll assume that the pico-debug
// resident debugger has reconfigured things to run off the 48 MHz USB
// clock.
48_000
};

unsafe { kern::startup::start_kernel(cycles_per_ms) }
}
2 changes: 2 additions & 0 deletions boards/pi-pico-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[probe-rs]
chip-name = "rp235x"
37 changes: 36 additions & 1 deletion build/kernel-link.x
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,28 @@ SECTIONS
. = . + _HUBRIS_IMAGE_HEADER_SIZE;
} > FLASH

/* Optional RP235x IMAGE_DEF block loop (tiny: typically 20 bytes)
We put it AFTER the header to preserve the bootloader invariant.
If no object defines .image_def, this section has size 0. */
.image_def :
{
__image_def_start = .;
. = ALIGN(4);
KEEP(*(.image_def));
__image_def_end = .;
} > FLASH

/* Explicitly place text at vector table + size of header, deliberately ignoring
section alignment. This is important because the bootloader assumes that the header
immediately follows the vector table; if something changes to cause that to not
be true, this expression will cause the text and header sections to overlap, causing
a difficult to understand linker failure, which will hopefully be somewhat improved
by this comment.
*/
PROVIDE(_stext = ADDR(.vector_table) + SIZEOF(.vector_table) + SIZEOF(.header));
PROVIDE(_stext = ADDR(.vector_table)
+ SIZEOF(.vector_table)
+ SIZEOF(.header)
+ SIZEOF(.image_def));

/* ### .text */
.text _stext :
Expand Down Expand Up @@ -279,5 +293,26 @@ ASSERT(ADDR(.vector_table) % (1 << LOG2CEIL(SIZEOF(.vector_table))) == 0, "
Vector table alignment too small for number of exception entires. Increase
the alignment to the next power of two");

/* --- optional safety checks for RP235x builds --- */

/* IMAGE_DEF must sit within first 4 KiB of the image */
ASSERT(SIZEOF(.image_def) == 0
|| (__image_def_end - ADDR(.vector_table)) <= 0x1000,
"RP235x: IMAGE_DEF must be within the first 4 KiB of the image");

/* Guard against the header growing large enough to push IMAGE_DEF out of the first 4k */
ASSERT(SIZEOF(.image_def) == 0
|| (SIZEOF(.vector_table) + SIZEOF(.header) + SIZEOF(.image_def)) <= 0x1000,
"Vector+header+IMAGE_DEF must fit in first 4 KiB");

/* Ensure it remains the expected n-byte form (adjust if items are added) */
ASSERT(SIZEOF(.image_def) == 0
|| SIZEOF(.image_def) == 20,
"Unexpected IMAGE_DEF size; edit kernel-link.x if this change was expected");

/* Sanity: keep IMAGE_DEF before .text */
ASSERT(SIZEOF(.image_def) == 0
|| ADDR(.image_def) < ADDR(.text),
"IMAGE_DEF must precede .text");

/* Do not exceed this mark in the error messages above | */
8 changes: 7 additions & 1 deletion build/xtask/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,13 @@ impl Config {
let mut peripherals: IndexMap<String, Peripheral> = {
let chip_file =
cfg.parent().unwrap().join(&toml.chip).join("chip.toml");
let chip_contents = std::fs::read(chip_file)?;
let chip_contents =
std::fs::read(&chip_file).with_context(|| {
format!(
"could not find chip.toml at {}",
chip_file.display()
)
})?;
hasher.write(&chip_contents);
toml::from_str(std::str::from_utf8(&chip_contents)?)?
};
Expand Down
13 changes: 11 additions & 2 deletions build/xtask/src/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,13 @@ fn build_archive(
archive.copy(openocd_cfg, debug_dir.join("openocd.cfg"))?;
}
archive
.copy(chip_dir.join("openocd.gdb"), debug_dir.join("openocd.gdb"))?;
.copy(chip_dir.join("openocd.gdb"), debug_dir.join("openocd.gdb"))
.with_context(|| {
format!(
"could not locate openocd.gdb at {}",
chip_dir.join("openocd.gdb").display()
)
})?;

let mut metadata = None;

Expand Down Expand Up @@ -2009,13 +2015,16 @@ fn build(
format!(
"-C link-arg=-z -C link-arg=common-page-size=0x20 \
-C link-arg=-z -C link-arg=max-page-size=0x20 \
-C link-arg=-Map={}/firmware.map \
-C llvm-args=--enable-machine-outliner=never \
-Z emit-stack-sizes \
-C overflow-checks=y \
-C metadata={} \
{}
",
cfg.link_script_hash, remap_path_prefix,
cfg.dist_dir.display(),
cfg.link_script_hash,
remap_path_prefix,
),
);
cmd.arg("--");
Expand Down
12 changes: 12 additions & 0 deletions chips/rp235x/chip.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[resets]
address = 0x4002_0000 # 2.2.4. APB registers
size = 32

[sio]
address = 0xd000_0000 # 2.2.6. Core-local peripherals (SIO)
size = 512

[spi0]
address = 0x4008_0000 # 12.3.5 List of registers
size = 0x1000
interrupts = { irq = 31 } # SPI0_IRQ from 3.2 Interrupts
15 changes: 15 additions & 0 deletions chips/rp235x/memory-pico-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[[flash]]
address = 0x1000_0000 # 2.2. Address map "XIP 0x10000000"
# NOTE: RP235x flash is external, so the value here is a property of the Pico 2, not the RP2350
# itself. Update to suit your actual hardware.
size = 0x40_0000 # Pico 2 datasheet: "RP2350 microcontroller with 4 MB of flash memory"
read = true
execute = true

[[ram]]
address = 0x2000_0000 # 4.2. SRAM "SRAM is mapped to system addresses starting at 0x20000000."
size = 0x8_2000 # 4.2. SRAM "There is a total of 520 kB (520 × 1024 bytes) of on-chip SRAM."
read = true
write = true
execute = false # 4.2. SRAM "you can use any bank to store processor code, data buffers, or a
# mixture of the two."
6 changes: 6 additions & 0 deletions chips/rp235x/openocd.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
gdb_port 3340
telnet_port 4450

# OpenOCD configuration for the RP235x
source [find interface/cmsis-dap.cfg]
source [find target/rp2350.cfg]
12 changes: 12 additions & 0 deletions chips/rp235x/openocd.gdb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
target extended-remote :3333

# print demangled symbols
set print asm-demangle on

# set backtrace limit to not have infinite backtrace loops
set backtrace limit 32

# detect hard faults
break HardFault

monitor arm semihosting enable
18 changes: 9 additions & 9 deletions doc/guide/caboose.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ mapped as an MPU region. Only tasks declared in `caboose.tasks` are allowed to
read data from the caboose region of flash. If other tasks attempt to read from
this memory region, they will experience the typical memory fault.

The Hubris build system will populate the caboose with start and end words
(32-bit words) words, and a sequence of
The Hubris build system will populate the caboose with 32-bit start and end
words, and a sequence of
https://github.com/oxidecomputer/tlvc[TLV-C] key-value pairs containing image
metadata:

Expand All @@ -48,12 +48,12 @@ metadata:
| Type
| Description

| **Start**
| `u32`
| **Start**
| `u32`
| `abi::CABOOSE_MAGIC`

| `GITC` tag
| TLV-C
| `GITC` tag
| TLV-C
| The current Git commit hash with an optional trailing "-dirty" if the
repository contains uncommitted changes.

Expand All @@ -74,7 +74,7 @@ if it was set.
| `u8`
| _(filled with `0xFF`)_

| **End**
| **End**
| `u32`
| Caboose size (little-endian `u32`)
|===
Expand Down Expand Up @@ -111,8 +111,8 @@ let caboose: Option<&'static [u8]> = drv_caboose_pos::CABOOSE_POS.as_slice();
can't know the caboose position until all tasks have been built)

Besides the start and end words and the default metadata described above, the
Hubris build system is agnostic to any further contents of the caboose. A
Hubris build system is agnostic to any further contents of the caboose. A
separate release engineering process may decide to store any arbitrary data in
the remaining space. The
the remaining space. The
https://github.com/oxidecomputer/hubtools[`hubtools` repository] includes a
library and CLI for modifying the caboose of a Hubris archive.
3 changes: 3 additions & 0 deletions drv/user-leds/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,9 @@ fn led_toggle(led: Led) {
gpio_driver.toggle(pin).unwrap_lite();
}

///////////////////////////////////////////////////////////////////////////////
// End board-specific bits

mod idl {
use super::LedError;

Expand Down
Loading