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 16, 2024
1 parent 6302b8d commit e090006
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 0 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 @@ -163,6 +169,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 == '')
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
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 @@ -203,6 +203,7 @@ mod sys {
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
mod inner {
use super::{SystemTime, Timespec};
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
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
1 change: 1 addition & 0 deletions tests/no-std/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use core::str;
target_arch = "arm",
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "xtensa",
))]
use semihosting::sys::arm_compat::*;
#[cfg(any(
Expand Down

0 comments on commit e090006

Please sign in to comment.