Parse FADT

This commit is contained in:
Jeremy Soller 2016-12-28 17:21:16 -07:00
parent eb09f13a9c
commit 1bcc7f96f4
4 changed files with 127 additions and 1 deletions

View 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
}
}
}

View file

@ -11,12 +11,14 @@ use paging::{entry, ActivePageTable, Page, PhysicalAddress, VirtualAddress};
use start::{kstart_ap, CPU_COUNT, AP_READY};
use self::dmar::{Dmar, DmarEntry};
use self::fadt::Fadt;
use self::madt::{Madt, MadtEntry};
use self::rsdt::Rsdt;
use self::sdt::Sdt;
use self::xsdt::Xsdt;
pub mod dmar;
pub mod fadt;
pub mod madt;
pub mod rsdt;
pub mod sdt;
@ -31,7 +33,9 @@ pub fn init_sdt(sdt: &'static Sdt, active_table: &mut ActivePageTable) {
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);
let mut local_apic = unsafe { &mut LOCAL_APIC };

View file

@ -316,5 +316,8 @@ pub mod panic;
/// Initialization and start function
pub mod start;
/// Shutdown function
pub mod stop;
/// Time
pub mod time;

23
arch/x86_64/src/stop.rs Normal file
View 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!();
}