Skip to content

Commit a9b3499

Browse files
committed
ACPI: Replace static mut
1 parent 60fc624 commit a9b3499

File tree

1 file changed

+24
-27
lines changed

1 file changed

+24
-27
lines changed

src/arch/x86_64/kernel/acpi.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use core::convert::Infallible;
22
use core::{mem, ptr, slice, str};
33

44
use align_address::Align;
5+
use hermit_sync::OnceCell;
56
use x86::io::*;
67
use x86_64::structures::paging::PhysFrame;
78

@@ -41,11 +42,11 @@ const AML_BYTEPREFIX: u8 = 0x0A;
4142
const SLP_EN: u16 = 1 << 13;
4243

4344
/// The "Multiple APIC Description Table" (MADT) preserved for get_apic_table().
44-
static mut MADT: Option<AcpiTable<'_>> = None;
45+
static MADT: OnceCell<AcpiTable<'_>> = OnceCell::new();
4546
/// The PM1A Control I/O Port for powering off the computer through ACPI.
46-
static mut PM1A_CNT_BLK: Option<u16> = None;
47+
static PM1A_CNT_BLK: OnceCell<u16> = OnceCell::new();
4748
/// The Sleeping State Type code for powering off the computer through ACPI.
48-
static mut SLP_TYPA: Option<u8> = None;
49+
static SLP_TYPA: OnceCell<u8> = OnceCell::new();
4950

5051
/// The "Root System Description Pointer" structure providing pointers to all other ACPI tables.
5152
#[repr(C, packed)]
@@ -68,6 +69,7 @@ impl AcpiRsdp {
6869
}
6970

7071
/// The header of (almost) every ACPI table.
72+
#[derive(Clone, Copy, Debug)]
7173
#[repr(C, packed)]
7274
struct AcpiSdtHeader {
7375
signature: [u8; 4],
@@ -89,6 +91,7 @@ impl AcpiSdtHeader {
8991

9092
/// A convenience structure to work with an ACPI table.
9193
/// Maps a single table to memory and frees the memory when a variable of this structure goes out of scope.
94+
#[derive(Debug)]
9295
pub struct AcpiTable<'a> {
9396
header: &'a AcpiSdtHeader,
9497
allocated_virtual_address: VirtAddr,
@@ -376,9 +379,7 @@ fn search_s5_in_table(table: AcpiTable<'_>) {
376379
// Note that Power Off may also be controlled through PM1B_CNT_BLK / SLP_TYPB
377380
// according to the ACPI Specification. However, this has not yet been observed on real computers
378381
// and therefore not implemented.
379-
unsafe {
380-
SLP_TYPA = Some(slp_typa);
381-
}
382+
SLP_TYPA.set(slp_typa).unwrap();
382383
}
383384
}
384385
}
@@ -402,9 +403,7 @@ fn parse_fadt(fadt: AcpiTable<'_>) {
402403
} else {
403404
fadt_table.pm1a_cnt_blk as u16
404405
};
405-
unsafe {
406-
PM1A_CNT_BLK = Some(pm1a_cnt_blk);
407-
}
406+
PM1A_CNT_BLK.set(pm1a_cnt_blk).unwrap();
408407

409408
// Map the "Differentiated System Description Table" (DSDT).
410409
let x_dsdt_field_address = ptr::addr_of!(fadt_table.x_dsdt) as usize;
@@ -435,7 +434,7 @@ fn parse_fadt(fadt: AcpiTable<'_>) {
435434
fn parse_ssdt(ssdt: AcpiTable<'_>) {
436435
// We don't need to parse the SSDT if we already have information about the "_S5_" object
437436
// (e.g. from the DSDT or a previous SSDT).
438-
if unsafe { SLP_TYPA }.is_some() {
437+
if SLP_TYPA.get().is_some() {
439438
return;
440439
}
441440

@@ -444,25 +443,25 @@ fn parse_ssdt(ssdt: AcpiTable<'_>) {
444443
}
445444

446445
pub fn get_madt() -> Option<&'static AcpiTable<'static>> {
447-
unsafe { MADT.as_ref() }
446+
MADT.get()
448447
}
449448

450449
pub fn poweroff() -> Result<Infallible, ()> {
451-
unsafe {
452-
if let (Some(pm1a_cnt_blk), Some(slp_typa)) = (PM1A_CNT_BLK, SLP_TYPA) {
453-
let bits = (u16::from(slp_typa) << 10) | SLP_EN;
454-
debug!(
455-
"Powering Off through ACPI (port {:#X}, bitmask {:#X})",
456-
pm1a_cnt_blk, bits
457-
);
450+
if let (Some(&pm1a_cnt_blk), Some(&slp_typa)) = (PM1A_CNT_BLK.get(), SLP_TYPA.get()) {
451+
let bits = (u16::from(slp_typa) << 10) | SLP_EN;
452+
debug!(
453+
"Powering Off through ACPI (port {:#X}, bitmask {:#X})",
454+
pm1a_cnt_blk, bits
455+
);
456+
unsafe {
458457
outw(pm1a_cnt_blk, bits);
459-
loop {
460-
processor::halt();
461-
}
462-
} else {
463-
warn!("ACPI Power Off is not available");
464-
Err(())
465458
}
459+
loop {
460+
processor::halt();
461+
}
462+
} else {
463+
warn!("ACPI Power Off is not available");
464+
Err(())
466465
}
467466
}
468467

@@ -505,9 +504,7 @@ pub fn init() {
505504
verify_checksum(table.header_start_address(), table.header.length as usize).is_ok(),
506505
"MADT at {table_physical_address:#X} has invalid checksum"
507506
);
508-
unsafe {
509-
MADT = Some(table);
510-
}
507+
MADT.set(table).unwrap();
511508
} else if table.header.signature() == "FACP" {
512509
// The "Fixed ACPI Description Table" (FADT) aka "Fixed ACPI Control Pointer" (FACP)
513510
// Check and parse this table for the poweroff() call.

0 commit comments

Comments
 (0)