Skip to content

Commit 2d75b15

Browse files
committed
feat(riscv-rt): dedicated trap regions
Placed behind the `region-trap` feature flag.
1 parent 1e1ce67 commit 2d75b15

File tree

7 files changed

+44
-28
lines changed

7 files changed

+44
-28
lines changed

.github/workflows/tests.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ jobs:
5555
run: RUSTFLAGS="-C link-arg=-Tmemory.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features device
5656
- name: Build (include memory.x)
5757
run: RUSTFLAGS="-C link-arg=-Tdevice.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features memory
58+
- name: Build (include memory.x, use trap region)
59+
run: RUSTFLAGS="-C link-arg=-Tdevice.x -C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features memory,trap-region
5860
- name: Build (include device.x and memory.x)
5961
run: RUSTFLAGS="-C link-arg=-Tlink.x" cargo build --package tests-build --target ${{ matrix.target }} --example ${{ matrix.example }} --features device,memory
6062

riscv-rt/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ no-interrupts = []
4242
no-exceptions = []
4343
device = []
4444
memory = []
45+
trap-region = []

riscv-rt/link.x.in

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ PROVIDE(_max_hart_id = 0);
127127
PROVIDE(_hart_stack_size = SIZEOF(.stack) / (_max_hart_id + 1));
128128
PROVIDE(_heap_size = 0);
129129

130+
{% set trap_regions %}
131+
. = ALIGN(4);
132+
KEEP(*(.trap.vector)); /* for _trap_vector (vectored mode only) */
133+
KEEP(*(.trap.start)); /* for _start_trap routine */
134+
KEEP(*(.trap.start.*)); /* for _start_INTERRUPT_trap routines (vectored mode only) */
135+
KEEP(*(.trap.continue)); /* for _continue_trap routine (vectored mode only) */
136+
KEEP(*(.trap.rust)); /* for _start_trap_rust Rust function */
137+
KEEP(*(.trap .trap.*)); /* Other .trap symbols at the end */
138+
{% endset %}
139+
130140
SECTIONS
131141
{
132142
.text.dummy (NOLOAD) :
@@ -143,14 +153,9 @@ SECTIONS
143153
/* point of the program. */
144154
KEEP(*(.init));
145155

146-
. = ALIGN(4);
147-
KEEP(*(.trap.vector)); /* for _trap_vector (vectored mode only) */
148-
KEEP(*(.trap.start)); /* for _start_trap routine */
149-
KEEP(*(.trap.start.*)); /* for _start_INTERRUPT_trap routines (vectored mode only) */
150-
KEEP(*(.trap.continue)); /* for _continue_trap routine (vectored mode only) */
151-
KEEP(*(.trap.rust)); /* for _start_trap_rust Rust function */
152-
KEEP(*(.trap .trap.*)); /* Other .trap symbols at the end */
153-
156+
{% if not contains(cfg.feature, "trap-region") %}
157+
{{ trap_regions }}
158+
{% endif %}
154159
*(.text.abort);
155160
*(.text .text.*);
156161

@@ -173,6 +178,13 @@ SECTIONS
173178
__erodata = .;
174179
} > REGION_RODATA
175180

181+
{% if contains(cfg.feature, "trap-region") %}
182+
.trap : ALIGN(4)
183+
{
184+
{{ trap_regions }}
185+
} > REGION_TRAP
186+
{% endif %}
187+
176188
.data : ALIGN({{ cfg.arch_width }})
177189
{
178190
. = ALIGN({{ cfg.arch_width }});

riscv-rt/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,17 @@
532532
//! because when booting from elf, U-boot passes `argc` and `argv`. This feature also implies `single-hart`.
533533
//! The only way to get boot-hart is through fdt, so other harts initialization is up to you.
534534
//!
535+
//! ## `trap-region`
536+
//!
537+
//! Adds a dedicated trap memory region, `REGION_TRAP`, for placing `.trap` sections into. Enabling
538+
//! this feature and adding `REGION_ALIAS("REGION_TRAP", RAM);` to `memory.x` would for example place
539+
//! it in `RAM`.
540+
//!
541+
//! `REGION_TEXT` is usually placed in flash memory with a cache in front. Having a separate trap
542+
//! memory region makes it possible to always store interrupt and exceptions handlers in RAM,
543+
//! effectively bypassing cache contention and variable trap latency at the cost of increased RAM
544+
//! usage.
545+
//!
535546
//! [attr-entry]: attr.entry.html
536547
//! [attr-exception]: attr.exception.html
537548
//! [attr-external-interrupt]: attr.external_interrupt.html

tests-build/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ panic-halt = "1.0"
88
riscv = { path = "../riscv" }
99
riscv-rt = { path = "../riscv-rt" }
1010

11+
[build-dependencies]
12+
minilink = "0.2"
13+
1114
[features]
1215
pre-init = ["riscv-rt/pre-init"]
1316
single-hart = ["riscv-rt/single-hart"]
@@ -16,3 +19,4 @@ device = ["riscv-rt/device"]
1619
memory = ["riscv-rt/memory"]
1720
no-exceptions = ["riscv-rt/no-exceptions"]
1821
no-interrupts = ["riscv-rt/no-interrupts"]
22+
trap-region = ["riscv-rt/trap-region"]

tests-build/build.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,4 @@
1-
use std::{env, fs::File, io::Write, path::PathBuf};
2-
31
fn main() {
4-
// Put device.x somewhere the linker can find it
5-
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
6-
File::create(out.join("device.x"))
7-
.unwrap()
8-
.write_all(include_bytes!("device.x"))
9-
.unwrap();
10-
println!("cargo:rustc-link-search={}", out.display());
11-
println!("cargo:rerun-if-changed=device.x");
12-
13-
// Put memory.x somewhere the linker can find it
14-
File::create(out.join("memory.x"))
15-
.unwrap()
16-
.write_all(include_bytes!("memory.x"))
17-
.unwrap();
18-
println!("cargo:rustc-link-search={}", out.display());
19-
println!("cargo:rerun-if-changed=memory.x");
20-
21-
println!("cargo:rerun-if-changed=build.rs");
2+
minilink::register_template("device.x", "device.x");
3+
minilink::register_template("memory.x", "memory.x");
224
}

tests-build/memory.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@ REGION_ALIAS("REGION_DATA", RAM);
1010
REGION_ALIAS("REGION_BSS", RAM);
1111
REGION_ALIAS("REGION_HEAP", RAM);
1212
REGION_ALIAS("REGION_STACK", RAM);
13+
14+
{% if contains(cfg.feature, "trap-region") %}
15+
REGION_ALIAS("REGION_TRAP", RAM);
16+
{% endif %}

0 commit comments

Comments
 (0)