Skip to content

Commit

Permalink
Support Xtensa (OpenOCD Semihosting)
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Mar 19, 2024
1 parent 5497209 commit 298473d
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/.cspell/project-dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ebreak
EINTR
EINVAL
errno
espup
fipe
FLEN
fopen
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ jobs:
- uses: taiki-e/checkout-action@v1
- name: Install Rust
run: rustup toolchain add ${{ matrix.rust }} --no-self-update --component rust-src && rustup default ${{ matrix.rust }}
- uses: taiki-e/install-action@v2
with:
tool: espup
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: startsWith(matrix.rust, 'nightly') && (startsWith(matrix.os, 'ubuntu') || matrix.os == '')
- run: |
set -eEuxo pipefail
sudo apt-get -o Acquire::Retries=10 -qq update && sudo apt-get -o Acquire::Retries=10 -o Dpkg::Use-Pty=0 install -y --no-install-recommends \
Expand Down Expand Up @@ -164,6 +170,12 @@ jobs:
echo "C:\Program Files\qemu" >>"${GITHUB_PATH}"
"C:\Program Files\qemu\qemu-system-arm" --version
if: startsWith(matrix.os, 'windows')
- run: espup install --targets esp32
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: startsWith(matrix.rust, 'nightly') && (startsWith(matrix.os, 'ubuntu') || matrix.os == '')
- run: tools/no-std.sh
- run: TEST_RUNNER=qemu-user tools/no-std.sh
if: startsWith(matrix.os, 'ubuntu') || matrix.os == ''
- run: cargo +esp build --target xtensa-esp32-none-elf -Z build-std=core,alloc --features $TEST_FEATURES
if: startsWith(matrix.rust, 'nightly') && (startsWith(matrix.os, 'ubuntu') || matrix.os == '')
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords = ["qemu"]
categories = ["embedded", "hardware-support", "no-std", "no-std::no-alloc"]
exclude = ["/.*", "/tools", "/target-specs"]
description = """
Semihosting for AArch64, ARM, RISC-V, MIPS32, and MIPS64.
Semihosting for AArch64, ARM, RISC-V, MIPS32, MIPS64, and Xtensa.
"""

[package.metadata.docs.rs]
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![github actions](https://img.shields.io/github/actions/workflow/status/taiki-e/semihosting/ci.yml?branch=main&style=flat-square&logo=github)](https://github.com/taiki-e/semihosting/actions)

<!-- tidy:crate-doc:start -->
Semihosting for AArch64, ARM, RISC-V, MIPS32, and MIPS64.
Semihosting for AArch64, ARM, RISC-V, MIPS32, MIPS64, and Xtensa.

This library provides access to semihosting, a mechanism for programs running on the real or virtual (e.g., QEMU) target to communicate with I/O facilities on the host system. See the [ARM documentation](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst) for more information on semihosting.

Expand Down Expand Up @@ -40,6 +40,7 @@ The following target architectures are supported:
| ----------- | ------------- | ------------------------- |
| arm/aarch64 | [Semihosting for AArch32 and AArch64](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst) | `sys::arm_compat` |
| riscv32/riscv64 | [RISC-V Semihosting](https://github.com/riscv-software-src/riscv-semihosting/blob/HEAD/riscv-semihosting-spec.adoc) | `sys::arm_compat` |
| xtensa | [OpenOCD Semihosting](https://github.com/espressif/openocd-esp32/blob/HEAD/src/target/espressif/esp_xtensa_semihosting.c) | `sys::arm_compat` |
| mips/mips32r6/mips64/mips64r6 | Unified Hosting Interface (MD01069) | `sys::mips` |

The host must be running an emulator or a debugger attached to the target.
Expand Down
1 change: 1 addition & 0 deletions src/experimental/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ mod sys {
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
mod imp {
use core::cell::Cell;
Expand Down
1 change: 1 addition & 0 deletions src/experimental/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ mod sys {
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
mod inner {
use super::{SystemTime, Timespec};
Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/*!
<!-- tidy:crate-doc:start -->
Semihosting for AArch64, ARM, RISC-V, MIPS32, and MIPS64.
Semihosting for AArch64, ARM, RISC-V, MIPS32, MIPS64, and Xtensa.
This library provides access to semihosting, a mechanism for programs running on the real or virtual (e.g., QEMU) target to communicate with I/O facilities on the host system. See the [ARM documentation](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst) for more information on semihosting.
Expand Down Expand Up @@ -35,6 +35,7 @@ The following target architectures are supported:
| ----------- | ------------- | ------------------------- |
| arm/aarch64 | [Semihosting for AArch32 and AArch64](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst) | `sys::arm_compat` |
| riscv32/riscv64 | [RISC-V Semihosting](https://github.com/riscv-software-src/riscv-semihosting/blob/HEAD/riscv-semihosting-spec.adoc) | `sys::arm_compat` |
| xtensa | [OpenOCD Semihosting](https://github.com/espressif/openocd-esp32/blob/HEAD/src/target/espressif/esp_xtensa_semihosting.c) | `sys::arm_compat` |
| mips/mips32r6/mips64/mips64r6 | Unified Hosting Interface (MD01069) | `sys::mips` |
The host must be running an emulator or a debugger attached to the target.
Expand Down Expand Up @@ -212,6 +213,7 @@ semihosting = { version = "0.1", features = ["stdio", "panic-handler"] }
target_arch = "mips32r6",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "xtensa",
),
feature(asm_experimental_arch)
)]
Expand All @@ -227,6 +229,7 @@ semihosting = { version = "0.1", features = ["stdio", "panic-handler"] }
target_arch = "mips32r6",
target_arch = "mips64",
target_arch = "mips64r6",
target_arch = "xtensa",
)))]
compile_error!("unsupported target");

Expand Down
1 change: 1 addition & 0 deletions src/sys/arm_compat/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//! - Semihosting for AArch32 and AArch64 <https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst>
//! - RISC-V Semihosting <https://github.com/riscv-software-src/riscv-semihosting/blob/HEAD/riscv-semihosting-spec.adoc>
//! - <https://github.com/qemu/qemu/blob/HEAD/semihosting/arm-compat-semi.c>
//! - <https://github.com/espressif/openocd-esp32/blob/HEAD/src/target/espressif/esp_xtensa_semihosting.c>
#![allow(clippy::missing_safety_doc)] // TODO

Expand Down
1 change: 1 addition & 0 deletions src/sys/arm_compat/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use arch::{syscall, syscall_readonly};
#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")]
#[cfg_attr(target_arch = "arm", path = "arm.rs")]
#[cfg_attr(any(target_arch = "riscv32", target_arch = "riscv64"), path = "riscv.rs")]
#[cfg_attr(target_arch = "xtensa", path = "xtensa.rs")]
mod arch;

pub use crate::sys::reg::{ParamRegR, ParamRegW, RetReg};
Expand Down
39 changes: 39 additions & 0 deletions src/sys/arm_compat/syscall/xtensa.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

use core::arch::asm;

use super::{OperationNumber, ParamRegR, ParamRegW, RetReg};

/// Raw semihosting call with a parameter that will be read + modified by the host
#[inline]
pub unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg {
unsafe {
let r;
asm!(
"break 1, 14",
inout("a2") number.0 as usize => r, // OPERATION NUMBER REGISTER => RETURN REGISTER
// Use inout because operation such as SYS_ELAPSED suggest that
// PARAMETER REGISTER may be changed.
inout("a3") parameter.0 => _, // PARAMETER REGISTER
options(nostack, preserves_flags),
);
RetReg(r)
}
}

/// Raw semihosting call with a parameter that will be read (but not modified) by the host
#[inline]
pub unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg {
unsafe {
let r;
asm!(
"break 1, 14",
inout("a2") number.0 as usize => r, // OPERATION NUMBER REGISTER => RETURN REGISTER
// Use inout because operation such as SYS_ELAPSED suggest that
// PARAMETER REGISTER may be changed.
inout("a3") parameter.0 => _, // PARAMETER REGISTER
options(nostack, preserves_flags, readonly),
);
RetReg(r)
}
}
3 changes: 3 additions & 0 deletions src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
use arm_compat as arch;
#[cfg(any(
target_arch = "aarch64",
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
#[cfg_attr(
semihosting_doc_cfg,
Expand All @@ -29,6 +31,7 @@ use arm_compat as arch;
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
)))
)]
pub mod arm_compat;
Expand Down
3 changes: 3 additions & 0 deletions src/sys/reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ impl<'a> ParamRegW<'a> {
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
impl<'a> ParamRegW<'a> {
#[inline]
Expand Down Expand Up @@ -100,6 +101,7 @@ impl<'a> ParamRegR<'a> {
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
impl<'a> ParamRegR<'a> {
#[inline]
Expand Down Expand Up @@ -157,6 +159,7 @@ impl RetReg {
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
impl RetReg {
#[allow(clippy::cast_possible_truncation)]
Expand Down

0 comments on commit 298473d

Please sign in to comment.