### Get Parsed HPET Information Source: https://context7.com/rust-osdev/acpi/llms.txt Provides a parsed view of High Precision Event Timer (HPET) capabilities. Requires the `acpi` crate and a `tables` object. ```rust use acpi::sdt::hpet::HpetInfo; let hpet_info = HpetInfo::new(&tables) .expect("Failed to get HPET info"); println!("HPET Information:"); println!(" Hardware revision: {}", hpet_info.hardware_rev); println!(" Number of comparators: {}", hpet_info.num_comparators); println!(" 64-bit main counter: {}", hpet_info.main_counter_is_64bits); println!(" Legacy IRQ capable: {}", hpet_info.legacy_irq_capable); println!(" Base address: {:#x}", hpet_info.base_address); println!(" Clock tick unit: {} femtoseconds", hpet_info.clock_tick_unit); println!(" Page protection: {:?}", hpet_info.page_protection); ``` -------------------------------- ### Initialize AcpiPlatform for High-Level Access Source: https://context7.com/rust-osdev/acpi/llms.txt Initializes AcpiPlatform to parse ACPI tables and access structured platform information like interrupt models and processor topology. Requires the `alloc` feature and a full `Handler` implementation. ```rust use acpi::platform::{AcpiPlatform, InterruptModel, ProcessorState}; // AcpiPlatform requires the alloc feature and full Handler implementation let platform = AcpiPlatform::new(tables, handler.clone()) .expect("Failed to create AcpiPlatform"); println!("Power profile: {:?}", platform.power_profile); println!("SCI Interrupt: {}", platform.sci_interrupt); // Access interrupt model match &platform.interrupt_model { InterruptModel::Apic(apic) => { println!("Using APIC model:"); println!(" Local APIC address: {:#x}", apic.local_apic_address); println!(" Number of I/O APICs: {}", apic.io_apics.len()); for ioapic in &apic.io_apics { println!(" I/O APIC {} at {:#x}, GSI base: {}", ioapic.id, ioapic.address, ioapic.global_system_interrupt_base); } for iso in &apic.interrupt_source_overrides { println!(" IRQ {} -> GSI {}, {:?}, {:?}", iso.isa_source, iso.global_system_interrupt, iso.polarity, iso.trigger_mode); } } InterruptModel::Unknown => { println!("Unknown interrupt model (likely legacy PIC)"); } } // Access processor information if let Some(ref proc_info) = platform.processor_info { println!("Boot processor: APIC ID {}", proc_info.boot_processor.local_apic_id); for ap in &proc_info.application_processors { let state = match ap.state { ProcessorState::Disabled => "disabled", ProcessorState::WaitingForSipi => "waiting for SIPI", ProcessorState::Running => "running", }; println!(" AP {} - APIC ID: {}, State: {}", ap.processor_uid, ap.local_apic_id, state); } } // Access PM Timer if available if let Some(ref pm_timer) = platform.pm_timer { println!("PM Timer: {:?}, 32-bit: {}", pm_timer.base, pm_timer.supports_32bit); } ``` -------------------------------- ### Wake Application Processors Source: https://context7.com/rust-osdev/acpi/llms.txt Utilizes the Multiprocessor Wakeup Mailbox mechanism to initialize APs from the boot processor. ```rust // Wake up an AP using the multiprocessor wakeup mechanism // The wakeup_vector is where the AP will start executing let apic_id: u32 = 1; // Target AP's APIC ID let wakeup_vector: u64 = 0x8000; // Physical address of AP startup code let timeout_loops: u64 = 1000000; unsafe { platform.wake_aps(apic_id, wakeup_vector, timeout_loops) .expect("Failed to wake AP"); } ``` -------------------------------- ### Initialize and Use AML Interpreter Source: https://context7.com/rust-osdev/acpi/llms.txt Creates and initializes an AML interpreter to execute ACPI bytecode from DSDT and SSDTs. It manages the AML namespace and allows evaluation of methods and objects. Use `evaluate_if_present` to safely check for object existence before evaluation. ```rust use acpi::aml::{Interpreter, namespace::AmlName}; use alloc::vec; use core::str::FromStr; // Create interpreter from platform (loads DSDT and all SSDTs automatically) let interpreter = Interpreter::new_from_platform(&platform) .expect("Failed to create AML interpreter"); // Initialize the namespace (runs _STA and _INI methods for devices) interpreter.initialize_namespace(); // Evaluate an AML method or read an object let path = AmlName::from_str(\"\\_SB.PCI0\").unwrap(); match interpreter.evaluate(path.clone(), vec![]) { Ok(result) => println!("Result: {:?}", result), Err(e) => println!("Error evaluating path: {:?}", e), } // Check if an object exists before evaluating let optional_path = AmlName::from_str(\"\\_SB.PCI0._CRS\").unwrap(); if let Ok(Some(result)) = interpreter.evaluate_if_present(optional_path, vec![]) { println!("_CRS result: {:?}", result); } ``` -------------------------------- ### Search for RSDP on BIOS Systems in Rust Source: https://context7.com/rust-osdev/acpi/llms.txt Searches for the RSDP (Root System Description Pointer) on BIOS systems using the implemented `Handler`. This is the entry point for ACPI tables. Ensure the `Handler` implementation is complete before calling. ```rust // Search for RSDP on BIOS systems let handler = MyHandler; let rsdp = unsafe { Rsdp::search_for_on_bios(handler.clone()) } .expect("Failed to find RSDP"); // Access RSDP information let revision = rsdp.revision(); let oem_id = rsdp.oem_id().unwrap(); println!("ACPI Revision: {}, OEM: {}", revision, oem_id); ``` -------------------------------- ### Find and Read Common ACPI Tables Source: https://context7.com/rust-osdev/acpi/llms.txt Searches for and accesses common ACPI tables such as FADT, HPET, and DSDT. Requires the `acpi` crate and a `tables` object. ```rust use acpi::sdt::{Signature, fadt::Fadt, hpet::HpetTable}; // Find the FADT (Fixed ACPI Description Table) if let Some(fadt) = tables.find_table::() { println!("FADT found!"); println!(" Power profile: {:?}", fadt.power_profile()); println!(" SCI Interrupt: {}", fadt.sci_interrupt); // Get DSDT address if let Ok(dsdt_addr) = fadt.dsdt_address() { println!(" DSDT at: {:#x}", dsdt_addr); } // Check power management timer if let Ok(Some(pm_timer)) = fadt.pm_timer_block() { println!(" PM Timer at: {:#x}", pm_timer.address); } } // Find HPET table if let Some(hpet) = tables.find_table::() { println!("HPET base address: {:#x}", hpet.base_address.address); } // Get DSDT for AML interpretation let dsdt = tables.dsdt().expect("Failed to get DSDT"); println!("DSDT at {:#x}, {} bytes, revision {}", dsdt.phys_address, dsdt.length, dsdt.revision); // Iterate over all SSDTs for ssdt in tables.ssdts() { println!("SSDT at {:#x}, {} bytes", ssdt.phys_address, ssdt.length); } ``` -------------------------------- ### Enter ACPI Mode for Power Management Source: https://context7.com/rust-osdev/acpi/llms.txt Transfers control of power management hardware from firmware (SMI) to the operating system (SCI). This is a prerequisite for handling power events. Ensure proper event handling is set up before entering ACPI mode. ```rust use acpi::platform::AcpiMode; // Check current mode let mode = platform.read_mode().expect("Failed to read ACPI mode"); println!("Current mode: {:?}", mode); if mode == AcpiMode::Legacy { // Enter ACPI mode - WARNING: requires proper event handling setup! platform.enter_acpi_mode().expect("Failed to enter ACPI mode"); println!("Entered ACPI mode"); } // Initialize event registers (disable all fixed events initially) platform.initialize_events().expect("Failed to initialize events"); ``` -------------------------------- ### Parse Resource Descriptors Source: https://context7.com/rust-osdev/acpi/llms.txt Extracts and iterates over device resources like IRQs, I/O ports, and memory ranges from _CRS or _PRS buffers. ```rust use acpi::aml::resource::{resource_descriptor_list, Resource}; use acpi::aml::object::Object; use alloc::vec; // Assume we have a _CRS buffer from evaluating a device's _CRS method let crs_path = AmlName::from_str("\\_SB.PCI0.ISA.KBD._CRS").unwrap(); let crs_buffer = interpreter.evaluate(crs_path, vec![]) .expect("Failed to evaluate _CRS"); let resources = resource_descriptor_list(crs_buffer) .expect("Failed to parse resource descriptors"); for resource in resources { match resource { Resource::Irq(irq) => { println!("IRQ: {}, {:?}, {:?}, shared: {}", irq.irq, irq.trigger, irq.polarity, irq.is_shared); } Resource::IOPort(io) => { println!("I/O Port: {:#x}-{:#x}, length: {}", io.memory_range.0, io.memory_range.1, io.range_length); } Resource::MemoryRange(mem) => { println!("Memory Range: {:?}", mem); } Resource::AddressSpace(addr) => { println!("Address Space: {:?} {:#x}-{:#x}, length: {:#x}", addr.resource_type, addr.address_range.0, addr.address_range.1, addr.length); } Resource::Dma(dma) => { println!("DMA: channel mask {:#x}, {:?}", dma.channel_mask, dma.supported_speeds); } } } ``` -------------------------------- ### Read MCFG Table for PCI Express Configuration Source: https://context7.com/rust-osdev/acpi/llms.txt Parses the MCFG table to retrieve base addresses for PCI Express memory-mapped configuration space across different segments. Iterates through each entry to display segment information. ```rust use acpi::sdt::mcfg::Mcfg; if let Some(mcfg) = tables.find_table::() { println!("PCI Express Configuration Regions:"); for entry in mcfg.entries() { println!(" Segment {}: Base {:#x}, Bus range {}-{}", entry.pci_segment_group, entry.base_address, entry.bus_number_start, entry.bus_number_end); } } ``` -------------------------------- ### Parse MADT for Interrupt Controller Details Source: https://context7.com/rust-osdev/acpi/llms.txt Parses the Multiple APIC Description Table (MADT) to extract information about Local APICs, I/O APICs, and interrupt overrides. Requires the `acpi` crate and a `tables` object. ```rust use acpi::sdt::madt::{Madt, MadtEntry}; if let Some(madt) = tables.find_table::() { println!("Local APIC address: {:#x}", madt.local_apic_address); println!("Supports legacy 8259 PIC: {}", madt.supports_8259()); // Iterate over MADT entries for entry in madt.get().entries() { match entry { MadtEntry::LocalApic(lapic) => { println!("Local APIC - Processor ID: {}, APIC ID: {}, Flags: {:#x}", lapic.processor_id, lapic.apic_id, lapic.flags); } MadtEntry::IoApic(ioapic) => { println!("I/O APIC - ID: {}, Address: {:#x}, GSI Base: {}", ioapic.io_apic_id, ioapic.io_apic_address, ioapic.global_system_interrupt_base); } MadtEntry::InterruptSourceOverride(iso) => { println!("Interrupt Override - IRQ {} -> GSI {}, Flags: {:#x}", iso.irq, iso.global_system_interrupt, iso.flags); } MadtEntry::LocalApicNmi(nmi) => { println!("Local APIC NMI - Processor: {}, LINT: {}", nmi.processor_id, nmi.nmi_line); } _ => {} } } } ``` -------------------------------- ### Parse PCI Interrupt Routing Tables Source: https://context7.com/rust-osdev/acpi/llms.txt Uses PciRoutingTable to query interrupt mappings from the _PRT object of a PCI root bridge. ```rust use acpi::aml::pci_routing::{PciRoutingTable, Pin}; use acpi::aml::namespace::AmlName; use core::str::FromStr; // Build routing table from _PRT path let prt_path = AmlName::from_str("\\_SB.PCI0._PRT").unwrap(); let routing_table = PciRoutingTable::from_prt_path(prt_path, &interpreter) .expect("Failed to parse PCI routing table"); // Look up interrupt for a specific device let device = 0x1f; // Device number let function = 0; // Function number let pin = Pin::IntA; match routing_table.route(device, function, pin, &interpreter) { Ok(irq) => { println!("Device {:02x}.{} INTA -> IRQ {}, {:?}, {:?}", device, function, irq.irq, irq.trigger, irq.polarity); } Err(e) => println!("No routing entry: {:?}", e), } ``` -------------------------------- ### Create AcpiTables from RSDP Address in Rust Source: https://context7.com/rust-osdev/acpi/llms.txt Constructs `AcpiTables` from a given RSDP physical address to enumerate all system ACPI tables. This requires a valid RSDP address and a functional `Handler` implementation. ```rust use acpi::{AcpiTables, AcpiError}; // Given RSDP physical address (e.g., from UEFI configuration table) let rsdp_address: usize = 0x000E0000; // Example address let handler = MyHandler; let tables = unsafe { AcpiTables::from_rsdp(handler.clone(), rsdp_address) } .expect("Failed to parse ACPI tables"); // Iterate over all table headers for (phys_addr, header) in tables.table_headers() { println!("Table: {} at {:#x}, length: {} bytes", header.signature, phys_addr, header.length ); } ``` -------------------------------- ### Implement ACPI Handler Trait in Rust Source: https://context7.com/rust-osdev/acpi/llms.txt Implement the `Handler` trait to interface with hardware operations like memory mapping, I/O port access, and PCI configuration space. This is required for the ACPI library to function. ```rust use acpi::{AcpiTables, Handler, PhysicalMapping, rsdp::Rsdp}; // First, implement the Handler trait for your platform #[derive(Clone)] struct MyHandler; impl Handler for MyHandler { unsafe fn map_physical_region(&self, physical_address: usize, size: usize) -> PhysicalMapping { // Map physical memory into virtual address space // Implementation depends on your OS/bootloader todo!() } fn unmap_physical_region(region: &PhysicalMapping) { // Unmap the physical region todo!() } // Implement remaining Handler methods for memory/IO access... fn read_u8(&self, address: usize) -> u8 { todo!() } fn read_u16(&self, address: usize) -> u16 { todo!() } fn read_u32(&self, address: usize) -> u32 { todo!() } fn read_u64(&self, address: usize) -> u64 { todo!() } fn write_u8(&self, address: usize, value: u8) { todo!() } fn write_u16(&self, address: usize, value: u16) { todo!() } fn write_u32(&self, address: usize, value: u32) { todo!() } fn write_u64(&self, address: usize, value: u64) { todo!() } fn read_io_u8(&self, port: u16) -> u8 { todo!() } fn read_io_u16(&self, port: u16) -> u16 { todo!() } fn read_io_u32(&self, port: u16) -> u32 { todo!() } fn write_io_u8(&self, port: u16, value: u8) { todo!() } fn write_io_u16(&self, port: u16, value: u16) { todo!() } fn write_io_u32(&self, port: u16, value: u32) { todo!() } fn read_pci_u8(&self, address: pci_types::PciAddress, offset: u16) -> u8 { todo!() } fn read_pci_u16(&self, address: pci_types::PciAddress, offset: u16) -> u16 { todo!() } fn read_pci_u32(&self, address: pci_types::PciAddress, offset: u16) -> u32 { todo!() } fn write_pci_u8(&self, address: pci_types::PciAddress, offset: u16, value: u8) { todo!() } fn write_pci_u16(&self, address: pci_types::PciAddress, offset: u16, value: u16) { todo!() } fn write_pci_u32(&self, address: pci_types::PciAddress, offset: u16, value: u32) { todo!() } fn nanos_since_boot(&self) -> u64 { todo!() } fn stall(&self, microseconds: u64) { todo!() } fn sleep(&self, milliseconds: u64) { todo!() } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.