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

add riscv-semihosting #170

Merged
merged 51 commits into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
a8c058f
initial commit
Jan 22, 2017
18420a8
hax to make this crate compilable for x86
Jan 22, 2017
0524b95
add `write` functions to write to the host's stdout
Jan 23, 2017
82aa430
release v0.1.1
Jan 23, 2017
419094e
fix typo in hprintln!
Jascha-N Feb 15, 2017
81535b4
Merge pull request #1 from Jascha-N/fix-hprintln
Feb 15, 2017
adf0363
release v0.1.2
Feb 15, 2017
0d42a81
add a macro to write to the host stderr
Feb 27, 2017
3f17e4e
Merge pull request #2 from japaric/stderr
Feb 27, 2017
36ae9a2
release v0.1.3
Feb 27, 2017
ad2fb8f
ignore failing test
pftbest Mar 12, 2017
db5951b
fix syscall macros
pftbest Mar 12, 2017
02cb500
add `exit` and `report_exception` syscalls
pftbest Mar 13, 2017
22fb4a7
Fix issues found by code review, add more documentation.
pftbest Mar 19, 2017
6a585c1
Use enum for exit status.
pftbest Mar 20, 2017
9542a86
Merge pull request #3 from pftbest/exit
Mar 20, 2017
9562a58
watch tail -> tail -f
japaric May 15, 2017
6d79132
Merge pull request #10 from japaric/tail
japaric May 15, 2017
6deed40
WIP: proof of concept for stdout() and stderr() functions to open str…
schodet Jun 16, 2017
a295a73
drop write macro in favor of IO objects + fmt::Write
japaric Jul 3, 2017
16a2e26
Merge pull request #12 from japaric/gh5
japaric Jul 3, 2017
f7428a7
Drop references to removed hprint(ln)! macros
schodet Jul 4, 2017
3a1f763
Document nr::open, fix text/binary inversion
schodet Jul 4, 2017
aaa1c60
Document the strange usage of W_APPEND mode for stderr
schodet Jul 4, 2017
bab5fba
add CI
japaric Jul 4, 2017
bbe2d65
drop sh ci/after_success.sh
japaric Jul 4, 2017
4e7d9d4
don't test master
japaric Jul 4, 2017
94922ac
Auto merge of #13 - schodet:stdio, r=japaric
homunkulus Jul 4, 2017
71d0221
v0.2.0
japaric Jul 7, 2017
28a3d99
Fix semihosting's SYS_CLOSE nr.
kubo39 Aug 28, 2017
cb1afe4
Implement semihosting for RISCV.
dvc94ch Feb 27, 2018
4e8ad01
Merge upstream cortex-m-semihosting.
jperkin Jan 2, 2022
7c021ec
Fix assembly to ensure uncompressed instructions.
jperkin Jan 2, 2022
4fde939
Update README with a basic introduction.
jperkin Jan 2, 2022
bf2940f
Removed inline asm, bumped MSRV
FawazTirmizi Jul 18, 2022
e07d797
Merge pull request #2 from FawazTirmizi/cortex-feature-parity
Disasm Jul 19, 2022
d5b79a7
Merge commit '4fde9396f72c76f327893d498efd0082bf97a58c' into dev/fawa…
FawazTirmizi Jul 19, 2022
e80cec6
Cleaned up documentation
FawazTirmizi Jul 19, 2022
f4c4830
Remove cortex-m-semihosting CI
FawazTirmizi Jul 19, 2022
b7f5ee4
Updated Cargo.toml
FawazTirmizi Jul 19, 2022
6002ee5
Revert "Remove cortex-m-semihosting CI"
FawazTirmizi Jul 20, 2022
64ef9e4
Merge pull request #3 from FawazTirmizi/rivos/main
Disasm Jul 20, 2022
45ac4e8
Replaced old CI with one using GitHub Actions (#4)
FawazTirmizi Oct 21, 2022
6e35584
Added features to select privilege level (#5)
FawazTirmizi Nov 1, 2022
a1c88e5
move to riscv-semihosting
romancardenas Dec 28, 2023
b5a6c0b
Merge remote-tracking branch 'semihosting/master' into semihosting
romancardenas Dec 28, 2023
e70afe4
adjust the workspace
romancardenas Dec 28, 2023
297aa6e
m-mode as default
romancardenas Dec 29, 2023
eb29d96
modify readme
romancardenas Dec 29, 2023
eade038
update CI
romancardenas Dec 29, 2023
4dc63f6
minor changes
romancardenas Dec 31, 2023
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
22 changes: 16 additions & 6 deletions .github/workflows/changelog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ jobs:
filters: |
riscv:
- 'riscv/**'
riscv-rt:
- 'riscv-rt/**'
riscv-pac:
- 'riscv-pac/**'
riscv-rt:
- 'riscv-rt/**'
riscv-semihosting:
- 'riscv-semihosting/**'

- name: Check for CHANGELOG.md (riscv)
if: steps.changes.outputs.riscv == 'true'
Expand All @@ -32,6 +34,14 @@ jobs:
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv/CHANGELOG.md file.'

- name: Check for CHANGELOG.md (riscv-pac)
if: steps.changes.outputs.riscv-pac == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
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-rt)
if: steps.changes.outputs.riscv-rt == 'true'
uses: dangoslen/changelog-enforcer@v3
Expand All @@ -40,10 +50,10 @@ jobs:
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-rt/CHANGELOG.md file.'

- name: Check for CHANGELOG.md (riscv-pac)
if: steps.changes.outputs.riscv-pac == 'true'
- name: Check for CHANGELOG.md (riscv-semihosting)
if: steps.changes.outputs.riscv-semihosting == 'true'
uses: dangoslen/changelog-enforcer@v3
with:
changeLogPath: ./riscv-pac/CHANGELOG.md
changeLogPath: ./riscv-semihosting/CHANGELOG.md
skipLabels: 'skip changelog'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-pac/CHANGELOG.md file.'
missingUpdateErrorMessage: 'Please add a changelog entry in the riscv-semihosting/CHANGELOG.md file.'
63 changes: 63 additions & 0 deletions .github/workflows/riscv-semihosting.yaml
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) }}'
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ members = [
"riscv",
"riscv-pac",
"riscv-rt",
"riscv-semihosting",
]
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This repository contains various crates useful for writing Rust programs on RISC
* [`riscv`]: CPU registers access and intrinsics
* [`riscv-pac`]: Common traits to be implemented by RISC-V PACs
* [`riscv-rt`]: Startup code and interrupt handling

* [`riscv-semihosting`]: Semihosting for RISC-V processors

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

Expand All @@ -22,6 +22,8 @@ Conduct][CoC], the maintainer of this crate, the [RISC-V team][team], promises
to intervene to uphold that code of conduct.

[`riscv`]: https://crates.io/crates/riscv
[`riscv-pac`]: https://crates.io/crates/riscv-pac
[`riscv-rt`]: https://crates.io/crates/riscv-rt
[`riscv-semihosting`]: https://crates.io/crates/riscv-semihosting
[team]: https://github.com/rust-embedded/wg#the-risc-v-team
[CoC]: CODE_OF_CONDUCT.md
33 changes: 33 additions & 0 deletions riscv-semihosting/CHANGELOG.md
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
27 changes: 27 additions & 0 deletions riscv-semihosting/Cargo.toml
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"}
61 changes: 61 additions & 0 deletions riscv-semihosting/README.md
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
9 changes: 9 additions & 0 deletions riscv-semihosting/build.rs
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");
}
}
94 changes: 94 additions & 0 deletions riscv-semihosting/src/debug.rs
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);
}
}
Loading