Update to latest acpi crate
This commit is contained in:
+29
-33
@@ -1,6 +1,7 @@
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{fmt, mem};
|
||||
use syscall::PAGE_SIZE;
|
||||
@@ -11,9 +12,13 @@ use common::io::{Io, Pio};
|
||||
use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
use thiserror::Error;
|
||||
|
||||
use aml::{AmlContext, AmlError, AmlHandle, AmlName};
|
||||
use acpi::{
|
||||
aml::{namespace::AmlName, AmlError, Interpreter},
|
||||
platform::AcpiPlatform,
|
||||
AcpiTables,
|
||||
};
|
||||
use amlserde::aml_serde_name::aml_to_symbol;
|
||||
use amlserde::{AmlHandleLookup, AmlSerde};
|
||||
use amlserde::AmlSerde;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub mod dmar;
|
||||
@@ -232,7 +237,7 @@ pub struct Ssdt(Sdt);
|
||||
// must empty the cache so it is rebuilt.
|
||||
// If you modify an SDT, you must discard the aml_context and rebuild it.
|
||||
pub struct AmlSymbols {
|
||||
aml_context: AmlContext,
|
||||
aml_context: Interpreter<AmlPhysMemHandler>,
|
||||
// k = name, v = description
|
||||
symbol_cache: FxHashMap<String, String>,
|
||||
page_cache: Arc<Mutex<AmlPageCache>>,
|
||||
@@ -241,17 +246,19 @@ pub struct AmlSymbols {
|
||||
impl AmlSymbols {
|
||||
pub fn new() -> Self {
|
||||
let page_cache = Arc::new(Mutex::new(AmlPageCache::default()));
|
||||
let handler = AmlPhysMemHandler::new(Arc::clone(&page_cache));
|
||||
//TODO: use these parsed tables for the rest of acpid and return errors instead of unwrap
|
||||
let rsdp_address = usize::from_str_radix(&std::env::var("RSDP_ADDR").unwrap(), 16).unwrap();
|
||||
let tables = unsafe { AcpiTables::from_rsdp(handler.clone(), rsdp_address).unwrap() };
|
||||
let platform = AcpiPlatform::new(tables, handler).unwrap();
|
||||
Self {
|
||||
aml_context: AmlContext::new(
|
||||
Box::new(AmlPhysMemHandler::new(Arc::clone(&page_cache))),
|
||||
aml::DebugVerbosity::None,
|
||||
),
|
||||
aml_context: Interpreter::new_from_platform(&platform).unwrap(),
|
||||
symbol_cache: FxHashMap::default(),
|
||||
page_cache,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mut_aml_context(&mut self) -> &mut AmlContext {
|
||||
pub fn mut_aml_context(&mut self) -> &mut Interpreter<AmlPhysMemHandler> {
|
||||
&mut self.aml_context
|
||||
}
|
||||
|
||||
@@ -260,7 +267,7 @@ impl AmlSymbols {
|
||||
}
|
||||
|
||||
pub fn parse_table(&mut self, aml: &[u8]) -> Result<(), AmlError> {
|
||||
self.aml_context.parse_table(aml)
|
||||
self.aml_context.load_table(aml)
|
||||
}
|
||||
|
||||
pub fn lookup(&self, symbol: &str) -> Option<String> {
|
||||
@@ -272,18 +279,19 @@ impl AmlSymbols {
|
||||
}
|
||||
|
||||
pub fn build_cache(&mut self) {
|
||||
let mut symbol_list: Vec<(AmlName, String, AmlHandle)> = Vec::with_capacity(5000);
|
||||
let mut symbol_list: Vec<(AmlName, String)> = Vec::with_capacity(5000);
|
||||
|
||||
if self
|
||||
.aml_context
|
||||
.namespace
|
||||
.lock()
|
||||
.traverse(|level_aml_name, level| {
|
||||
for (child_seg, handle) in level.values.iter() {
|
||||
if let Ok(aml_name) =
|
||||
AmlName::from_name_seg(child_seg.to_owned()).resolve(level_aml_name)
|
||||
{
|
||||
let name = aml_to_symbol(&aml_name);
|
||||
symbol_list.push((aml_name, name, handle.to_owned()));
|
||||
symbol_list.push((aml_name, name));
|
||||
} else {
|
||||
log::error!(
|
||||
"AmlName resolve failed, {:?}:{:?}",
|
||||
@@ -300,24 +308,12 @@ impl AmlSymbols {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut handle_lookup = AmlHandleLookup::new();
|
||||
|
||||
for (aml_name, name, handle) in &symbol_list {
|
||||
handle_lookup.insert(handle.to_owned(), aml_name.to_owned());
|
||||
}
|
||||
|
||||
let mut symbol_cache: FxHashMap<String, String> = FxHashMap::default();
|
||||
|
||||
for (aml_name, name, handle) in &symbol_list {
|
||||
for (aml_name, name) in &symbol_list {
|
||||
// create an empty entry, in case something goes wrong with serialization
|
||||
symbol_cache.insert(name.to_owned(), "".to_owned());
|
||||
if let Some(ser_value) = AmlSerde::from_aml(
|
||||
&mut self.aml_context,
|
||||
&handle_lookup,
|
||||
&aml_to_symbol(aml_name),
|
||||
aml_name,
|
||||
handle,
|
||||
) {
|
||||
if let Some(ser_value) = AmlSerde::from_aml(&mut self.aml_context, aml_name) {
|
||||
if let Ok(ser_string) = ron::ser::to_string_pretty(&ser_value, Default::default()) {
|
||||
// replace the empty entry
|
||||
symbol_cache.insert(name.to_owned(), ser_string);
|
||||
@@ -536,7 +532,7 @@ impl AcpiContext {
|
||||
|
||||
let aml_symbols = self.aml_symbols.read();
|
||||
|
||||
let s5_aml_name = match aml::AmlName::from_str("\\_S5") {
|
||||
let s5_aml_name = match acpi::aml::namespace::AmlName::from_str("\\_S5") {
|
||||
Ok(aml_name) => aml_name,
|
||||
Err(error) => {
|
||||
log::error!("Could not build AmlName for \\_S5, {:?}", error);
|
||||
@@ -544,7 +540,7 @@ impl AcpiContext {
|
||||
}
|
||||
};
|
||||
|
||||
let s5 = match aml_symbols.aml_context.namespace.get_by_path(&s5_aml_name) {
|
||||
let s5 = match aml_symbols.aml_context.namespace.lock().get(s5_aml_name) {
|
||||
Ok(s5) => s5,
|
||||
Err(error) => {
|
||||
log::error!("Cannot set S-state, missing \\_S5, {:?}", error);
|
||||
@@ -552,23 +548,23 @@ impl AcpiContext {
|
||||
}
|
||||
};
|
||||
|
||||
let package = match s5 {
|
||||
aml::AmlValue::Package(package) => package,
|
||||
let package = match s5.deref() {
|
||||
acpi::aml::object::Object::Package(package) => package,
|
||||
_ => {
|
||||
log::error!("Cannot set S-state, \\_S5 is not a package");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let slp_typa = match package[0] {
|
||||
aml::AmlValue::Integer(i) => i,
|
||||
let slp_typa = match package[0].deref() {
|
||||
acpi::aml::object::Object::Integer(i) => i.to_owned(),
|
||||
_ => {
|
||||
log::error!("typa is not an Integer");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let slp_typb = match package[1] {
|
||||
aml::AmlValue::Integer(i) => i,
|
||||
let slp_typb = match package[1].deref() {
|
||||
acpi::aml::object::Object::Integer(i) => i.to_owned(),
|
||||
_ => {
|
||||
log::error!("typb is not an Integer");
|
||||
return;
|
||||
|
||||
+80
-18
@@ -1,9 +1,11 @@
|
||||
use acpi::{aml::AmlError, Handle, PciAddress, PhysicalMapping};
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
use common::io::{Io, Pio};
|
||||
use num_traits::PrimInt;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::fmt::LowerHex;
|
||||
use std::mem::size_of;
|
||||
use std::ptr::NonNull;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use syscall::PAGE_SIZE;
|
||||
|
||||
@@ -21,7 +23,7 @@ impl MappedPage {
|
||||
common::physmap(
|
||||
phys_page,
|
||||
PAGE_SIZE,
|
||||
common::Prot::RO,
|
||||
common::Prot::RW,
|
||||
common::MemoryType::default(),
|
||||
)
|
||||
.map_err(|error| std::io::Error::from_raw_os_error(error.errno()))?
|
||||
@@ -135,6 +137,7 @@ impl AmlPageCache {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AmlPhysMemHandler {
|
||||
page_cache: Arc<Mutex<AmlPageCache>>,
|
||||
}
|
||||
@@ -147,7 +150,35 @@ impl AmlPhysMemHandler {
|
||||
}
|
||||
}
|
||||
|
||||
impl aml::Handler for AmlPhysMemHandler {
|
||||
impl acpi::Handler for AmlPhysMemHandler {
|
||||
unsafe fn map_physical_region<T>(&self, phys: usize, size: usize) -> PhysicalMapping<Self, T> {
|
||||
let phys_page = phys & PAGE_MASK;
|
||||
let offset = phys & OFFSET_MASK;
|
||||
let pages = (offset + size + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
let map_size = pages * PAGE_SIZE;
|
||||
let virt_page = common::physmap(
|
||||
phys_page,
|
||||
map_size,
|
||||
common::Prot::RW,
|
||||
common::MemoryType::default(),
|
||||
)
|
||||
.expect("failed to map physical region") as usize;
|
||||
PhysicalMapping {
|
||||
physical_start: phys,
|
||||
virtual_start: NonNull::new((virt_page + offset) as *mut T).unwrap(),
|
||||
region_length: size,
|
||||
mapped_length: map_size,
|
||||
handler: self.clone(),
|
||||
}
|
||||
}
|
||||
fn unmap_physical_region<T>(region: &PhysicalMapping<Self, T>) {
|
||||
let virt_page = region.virtual_start.addr().get() & PAGE_MASK;
|
||||
unsafe {
|
||||
libredox::call::munmap(virt_page as *mut (), region.mapped_length)
|
||||
.expect("failed to unmap physical region")
|
||||
}
|
||||
}
|
||||
|
||||
fn read_u8(&self, address: usize) -> u8 {
|
||||
log::trace!("read u8 {:X}", address);
|
||||
if let Ok(mut page_cache) = self.page_cache.lock() {
|
||||
@@ -189,7 +220,7 @@ impl aml::Handler for AmlPhysMemHandler {
|
||||
0
|
||||
}
|
||||
|
||||
fn write_u8(&mut self, address: usize, value: u8) {
|
||||
fn write_u8(&self, address: usize, value: u8) {
|
||||
log::trace!("write u8 {:X} = {:X}", address, value);
|
||||
if let Ok(mut page_cache) = self.page_cache.lock() {
|
||||
if page_cache.write_to_phys::<u8>(address, value).is_ok() {
|
||||
@@ -198,7 +229,7 @@ impl aml::Handler for AmlPhysMemHandler {
|
||||
}
|
||||
log::error!("failed to write u8 {:#x}", address);
|
||||
}
|
||||
fn write_u16(&mut self, address: usize, value: u16) {
|
||||
fn write_u16(&self, address: usize, value: u16) {
|
||||
log::trace!("write u16 {:X} = {:X}", address, value);
|
||||
if let Ok(mut page_cache) = self.page_cache.lock() {
|
||||
if page_cache.write_to_phys::<u16>(address, value).is_ok() {
|
||||
@@ -207,7 +238,7 @@ impl aml::Handler for AmlPhysMemHandler {
|
||||
}
|
||||
log::error!("failed to write u16 {:#x}", address);
|
||||
}
|
||||
fn write_u32(&mut self, address: usize, value: u32) {
|
||||
fn write_u32(&self, address: usize, value: u32) {
|
||||
log::trace!("write u32 {:X} = {:X}", address, value);
|
||||
if let Ok(mut page_cache) = self.page_cache.lock() {
|
||||
if page_cache.write_to_phys::<u32>(address, value).is_ok() {
|
||||
@@ -216,7 +247,7 @@ impl aml::Handler for AmlPhysMemHandler {
|
||||
}
|
||||
log::error!("failed to write u32 {:#x}", address);
|
||||
}
|
||||
fn write_u64(&mut self, address: usize, value: u64) {
|
||||
fn write_u64(&self, address: usize, value: u64) {
|
||||
log::trace!("write u64 {:X} = {:X}", address, value);
|
||||
if let Ok(mut page_cache) = self.page_cache.lock() {
|
||||
if page_cache.write_to_phys::<u64>(address, value).is_ok() {
|
||||
@@ -282,25 +313,56 @@ impl aml::Handler for AmlPhysMemHandler {
|
||||
log::error!("cannot write 0x{value:08X} to port 0x{port:04X}");
|
||||
}
|
||||
|
||||
fn read_pci_u8(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16) -> u8 {
|
||||
log::error!("read pci u8 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}");
|
||||
fn read_pci_u8(&self, addr: PciAddress, off: u16) -> u8 {
|
||||
log::error!("read pci u8 {addr}@{off:04X}");
|
||||
0
|
||||
}
|
||||
fn read_pci_u16(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16) -> u16 {
|
||||
log::error!("read pci u16 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}");
|
||||
fn read_pci_u16(&self, addr: PciAddress, off: u16) -> u16 {
|
||||
log::error!("read pci u16 {addr}@{off:04X}");
|
||||
0
|
||||
}
|
||||
fn read_pci_u32(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16) -> u32 {
|
||||
log::error!("read pci u32 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}");
|
||||
fn read_pci_u32(&self, addr: PciAddress, off: u16) -> u32 {
|
||||
log::error!("read pci u32 {addr}@{off:04X}");
|
||||
0
|
||||
}
|
||||
fn write_pci_u8(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16, value: u8) {
|
||||
log::error!("write pci u8 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}={value:02X}");
|
||||
fn write_pci_u8(&self, addr: PciAddress, off: u16, value: u8) {
|
||||
log::error!("write pci u8 {addr}@{off:04X}={value:02X}");
|
||||
}
|
||||
fn write_pci_u16(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16, value: u16) {
|
||||
log::error!("write pci u16 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}={value:04X}");
|
||||
fn write_pci_u16(&self, addr: PciAddress, off: u16, value: u16) {
|
||||
log::error!("write pci u16 {addr}@{off:04X}={value:04X}");
|
||||
}
|
||||
fn write_pci_u32(&self, seg: u16, bus: u8, dev: u8, func: u8, off: u16, value: u32) {
|
||||
log::error!("write pci u32 {seg:04X}:{bus:02X}:{dev:02X}.{func:01X}@{off:04X}={value:08X}");
|
||||
fn write_pci_u32(&self, addr: PciAddress, off: u16, value: u32) {
|
||||
log::error!("write pci u32 {addr}@{off:04X}={value:08X}");
|
||||
}
|
||||
|
||||
fn nanos_since_boot(&self) -> u64 {
|
||||
let ts = libredox::call::clock_gettime(libredox::flag::CLOCK_MONOTONIC)
|
||||
.expect("failed to get time");
|
||||
(ts.tv_sec as u64) * 1_000_000_000 + (ts.tv_nsec as u64)
|
||||
}
|
||||
|
||||
fn stall(&self, microseconds: u64) {
|
||||
let start = std::time::Instant::now();
|
||||
while start.elapsed().as_micros() < microseconds.into() {
|
||||
std::hint::spin_loop();
|
||||
}
|
||||
}
|
||||
|
||||
fn sleep(&self, milliseconds: u64) {
|
||||
std::thread::sleep(std::time::Duration::from_millis(milliseconds));
|
||||
}
|
||||
|
||||
fn create_mutex(&self) -> Handle {
|
||||
log::warn!("TODO: Handler::create_mutex");
|
||||
Handle(0)
|
||||
}
|
||||
|
||||
fn acquire(&self, mutex: Handle, timeout: u16) -> Result<(), AmlError> {
|
||||
log::warn!("TODO: Handler::aquire");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn release(&self, mutex: Handle) {
|
||||
log::warn!("TODO: Handler::release");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user