Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
28 changes: 25 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ jobs:
include:
- TARGET: x86_64-unknown-linux-gnu
OS: ubuntu-latest
FEATURES: ''
- TARGET: aarch64-unknown-linux-gnu
OS: ubuntu-latest
FEATURES: '--no-default-features'
- TARGET: i686-unknown-linux-gnu
OS: ubuntu-latest
FEATURES: '--no-default-features --features alloc'

runs-on: ${{ matrix.OS }}
env:
Expand All @@ -30,7 +33,7 @@ jobs:
- uses: actions/checkout@v2
with:
submodules: 'recursive'

- name: Install Rust
uses: actions-rs/toolchain@v1
with:
Expand All @@ -39,9 +42,9 @@ jobs:
profile: minimal
target: ${{ matrix.target }}
components: llvm-tools-preview

- name: Build crates
run: cargo build --target $TARGET
run: cargo build --target $TARGET $FEATURES

test:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -84,3 +87,22 @@ jobs:

- name: Run clippy (tests)
run: cargo clippy --tests

test-no-alloc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
default: true
profile: minimal
components: llvm-tools-preview
target: x86_64-unknown-none

- name: Build no alloc test exe
working-directory: tools/no_alloc_check
run: cargo build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ tests/*.aml
tests/*.lst
tests/*.txt
dumps/
tools/no_alloc_check/target
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[workspace]
members = ["tools/aml_tester", "tools/acpi_dumper", "tools/aml_test_tools", "tools/uacpi_test_adapter"]
# See the note in the no_alloc_check README.md to see why this is excluded.
exclude = ["tools/no_alloc_check"]
resolver = "2"

[package]
Expand Down
2 changes: 2 additions & 0 deletions tools/no_alloc_check/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = ["x86_64-unknown-none"]
15 changes: 15 additions & 0 deletions tools/no_alloc_check/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "no_alloc_check"
version = "0.0.0"
edition = "2024"
publish = false

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"

[dependencies]
acpi = { path = "../..", default-features = false }
pci_types = "0.10.1"
23 changes: 23 additions & 0 deletions tools/no_alloc_check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# no_alloc_check test tool

This executable is used to check that the crate is usable in a no-alloc environment. It was born
out of a comment on [issue 311](https://github.com/rust-osdev/acpi/issues/311) that it didn't work.

The main `acpi` crate is compiled with no alloc support in one of the workflow builds. This
executable is also built in the workflow as a sanity check that the crate can be *linked to* in a
no-alloc environment.

This executable should build, but actually attempting to run it will result in an access
violation. To demonstrate that the crate can be used in a no-alloc environment it is enough that it
builds successfully.

## Acknowledgements

The code was based on the [example by zulinx86](https://zenn.dev/zulinx86/articles/rust-nostd-101)

## Exclusion from the workspace

This crate is excluded from the workspace because it requires the profile setting `panic = abort`.

We do not want to apply that profile to the whole workspace, but the panic profile setting cannot
be applied to individual crates in a workspace.
2 changes: 2 additions & 0 deletions tools/no_alloc_check/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
51 changes: 51 additions & 0 deletions tools/no_alloc_check/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! A simple executable to check that the `acpi` crate can be used in a no-alloc environment.
//!
//! This was born out of a comment in [issue 311](https://github.com/rust-osdev/acpi/issues/311)
//! that it didn't work.
//!
//! This executable should build, but actually attempting to run it will result in an access
//! violation. It is enough that it builds successfully.
//!
//! Heavily adapted from the
//! [example by zulinx86](https://zenn.dev/zulinx86/articles/rust-nostd-101)

#![no_std]
#![no_main]

mod null_handler;

use core::{arch::asm, panic::PanicInfo};

use null_handler::NullHandler;

fn sys_exit(status: i32) -> ! {
unsafe {
asm!(
"syscall",
in("rax") 60,
in("rdi") status,
options(noreturn)
);
}
}

#[unsafe(no_mangle)]
pub extern "C" fn _start() -> ! {
use ::acpi::{AcpiTables, sdt::madt::Madt};

// Clearly actually executing this will result in an access violation. The point is to check that it compiles.
let tables = unsafe { AcpiTables::from_rsdp(NullHandler {}, 0xd1e as usize) }
.unwrap_or_else(|x| panic!("Failed to parse RSDP table: {:?}", x));

let mut _madt = tables.find_table::<Madt>().expect("Failed to find MADT");

_madt.get().entries().for_each(|_entry| {});

// Just in case it doesn't die already!
sys_exit(0);
}

#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}
93 changes: 93 additions & 0 deletions tools/no_alloc_check/src/null_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//! A [`Handler`] that does nothing useful.
//!
//! This is pretty much a duplicate of [`aml_test_utils::NullHandler`]. We don't use that version
//! because `aml_test_tools` is not a `no_std` crate, which we need for this executable.

use acpi::{Handler, PhysicalMapping};
use pci_types::PciAddress;

#[derive(Clone)]
pub struct NullHandler;

/// A [`Handler`] that does nothing. If required, it will generally return zero.
///
/// This is useful as a placeholder if you really don't care what values the core [`acpi`] parser
/// receives.
///
/// The handler is not ever called in this crate, but it must be present for compilation purposes.
impl Handler for NullHandler {
unsafe fn map_physical_region<T>(&self, _physical_address: usize, _size: usize) -> PhysicalMapping<Self, T> {
// This isn't implemented in `aml_tester` either
todo!()
}

fn unmap_physical_region<T>(_region: &PhysicalMapping<Self, T>) {}

fn read_u8(&self, _address: usize) -> u8 {
0
}

fn read_u16(&self, _address: usize) -> u16 {
0
}

fn read_u32(&self, _address: usize) -> u32 {
0
}

fn read_u64(&self, _address: usize) -> u64 {
0
}

fn write_u8(&self, _address: usize, _value: u8) {}

fn write_u16(&self, _address: usize, _value: u16) {}

fn write_u32(&self, _address: usize, _value: u32) {}

fn write_u64(&self, _address: usize, _value: u64) {}

fn read_io_u8(&self, _port: u16) -> u8 {
0
}

fn read_io_u16(&self, _port: u16) -> u16 {
0
}

fn read_io_u32(&self, _port: u16) -> u32 {
0
}

fn write_io_u8(&self, _port: u16, _value: u8) {}

fn write_io_u16(&self, _port: u16, _value: u16) {}

fn write_io_u32(&self, _port: u16, _value: u32) {}

fn read_pci_u8(&self, _address: PciAddress, _offset: u16) -> u8 {
0
}

fn read_pci_u16(&self, _address: PciAddress, _offset: u16) -> u16 {
0
}

fn read_pci_u32(&self, _address: PciAddress, _offset: u16) -> u32 {
0
}

fn write_pci_u8(&self, _address: PciAddress, _offset: u16, _value: u8) {}

fn write_pci_u16(&self, _address: PciAddress, _offset: u16, _value: u16) {}

fn write_pci_u32(&self, _address: PciAddress, _offset: u16, _value: u32) {}

fn nanos_since_boot(&self) -> u64 {
1000
}

fn stall(&self, _microseconds: u64) {}

fn sleep(&self, _milliseconds: u64) {}
}
Loading