Skip to content

Commit 246be2f

Browse files
authored
Merge branch 'main' into main
2 parents 136af52 + c99c032 commit 246be2f

File tree

9 files changed

+200
-58
lines changed

9 files changed

+200
-58
lines changed

.github/workflows/build.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,20 @@ jobs:
6464

6565
- name: Run AML test suite
6666
run: cargo run --bin aml_tester -- -p tests --reset
67+
68+
clippy:
69+
runs-on: ubuntu-latest
70+
steps:
71+
- uses: actions/checkout@v2
72+
with:
73+
submodules: 'recursive'
74+
- name: Install Rust
75+
uses: actions-rs/toolchain@v1
76+
with:
77+
toolchain: nightly
78+
default: true
79+
profile: minimal
80+
components: clippy
81+
82+
- name: Run clippy
83+
run: cargo clippy -p acpi

acpi-dumper/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,5 @@ fn main() {
9898

9999
#[cfg(not(target_os = "linux"))]
100100
fn main() {
101-
std::compilation_error!("acpi-dumper currently only supports linux");
101+
std::compile_error!("acpi-dumper currently only supports linux");
102102
}

acpi/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "acpi"
3-
version = "5.0.0"
3+
version = "5.1.0"
44
authors = ["Isaac Woods"]
55
repository = "https://github.com/rust-osdev/acpi"
66
description = "A pure-Rust library for parsing ACPI tables"

acpi/src/handler.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use core::{fmt, ops::Deref, ptr::NonNull};
1+
use core::{
2+
fmt,
3+
ops::{Deref, DerefMut},
4+
ptr::NonNull,
5+
};
26

37
/// Describes a physical mapping created by `AcpiHandler::map_physical_region` and unmapped by
48
/// `AcpiHandler::unmap_physical_region`. The region mapped must be at least `size_of::<T>()`
@@ -47,6 +51,10 @@ where
4751
/// than `region_length`, due to requirements of the paging system or other reasoning.
4852
/// - `handler` should be the same `AcpiHandler` that created the mapping. When the `PhysicalMapping` is
4953
/// dropped, it will be used to unmap the structure.
54+
///
55+
/// ### Safety
56+
///
57+
/// The caller must ensure that the physical memory can be safely mapped.
5058
pub unsafe fn new(
5159
physical_start: usize,
5260
virtual_start: NonNull<T>,
@@ -105,6 +113,15 @@ where
105113
}
106114
}
107115

116+
impl<H, T> DerefMut for PhysicalMapping<H, T>
117+
where
118+
H: AcpiHandler,
119+
{
120+
fn deref_mut(&mut self) -> &mut T {
121+
unsafe { self.virtual_start.as_mut() }
122+
}
123+
}
124+
108125
impl<H, T> Drop for PhysicalMapping<H, T>
109126
where
110127
H: AcpiHandler,

acpi/src/lib.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,27 @@
2020
//! default configuration of the crate.
2121
//!
2222
//! ### Usage
23-
//! To use the library, you will need to provide an implementation of the `AcpiHandler` trait, which allows the
23+
//! To use the library, you will need to provide an implementation of the [`AcpiHandler`] trait, which allows the
2424
//! library to make requests such as mapping a particular region of physical memory into the virtual address space.
2525
//!
26-
//! You then need to construct an instance of `AcpiTables`, which can be done in a few ways depending on how much
26+
//! You then need to construct an instance of [`AcpiTables`], which can be done in a few ways depending on how much
2727
//! information you have:
28-
//! * Use `AcpiTables::from_rsdp` if you have the physical address of the RSDP
29-
//! * Use `AcpiTables::from_rsdt` if you have the physical address of the RSDT/XSDT
30-
//! * Use `AcpiTables::search_for_rsdp_bios` if you don't have the address of either, but **you know you are
31-
//! running on BIOS, not UEFI**
32-
//! * Use `AcpiTables::from_tables_direct` if you are using the library in an unusual setting, such as in usermode,
33-
//! and have a custom method to enumerate and access the tables.
28+
//! * Use [`AcpiTables::from_rsdp`] if you have the physical address of the RSDP
29+
//! * Use [`AcpiTables::from_rsdt`] if you have the physical address of the RSDT/XSDT
30+
//! * Use [`AcpiTables::search_for_rsdp_bios`] if you don't have the address of either, but **you know you are
31+
//! running on BIOS, not UEFI**
3432
//!
3533
//! `AcpiTables` stores the addresses of all of the tables detected on a platform. The SDTs are parsed by this
3634
//! library, or can be accessed directly with `from_sdt`, while the `DSDT` and any `SSDTs` should be parsed with
3735
//! `aml`.
3836
//!
3937
//! To gather information out of the static tables, a few of the types you should take a look at are:
40-
//! - [`PlatformInfo`](crate::platform::PlatformInfo) parses the FADT and MADT to create a nice view of the
41-
//! processor topology and interrupt controllers on `x86_64`, and the interrupt controllers on other platforms.
42-
//! `AcpiTables::platform_info` is a convenience method for constructing a `PlatformInfo`.
43-
//! - [`HpetInfo`](crate::hpet::HpetInfo) parses the HPET table and tells you how to configure the High
44-
//! Precision Event Timer.
45-
//! - [`PciConfigRegions`](crate::mcfg::PciConfigRegions) parses the MCFG and tells you how PCIe configuration
46-
//! space is mapped into physical memory.
38+
//! - [`PlatformInfo`] parses the FADT and MADT to create a nice view of the processor topology and interrupt
39+
//! controllers on `x86_64`, and the interrupt controllers on other platforms.
40+
//! [`AcpiTables::platform_info`] is a convenience method for constructing a `PlatformInfo`.
41+
//! - [`HpetInfo`] parses the HPET table and tells you how to configure the High Precision Event Timer.
42+
//! - [`PciConfigRegions`] parses the MCFG and tells you how PCIe configuration space is mapped into physical
43+
//! memory.
4744
4845
/*
4946
* Contributing notes (you may find these useful if you're new to contributing to the library):
@@ -206,7 +203,9 @@ where
206203
{
207204
/// Create an `AcpiTables` if you have the physical address of the RSDP.
208205
///
209-
/// ### Safety: Caller must ensure the provided address is valid to read as an RSDP.
206+
/// ### Safety
207+
///
208+
/// Caller must ensure the provided address is valid to read as an RSDP.
210209
pub unsafe fn from_rsdp(handler: H, address: usize) -> AcpiResult<Self> {
211210
let rsdp_mapping = unsafe { handler.map_physical_region::<Rsdp>(address, mem::size_of::<Rsdp>()) };
212211
rsdp_mapping.validate()?;
@@ -216,8 +215,12 @@ where
216215
}
217216

218217
/// Search for the RSDP on a BIOS platform. This accesses BIOS-specific memory locations and will probably not
219-
/// work on UEFI platforms. See [Rsdp::search_for_rsdp_bios](rsdp_search::Rsdp::search_for_rsdp_bios) for
218+
/// work on UEFI platforms. See [`Rsdp::search_for_on_bios`] for details.
220219
/// details.
220+
///
221+
/// ### Safety
222+
///
223+
/// The caller must ensure that this function is called on BIOS platforms.
221224
pub unsafe fn search_for_rsdp_bios(handler: H) -> AcpiResult<Self> {
222225
let rsdp_mapping = unsafe { Rsdp::search_for_on_bios(handler.clone())? };
223226
// Safety: RSDP has been validated from `Rsdp::search_for_on_bios`
@@ -234,7 +237,9 @@ where
234237
/// from `from_rsdp` after validation, but can also be used if you've searched for the RSDP manually on a BIOS
235238
/// system.
236239
///
237-
/// ### Safety: Caller must ensure that the provided mapping is a fully validated RSDP.
240+
/// ### Safety
241+
///
242+
/// Caller must ensure that the provided mapping is a fully validated RSDP.
238243
pub unsafe fn from_validated_rsdp(handler: H, rsdp_mapping: PhysicalMapping<H, Rsdp>) -> AcpiResult<Self> {
239244
let revision = rsdp_mapping.revision();
240245
let root_table_mapping = if revision == 0 {
@@ -259,7 +264,9 @@ where
259264

260265
/// Create an `AcpiTables` if you have the physical address of the RSDT/XSDT.
261266
///
262-
/// ### Safety: Caller must ensure the provided address is valid RSDT/XSDT address.
267+
/// ### Safety
268+
///
269+
/// Caller must ensure the provided address is valid RSDT/XSDT address.
263270
pub unsafe fn from_rsdt(handler: H, revision: u8, address: usize) -> AcpiResult<Self> {
264271
let root_table_mapping = if revision == 0 {
265272
/*
@@ -404,19 +411,17 @@ where
404411
Ok(())
405412
}
406413

407-
/// Convenience method for contructing a [`PlatformInfo`](crate::platform::PlatformInfo). This is one of the
408-
/// first things you should usually do with an `AcpiTables`, and allows to collect helpful information about
409-
/// the platform from the ACPI tables.
414+
/// Convenience method for contructing a [`PlatformInfo`]. This is one of the first things you should usually do
415+
/// with an `AcpiTables`, and allows to collect helpful information about the platform from the ACPI tables.
410416
///
411-
/// Like `platform_info_in`, but uses the global allocator.
417+
/// Like [`platform_info_in`](Self::platform_info_in), but uses the global allocator.
412418
#[cfg(feature = "alloc")]
413419
pub fn platform_info(&self) -> AcpiResult<PlatformInfo<alloc::alloc::Global>> {
414420
PlatformInfo::new(self)
415421
}
416422

417-
/// Convenience method for contructing a [`PlatformInfo`](crate::platform::PlatformInfo). This is one of the
418-
/// first things you should usually do with an `AcpiTables`, and allows to collect helpful information about
419-
/// the platform from the ACPI tables.
423+
/// Convenience method for contructing a [`PlatformInfo`]. This is one of the first things you should usually do
424+
/// with an `AcpiTables`, and allows to collect helpful information about the platform from the ACPI tables.
420425
#[cfg(feature = "allocator_api")]
421426
pub fn platform_info_in<A>(&self, allocator: A) -> AcpiResult<PlatformInfo<A>>
422427
where
@@ -457,7 +462,9 @@ impl AmlTable {
457462
}
458463
}
459464

460-
/// ### Safety: Caller must ensure the provided address is valid for being read as an `SdtHeader`.
465+
/// ### Safety
466+
///
467+
/// Caller must ensure the provided address is valid for being read as an `SdtHeader`.
461468
unsafe fn read_table<H: AcpiHandler, T: AcpiTable>(
462469
handler: H,
463470
address: usize,
@@ -480,7 +487,7 @@ where
480487
handler: H,
481488
}
482489

483-
impl<'t, H> Iterator for SsdtIterator<'t, H>
490+
impl<H> Iterator for SsdtIterator<'_, H>
484491
where
485492
H: AcpiHandler,
486493
{
@@ -528,7 +535,7 @@ where
528535
handler: H,
529536
}
530537

531-
impl<'t, H> Iterator for SdtHeaderIterator<'t, H>
538+
impl<H> Iterator for SdtHeaderIterator<'_, H>
532539
where
533540
H: AcpiHandler,
534541
{

acpi/src/madt.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
22
sdt::{ExtendedField, SdtHeader, Signature},
3+
AcpiError,
34
AcpiTable,
45
};
56
use bit_field::BitField;
@@ -21,6 +22,7 @@ pub enum MadtError {
2122
InvalidLocalNmiLine,
2223
MpsIntiInvalidPolarity,
2324
MpsIntiInvalidTriggerMode,
25+
WakeupApsTimeout,
2426
}
2527

2628
/// Represents the MADT - this contains the MADT header fields. You can then iterate over a `Madt`
@@ -60,6 +62,15 @@ impl fmt::Display for Madt {
6062
}
6163

6264
impl Madt {
65+
pub fn get_mpwk_mailbox_addr(&self) -> Result<u64, AcpiError> {
66+
for entry in self.entries() {
67+
if let MadtEntry::MultiprocessorWakeup(entry) = entry {
68+
return Ok(entry.mailbox_address);
69+
}
70+
}
71+
Err(AcpiError::InvalidMadt(MadtError::UnexpectedEntry))
72+
}
73+
6374
#[cfg(feature = "allocator_api")]
6475
pub fn parse_interrupt_model_in<'a, A>(
6576
&self,
@@ -766,6 +777,36 @@ pub struct MultiprocessorWakeupEntry {
766777
pub mailbox_address: u64,
767778
}
768779

780+
#[derive(Debug, PartialEq, Eq)]
781+
pub enum MpProtectedModeWakeupCommand {
782+
Noop = 0,
783+
Wakeup = 1,
784+
Sleep = 2,
785+
AcceptPages = 3,
786+
}
787+
788+
impl From<u16> for MpProtectedModeWakeupCommand {
789+
fn from(value: u16) -> Self {
790+
match value {
791+
0 => MpProtectedModeWakeupCommand::Noop,
792+
1 => MpProtectedModeWakeupCommand::Wakeup,
793+
2 => MpProtectedModeWakeupCommand::Sleep,
794+
3 => MpProtectedModeWakeupCommand::AcceptPages,
795+
_ => panic!("Invalid value for MpProtectedModeWakeupCommand"),
796+
}
797+
}
798+
}
799+
800+
#[repr(C)]
801+
pub struct MultiprocessorWakeupMailbox {
802+
pub command: u16,
803+
_reserved: u16,
804+
pub apic_id: u32,
805+
pub wakeup_vector: u64,
806+
pub reserved_for_os: [u64; 254],
807+
reserved_for_firmware: [u64; 256],
808+
}
809+
769810
#[cfg(feature = "allocator_api")]
770811
fn parse_mps_inti_flags(flags: u16) -> crate::AcpiResult<(Polarity, TriggerMode)> {
771812
let polarity = match flags.get_bits(0..2) {

acpi/src/managed_slice.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ where
1616
allocator: A,
1717
}
1818

19-
impl<'a, T, A> ManagedSlice<'a, T, A>
19+
impl<T, A> ManagedSlice<'_, T, A>
2020
where
2121
A: Allocator,
2222
{
@@ -34,13 +34,13 @@ where
3434
}
3535

3636
#[cfg(feature = "alloc")]
37-
impl<'a, T> ManagedSlice<'a, T, alloc::alloc::Global> {
37+
impl<T> ManagedSlice<'_, T, alloc::alloc::Global> {
3838
pub fn new(len: usize) -> AcpiResult<Self> {
3939
Self::new_in(len, alloc::alloc::Global)
4040
}
4141
}
4242

43-
impl<'a, T, A> Drop for ManagedSlice<'a, T, A>
43+
impl<T, A> Drop for ManagedSlice<'_, T, A>
4444
where
4545
A: Allocator,
4646
{
@@ -54,7 +54,7 @@ where
5454
}
5555
}
5656

57-
impl<'a, T, A> core::ops::Deref for ManagedSlice<'a, T, A>
57+
impl<T, A> core::ops::Deref for ManagedSlice<'_, T, A>
5858
where
5959
A: Allocator,
6060
{
@@ -65,7 +65,7 @@ where
6565
}
6666
}
6767

68-
impl<'a, T, A> core::ops::DerefMut for ManagedSlice<'a, T, A>
68+
impl<T, A> core::ops::DerefMut for ManagedSlice<'_, T, A>
6969
where
7070
A: Allocator,
7171
{

0 commit comments

Comments
 (0)