Parse FADT
This commit is contained in:
parent
eb09f13a9c
commit
1bcc7f96f4
96
arch/x86_64/src/acpi/fadt.rs
Normal file
96
arch/x86_64/src/acpi/fadt.rs
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
use core::{mem, ptr};
|
||||||
|
|
||||||
|
use super::sdt::Sdt;
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Fadt {
|
||||||
|
pub header: Sdt,
|
||||||
|
pub firmware_ctrl: u32,
|
||||||
|
pub dsdt: u32,
|
||||||
|
|
||||||
|
// field used in ACPI 1.0; no longer in use, for compatibility only
|
||||||
|
reserved: u8,
|
||||||
|
|
||||||
|
pub preferred_power_managament: u8,
|
||||||
|
pub sci_interrupt: u16,
|
||||||
|
pub smi_command_port: u32,
|
||||||
|
pub acpi_enable: u8,
|
||||||
|
pub acpi_disable: u8,
|
||||||
|
pub s4_bios_req: u8,
|
||||||
|
pub pstate_control: u8,
|
||||||
|
pub pm1a_event_block: u32,
|
||||||
|
pub pm1b_event_block: u32,
|
||||||
|
pub pm1a_control_block: u32,
|
||||||
|
pub pm1b_control_block: u32,
|
||||||
|
pub pm2_control_block: u32,
|
||||||
|
pub pm_timer_block: u32,
|
||||||
|
pub gpe0_block: u32,
|
||||||
|
pub gpe1_block: u32,
|
||||||
|
pub pm1_event_length: u8,
|
||||||
|
pub pm1_control_length: u8,
|
||||||
|
pub pm2_control_length: u8,
|
||||||
|
pub pm_timer_length: u8,
|
||||||
|
pub gpe0_ength: u8,
|
||||||
|
pub gpe1_length: u8,
|
||||||
|
pub gpe1_base: u8,
|
||||||
|
pub c_state_control: u8,
|
||||||
|
pub worst_c2_latency: u16,
|
||||||
|
pub worst_c3_latency: u16,
|
||||||
|
pub flush_size: u16,
|
||||||
|
pub flush_stride: u16,
|
||||||
|
pub duty_offset: u8,
|
||||||
|
pub duty_width: u8,
|
||||||
|
pub day_alarm: u8,
|
||||||
|
pub month_alarm: u8,
|
||||||
|
pub century: u8,
|
||||||
|
|
||||||
|
// reserved in ACPI 1.0; used since ACPI 2.0+
|
||||||
|
pub boot_architecture_flags: u16,
|
||||||
|
|
||||||
|
reserved2: u8,
|
||||||
|
pub flags: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ACPI 2 structure
|
||||||
|
#[repr(packed)]
|
||||||
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
pub struct GenericAddressStructure {
|
||||||
|
address_space: u8,
|
||||||
|
bit_width: u8,
|
||||||
|
bit_offset: u8,
|
||||||
|
access_size: u8,
|
||||||
|
address: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// 12 byte structure; see below for details
|
||||||
|
pub reset_reg: GenericAddressStructure,
|
||||||
|
|
||||||
|
pub reset_value: u8,
|
||||||
|
reserved3: [u8; 3],
|
||||||
|
|
||||||
|
// 64bit pointers - Available on ACPI 2.0+
|
||||||
|
pub x_firmware_control: u64,
|
||||||
|
pub x_dsdt: u64,
|
||||||
|
|
||||||
|
pub x_pm1a_event_block: GenericAddressStructure,
|
||||||
|
pub x_pm1b_event_block: GenericAddressStructure,
|
||||||
|
pub x_pm1a_control_block: GenericAddressStructure,
|
||||||
|
pub x_pm1b_control_block: GenericAddressStructure,
|
||||||
|
pub x_pm2_control_block: GenericAddressStructure,
|
||||||
|
pub x_pm_timer_block: GenericAddressStructure,
|
||||||
|
pub x_gpe0_block: GenericAddressStructure,
|
||||||
|
pub x_gpe1_block: GenericAddressStructure,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
impl Fadt {
|
||||||
|
pub fn new(sdt: &'static Sdt) -> Option<Fadt> {
|
||||||
|
if &sdt.signature == b"FACP" && sdt.length as usize >= mem::size_of::<Fadt>() {
|
||||||
|
Some(unsafe { ptr::read((sdt as *const Sdt) as *const Fadt) })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,12 +11,14 @@ use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
|
||||||
use start::{kstart_ap, CPU_COUNT, AP_READY};
|
use start::{kstart_ap, CPU_COUNT, AP_READY};
|
||||||
|
|
||||||
use self::dmar::{Dmar, DmarEntry};
|
use self::dmar::{Dmar, DmarEntry};
|
||||||
|
use self::fadt::Fadt;
|
||||||
use self::madt::{Madt, MadtEntry};
|
use self::madt::{Madt, MadtEntry};
|
||||||
use self::rsdt::Rsdt;
|
use self::rsdt::Rsdt;
|
||||||
use self::sdt::Sdt;
|
use self::sdt::Sdt;
|
||||||
use self::xsdt::Xsdt;
|
use self::xsdt::Xsdt;
|
||||||
|
|
||||||
pub mod dmar;
|
pub mod dmar;
|
||||||
|
pub mod fadt;
|
||||||
pub mod madt;
|
pub mod madt;
|
||||||
pub mod rsdt;
|
pub mod rsdt;
|
||||||
pub mod sdt;
|
pub mod sdt;
|
||||||
|
@ -31,7 +33,9 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
|
||||||
print!("{}", c as char);
|
print!("{}", c as char);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(madt) = Madt::new(sdt) {
|
if let Some(fadt) = Fadt::new(sdt) {
|
||||||
|
println!(": {:#?}", fadt);
|
||||||
|
} else if let Some(madt) = Madt::new(sdt) {
|
||||||
println!(": {:>08X}: {}", madt.local_address, madt.flags);
|
println!(": {:>08X}: {}", madt.local_address, madt.flags);
|
||||||
|
|
||||||
let mut local_apic = unsafe { &mut LOCAL_APIC };
|
let mut local_apic = unsafe { &mut LOCAL_APIC };
|
||||||
|
|
|
@ -316,5 +316,8 @@ pub mod panic;
|
||||||
/// Initialization and start function
|
/// Initialization and start function
|
||||||
pub mod start;
|
pub mod start;
|
||||||
|
|
||||||
|
/// Shutdown function
|
||||||
|
pub mod stop;
|
||||||
|
|
||||||
/// Time
|
/// Time
|
||||||
pub mod time;
|
pub mod time;
|
||||||
|
|
23
arch/x86_64/src/stop.rs
Normal file
23
arch/x86_64/src/stop.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use io::{Io, Pio};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern fn kstop() -> ! {
|
||||||
|
// (phony) ACPI shutdown (http://forum.osdev.org/viewtopic.php?t=16990)
|
||||||
|
// Works for qemu and bochs.
|
||||||
|
for &port in [0x604, 0xB004].iter() {
|
||||||
|
println!("Shutdown with outw(0x{:X}, 0x{:X})", port, 0x2000);
|
||||||
|
Pio::<u16>::new(port).write(0x2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic shutdown code for bochs and qemu (older versions).
|
||||||
|
for c in "Shutdown".bytes() {
|
||||||
|
println!("Shutdown with outb(0x{:X}, '{}')", 0x8900, c as char);
|
||||||
|
Pio::<u8>::new(0x8900).write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Magic code for VMWare. Also a hard lock.
|
||||||
|
println!("Shutdown with cli hlt");
|
||||||
|
asm!("cli; hlt" : : : : "intel", "volatile");
|
||||||
|
|
||||||
|
unreachable!();
|
||||||
|
}
|
Loading…
Reference in a new issue