Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv-rt: compatibility with RV32E and RV64E #243

Merged
merged 8 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
20 changes: 15 additions & 5 deletions .github/workflows/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ jobs:
- 'riscv-rt/**'
riscv-semihosting:
- 'riscv-semihosting/**'
riscv-target-parser:
- 'riscv-target-parser/**'
- name: Check for CHANGELOG.md (riscv)
if: steps.changes.outputs.riscv == 'true'
Expand All @@ -43,7 +45,15 @@ jobs:
changeLogPath: ./riscv-pac/CHANGELOG.md
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-pac/CHANGELOG.md file.'


- name: Check for CHANGELOG.md (riscv-peripheral)
if: steps.changes.outputs.riscv-peripheral == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: ./riscv-peripheral/CHANGELOG.md
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-peripheral/CHANGELOG.md file.'

- name: Check for CHANGELOG.md (riscv-rt)
if: steps.changes.outputs.riscv-rt == 'true'
uses: dangoslen/changelog-enforcer@v3
Expand All @@ -60,10 +70,10 @@ jobs:
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-semihosting/CHANGELOG.md file.'

- name: Check for CHANGELOG.md (riscv-peripheral)
if: steps.changes.outputs.riscv-peripheral == 'true'
- name: Check for CHANGELOG.md (riscv-target-parser)
if: steps.changes.outputs.riscv-target-parser == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: ./riscv-peripheral/CHANGELOG.md
changeLogPath: ./riscv-target-parser/CHANGELOG.md
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-peripheral/CHANGELOG.md file.'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-target-parser/CHANGELOG.md file.'
37 changes: 37 additions & 0 deletions .github/workflows/riscv-target-parser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
on:
push:
branches: [ master ]
pull_request:
merge_group:

name: Run tests (riscv-target-parser)

jobs:
run-tests:
strategy:
matrix:
os: [ macos-latest, ubuntu-latest, windows-latest ] # windows shows weird linking errors
toolchain: [ stable, nightly, 1.61.0 ]
include:
# Nightly is only for reference and allowed to fail
- rust: nightly
experimental: true
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental || false }}
steps:
- uses: actions/checkout@v4
- name: Update Rust toolchain
run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- name: Build
run: cargo build --package riscv-target-parser
- name: Run tests
run: cargo test --package riscv-target-parser

# Job to check that all the builds succeeded
tests-check:
needs:
- run-tests
runs-on: ubuntu-latest
if: always()
steps:
- run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ members = [
"riscv-peripheral",
"riscv-rt",
"riscv-semihosting",
"riscv-target-parser",
"tests",
]
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This repository contains various crates useful for writing Rust programs on RISC
* [`riscv-peripheral`]: Interfaces for standard RISC-V peripherals
* [`riscv-rt`]: Startup code and interrupt handling
* [`riscv-semihosting`]: Semihosting for RISC-V processors
* [`riscv-target-parser`]: Utility crate for parsing RISC-V targets in build scripts

This project is developed and maintained by the [RISC-V team][team].

Expand All @@ -27,5 +28,6 @@ to intervene to uphold that code of conduct.
[`riscv-peripheral`]: https://crates.io/crates/riscv-peripheral
[`riscv-rt`]: https://crates.io/crates/riscv-rt
[`riscv-semihosting`]: https://crates.io/crates/riscv-semihosting
[`riscv-target-parser`]: https://crates.io/crates/riscv-target-parser
[team]: https://github.com/rust-embedded/wg#the-risc-v-team
[CoC]: CODE_OF_CONDUCT.md
2 changes: 2 additions & 0 deletions riscv-rt/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Add documentation to trap frame fields.
- Avoid using `t3`+ in startup assembly to ensure compatibility with RVE32.
- `link.x.in`: remove references to `eh_frame`.
- Rename start/end section symbols to align with `cortex-m-rt`:
- `_stext`: it remains, as linker files can modify it.
Expand Down
5 changes: 4 additions & 1 deletion riscv-rt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ targets = [
"riscv64imac-unknown-none-elf", "riscv64gc-unknown-none-elf",
]

[build-dependencies]
riscv-target-parser = { path = "../riscv-target-parser", version = "0.1.0" }

[dependencies]
riscv = { path = "../riscv", version = "0.12.0" }
riscv-pac = { path = "../riscv-pac", version = "0.2.0" }
riscv-rt-macros = { path = "macros", version = "0.2.2" }
riscv-rt-macros = { path = "macros", version = "0.3.0" }

[dev-dependencies]
panic-halt = "1.0.0"
Expand Down
92 changes: 9 additions & 83 deletions riscv-rt/build.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// NOTE: Adapted from cortex-m/build.rs

use std::{collections::HashSet, env, fs, io, path::PathBuf};
use riscv_target_parser::RiscvTarget;
use std::{env, fs, io, path::PathBuf};

fn add_linker_script(arch_width: u32) -> io::Result<()> {
// Read the file to a string and replace all occurrences of ${ARCH_WIDTH} with the arch width
Expand All @@ -17,96 +18,21 @@ fn add_linker_script(arch_width: u32) -> io::Result<()> {
Ok(())
}

/// Parse the target RISC-V architecture and returns its bit width and the extension set
fn parse_target(target: &str, cargo_flags: &str) -> (u32, HashSet<char>) {
// isolate bit width and extensions from the rest of the target information
let arch = target
.trim_start_matches("riscv")
.split('-')
.next()
.unwrap();

let bits = arch
.chars()
.take_while(|c| c.is_ascii_digit())
.collect::<String>()
.parse::<u32>()
.unwrap();

let mut extensions: HashSet<char> = arch.chars().skip_while(|c| c.is_ascii_digit()).collect();
// expand the 'g' shorthand extension
if extensions.contains(&'g') {
extensions.insert('i');
extensions.insert('m');
extensions.insert('a');
extensions.insert('f');
extensions.insert('d');
}

let cargo_flags = cargo_flags
.split(0x1fu8 as char)
.filter(|arg| !arg.is_empty());

cargo_flags
.filter(|k| k.starts_with("target-feature="))
.flat_map(|str| {
let flags = str.split('=').collect::<Vec<&str>>()[1];
flags.split(',')
})
.for_each(|feature| {
let chars = feature.chars().collect::<Vec<char>>();
match chars[0] {
'+' => {
extensions.insert(chars[1]);
}
'-' => {
extensions.remove(&chars[1]);
}
_ => {
panic!("Unsupported target feature operation");
}
}
});

(bits, extensions)
}

fn main() {
println!("cargo:rustc-check-cfg=cfg(riscv)");
println!("cargo:rustc-check-cfg=cfg(riscv32)");
println!("cargo:rustc-check-cfg=cfg(riscv64)");
// Required until target_feature risc-v is stable and in-use (rust 1.75)
for ext in ['i', 'e', 'm', 'a', 'f', 'd', 'g', 'c'] {
println!("cargo:rustc-check-cfg=cfg(riscv{})", ext);
}

let target = env::var("TARGET").unwrap();
let cargo_flags = env::var("CARGO_ENCODED_RUSTFLAGS").unwrap();
let _name = env::var("CARGO_PKG_NAME").unwrap();

// set configuration flags depending on the target
if target.starts_with("riscv") {
println!("cargo:rustc-cfg=riscv");
// This is required until target_arch & target_feature risc-v work is
// stable and in-use (rust 1.75.0)
let (bits, extensions) = parse_target(&target, &cargo_flags);

// generate the linker script and expose the ISA width
let arch_width = match bits {
32 => {
println!("cargo:rustc-cfg=riscv32");
4
}
64 => {
println!("cargo:rustc-cfg=riscv64");
8
}
_ => panic!("Unsupported bit width"),
};
add_linker_script(arch_width).unwrap();

// expose the ISA extensions
for ext in &extensions {
println!("cargo:rustc-cfg=riscv{}", ext);
if let Ok(target) = RiscvTarget::build(&target, &cargo_flags) {
for flag in target.rustc_flags() {
// Required until target_feature risc-v is stable and in-use
println!("cargo:rustc-check-cfg=cfg({flag})");
println!("cargo:rustc-cfg={flag}");
}
add_linker_script(target.width().into()).unwrap();
}
}
2 changes: 1 addition & 1 deletion riscv-rt/macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ keywords = ["riscv", "runtime", "startup"]
license = "MIT OR Apache-2.0"
name = "riscv-rt-macros"
repository = "https://github.com/rust-embedded/riscv"
version = "0.2.2"
version = "0.3.0"
edition = "2021"

[lib]
Expand Down
Loading
Loading