-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #170 from rust-embedded/semihosting
add `riscv-semihosting`
- Loading branch information
Showing
14 changed files
with
899 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
on: | ||
push: | ||
branches: [ master ] | ||
pull_request: | ||
merge_group: | ||
|
||
name: Build check (riscv-semihosting) | ||
|
||
jobs: | ||
# We check that the crate builds and links for all the toolchains and targets. | ||
build-riscv: | ||
strategy: | ||
matrix: | ||
# All generated code should be running on stable now, MRSV is 1.60.0 | ||
toolchain: [ stable, nightly, 1.60.0 ] | ||
target: | ||
- riscv32i-unknown-none-elf | ||
- riscv32imc-unknown-none-elf | ||
- riscv32imac-unknown-none-elf | ||
- riscv64imac-unknown-none-elf | ||
- riscv64gc-unknown-none-elf | ||
include: | ||
# Nightly is only for reference and allowed to fail | ||
- toolchain: nightly | ||
experimental: true | ||
runs-on: ubuntu-latest | ||
continue-on-error: ${{ matrix.experimental || false }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: dtolnay/rust-toolchain@master | ||
with: | ||
toolchain: ${{ matrix.toolchain }} | ||
targets: ${{ matrix.target }} | ||
- name: Build (M-mode) | ||
run: cargo build --package riscv-semihosting --target ${{ matrix.target }} | ||
- name: Build (U-mode) | ||
run: cargo build --package riscv-semihosting --target ${{ matrix.target }} --features=u-mode | ||
- name: Build (no semihosting) | ||
run: cargo build --package riscv-semihosting --target ${{ matrix.target }} --features=no-semihosting | ||
|
||
# On MacOS, Ubuntu, and Windows, we at least make sure that the crate builds and links. | ||
build-others: | ||
strategy: | ||
matrix: | ||
os: [ macos-latest, ubuntu-latest, windows-latest ] | ||
runs-on: ${{ matrix.os }} | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: dtolnay/rust-toolchain@stable | ||
- name: Build (no features) | ||
run: cargo build --package riscv-semihosting | ||
- name: Build (all features) | ||
run: cargo build --package riscv-semihosting --all-features | ||
|
||
# Job to check that all the builds succeeded | ||
build-check: | ||
needs: | ||
- build-riscv | ||
- build-others | ||
runs-on: ubuntu-latest | ||
if: always() | ||
steps: | ||
- run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,5 @@ members = [ | |
"riscv", | ||
"riscv-pac", | ||
"riscv-rt", | ||
"riscv-semihosting", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Change Log | ||
|
||
All notable changes to this project will be documented in this file. | ||
This project adheres to [Semantic Versioning](http://semver.org/). | ||
|
||
## [Unreleased] | ||
|
||
- Moved to the `riscv` Cargo workspace | ||
- Bring in API changes from | ||
[cortex-m-semihosting](https://github.com/rust-embedded/cortex-m/tree/master/cortex-m-semihosting), | ||
including: | ||
- Addition of the `hprint`, `hprintln`, `heprint`, `heprintln`, and `dbg` | ||
macros. | ||
- `hprint` and `heprintln` print to host stdout without and with a | ||
newline, respectively. | ||
- `heprint` and `heprintln` do the same, except to host stderr. | ||
- `dbg` works exactly like | ||
[`std::dbg`](https://doc.rust-lang.org/std/macro.dbg.html). | ||
- `HStdout` and `HStderr` have been combined into `HostStream`. | ||
- `inline-asm` feature removed, switched to stabilized inline asm and MSRV | ||
bumped to 1.59.0 | ||
- Clean up documentation, removing unnecessary references to | ||
cortex-m-semihosting and improving clarity. | ||
- Added GitHub Actions CI | ||
- Add features to select the privilege level the semihosting operations will be | ||
started from | ||
|
||
## [v0.0.1] - 2018-02-27 | ||
|
||
- Initial release | ||
|
||
[Unreleased]: https://github.com/riscv-rust/riscv-semihosting/compare/cb1afe4002d576b87bfd4c199f42a43815984ce4..HEAD | ||
[v0.0.1]: https://github.com/riscv-rust/riscv-semihosting/tree/cb1afe4002d576b87bfd4c199f42a43815984ce4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[package] | ||
authors = [ | ||
"The Cortex-M Team <cortex-m@teams.rust-embedded.org>", | ||
"Jorge Aparicio <japaricious@gmail.com>", | ||
"The RISC-V Team <risc-v@teams.rust-embedded.org>", | ||
] | ||
description = "Semihosting for RISCV processors" | ||
documentation = "https://docs.rs/riscv-semihosting" | ||
keywords = ["semihosting", "riscv"] | ||
categories = ["no-std", "embedded"] | ||
license = "MIT OR Apache-2.0" | ||
name = "riscv-semihosting" | ||
readme = "README.md" | ||
repository = "https://github.com/riscv-rust/riscv" | ||
version = "0.0.1" | ||
edition = "2021" | ||
rust-version = "1.60.0" | ||
|
||
[features] | ||
u-mode = [] | ||
jlink-quirks = [] | ||
no-semihosting = [] | ||
default = ["jlink-quirks"] | ||
|
||
[dependencies] | ||
critical-section = "1.0.0" | ||
riscv = {path = "../riscv", version = "0.10.1"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
[![crates.io](https://img.shields.io/crates/d/riscv-semihosting.svg)](https://crates.io/crates/riscv-semihosting) | ||
[![crates.io](https://img.shields.io/crates/v/riscv-semihosting.svg)](https://crates.io/crates/riscv-semihosting) | ||
|
||
# `riscv-semihosting` | ||
|
||
> Semihosting for RISC-V processors | ||
This is a fork of the | ||
[cortex-m-semihosting](https://docs.rs/cortex-m-semihosting) crate with changes | ||
to support the RISC-V Semihosting Specification as documented | ||
[here](https://github.com/riscv/riscv-semihosting-spec/blob/main/riscv-semihosting-spec.adoc) | ||
|
||
This crate can (almost) be used in exactly the same way as cortex-m-semihosting, | ||
simply by changing calls to `cortex_m_semihosting::*` to `riscv_semihosting::*`. | ||
Given this, the | ||
[`cortex-m-semihosting documentation`](https://docs.rs/cortex-m-semihosting) is | ||
generally sufficient for using this library. | ||
|
||
A major difference between this library and `cortex-m-semihosting` is that there | ||
are mandatory features to choose the privilege level at which the semihosting | ||
calls are executed. The *machine-mode (M-mode)* feature will cause the macros in `export` | ||
to execute the semihosting operation in an interrupt-free context, while | ||
*user-mode (U-mode)* causes them to just execute the operation. | ||
By default, M-mode is used. You can activate the U-mode via the `u-mode` feature. | ||
|
||
|
||
# Minimum Supported Rust Version (MSRV) | ||
|
||
This crate is guaranteed to compile on stable Rust 1.60.0 and up. It **won't** | ||
compile with older versions. | ||
|
||
## License | ||
|
||
Copyright 2018-2023 [RISC-V team][team] | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any purpose | ||
with or without fee is hereby granted, provided that the above copyright notice | ||
and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF | ||
THIS SOFTWARE. | ||
|
||
### Contribution | ||
|
||
Unless you explicitly state otherwise, any contribution intentionally submitted | ||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be | ||
dual licensed as above, without any additional terms or conditions. | ||
|
||
## Code of Conduct | ||
|
||
Contribution to this crate is organized under the terms of the [Rust Code of | ||
Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises | ||
to intervene to uphold that code of conduct. | ||
|
||
[CoC]: ../CODE_OF_CONDUCT.md | ||
[team]: https://github.com/rust-embedded/wg#the-risc-v-team |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use std::env; | ||
|
||
fn main() { | ||
let target = env::var("TARGET").unwrap(); | ||
|
||
if target.starts_with("riscv") { | ||
println!("cargo:rustc-cfg=riscv"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//! Interacting with debugging agent | ||
//! | ||
//! # Example | ||
//! | ||
//! This example will show how to terminate the QEMU session. The program | ||
//! should be running under QEMU with semihosting enabled | ||
//! (use `-semihosting` flag). | ||
//! | ||
//! Target program: | ||
//! | ||
//! ```no_run | ||
//! use riscv_semihosting::debug::{self, EXIT_SUCCESS, EXIT_FAILURE}; | ||
//! | ||
//! if 2 == 2 { | ||
//! // report success | ||
//! debug::exit(EXIT_SUCCESS); | ||
//! } else { | ||
//! // report failure | ||
//! debug::exit(EXIT_FAILURE); | ||
//! } | ||
//!``` | ||
/// This values are taken from section 5.5.2 of | ||
/// ADS Debug Target Guide (DUI0058). | ||
// TODO document | ||
#[allow(missing_docs)] | ||
pub enum Exception { | ||
// Hardware reason codes | ||
BranchThroughZero = 0x20000, | ||
UndefinedInstr = 0x20001, | ||
SoftwareInterrupt = 0x20002, | ||
PrefetchAbort = 0x20003, | ||
DataAbort = 0x20004, | ||
AddressException = 0x20005, | ||
IRQ = 0x20006, | ||
FIQ = 0x20007, | ||
// Software reason codes | ||
BreakPoint = 0x20020, | ||
WatchPoint = 0x20021, | ||
StepComplete = 0x20022, | ||
RunTimeErrorUnknown = 0x20023, | ||
InternalError = 0x20024, | ||
UserInterruption = 0x20025, | ||
ApplicationExit = 0x20026, | ||
StackOverflow = 0x20027, | ||
DivisionByZero = 0x20028, | ||
OSSpecific = 0x20029, | ||
} | ||
|
||
/// Status enum for `exit` syscall. | ||
pub type ExitStatus = Result<(), ()>; | ||
|
||
/// Successful execution of a program. | ||
pub const EXIT_SUCCESS: ExitStatus = Ok(()); | ||
|
||
/// Unsuccessful execution of a program. | ||
pub const EXIT_FAILURE: ExitStatus = Err(()); | ||
|
||
/// Reports to the debugger that the execution has completed. | ||
/// | ||
/// This call can be used to terminate QEMU session and report back success | ||
/// or failure. If you need to pass more than one type of error, consider | ||
/// using `report_exception` syscall instead. | ||
/// | ||
/// This call should not return. However, it is possible for the debugger | ||
/// to request that the application continue. In that case this call | ||
/// returns normally. | ||
/// | ||
pub fn exit(status: ExitStatus) { | ||
match status { | ||
EXIT_SUCCESS => report_exception(Exception::ApplicationExit), | ||
EXIT_FAILURE => report_exception(Exception::RunTimeErrorUnknown), | ||
} | ||
} | ||
|
||
/// Report an exception to the debugger directly. | ||
/// | ||
/// Exception handlers can use this SWI at the end of handler chains | ||
/// as the default action, to indicate that the exception has not been handled. | ||
/// | ||
/// This call should not return. However, it is possible for the debugger | ||
/// to request that the application continue. In that case this call | ||
/// returns normally. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `reason` - A reason code reported back to the debugger. | ||
/// | ||
pub fn report_exception(reason: Exception) { | ||
let code = reason as usize; | ||
unsafe { | ||
syscall1!(REPORT_EXCEPTION, code); | ||
} | ||
} |
Oops, something went wrong.