pub unsafe trait AcpiHandler {
Show 45 methods
// Required methods
fn get_root_pointer(&mut self) -> AcpiPhysicalAddress;
unsafe fn map_memory(
&mut self,
physical_address: AcpiPhysicalAddress,
length: usize,
) -> Result<*mut u8, AcpiMappingError>;
unsafe fn unmap_memory(&mut self, address: *mut u8, length: usize);
fn get_physical_address(
&mut self,
logical_address: *mut u8,
) -> Result<Option<AcpiPhysicalAddress>, AcpiError>;
unsafe fn read_physical_u8(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u8, AcpiError>;
unsafe fn read_physical_u16(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u16, AcpiError>;
unsafe fn read_physical_u32(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u32, AcpiError>;
unsafe fn read_physical_u64(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u64, AcpiError>;
unsafe fn write_physical_u8(
&mut self,
address: AcpiPhysicalAddress,
value: u8,
) -> Result<(), AcpiError>;
unsafe fn write_physical_u16(
&mut self,
address: AcpiPhysicalAddress,
value: u16,
) -> Result<(), AcpiError>;
unsafe fn write_physical_u32(
&mut self,
address: AcpiPhysicalAddress,
value: u32,
) -> Result<(), AcpiError>;
unsafe fn write_physical_u64(
&mut self,
address: AcpiPhysicalAddress,
value: u64,
) -> Result<(), AcpiError>;
unsafe fn readable(&mut self, pointer: *mut c_void, length: usize) -> bool;
unsafe fn writable(&mut self, pointer: *mut c_void, length: usize) -> bool;
unsafe fn install_interrupt_handler(
&mut self,
interrupt_number: u32,
callback: AcpiInterruptCallback,
) -> Result<(), AcpiError>;
unsafe fn remove_interrupt_handler(
&mut self,
interrupt_number: u32,
tag: AcpiInterruptCallbackTag,
) -> Result<(), AcpiError>;
fn get_thread_id(&mut self) -> u64;
unsafe fn execute(
&mut self,
callback: AcpiThreadCallback,
) -> Result<(), AcpiError>;
unsafe fn wait_for_events(&mut self);
unsafe fn sleep(&mut self, millis: usize);
unsafe fn stall(&mut self, micros: usize);
fn printf(&mut self, message: Arguments<'_>);
unsafe fn read_port_u8(
&mut self,
address: AcpiIoAddress,
) -> Result<u8, AcpiError>;
unsafe fn read_port_u16(
&mut self,
address: AcpiIoAddress,
) -> Result<u16, AcpiError>;
unsafe fn read_port_u32(
&mut self,
address: AcpiIoAddress,
) -> Result<u32, AcpiError>;
unsafe fn write_port_u8(
&mut self,
address: AcpiIoAddress,
value: u8,
) -> Result<(), AcpiError>;
unsafe fn write_port_u16(
&mut self,
address: AcpiIoAddress,
value: u16,
) -> Result<(), AcpiError>;
unsafe fn write_port_u32(
&mut self,
address: AcpiIoAddress,
value: u32,
) -> Result<(), AcpiError>;
unsafe fn get_timer(&mut self) -> u64;
unsafe fn read_pci_config_u8(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u8, AcpiError>;
unsafe fn read_pci_config_u16(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u16, AcpiError>;
unsafe fn read_pci_config_u32(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u32, AcpiError>;
unsafe fn read_pci_config_u64(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u64, AcpiError>;
unsafe fn write_pci_config_u8(
&mut self,
id: AcpiPciId,
register: usize,
value: u8,
) -> Result<(), AcpiError>;
unsafe fn write_pci_config_u16(
&mut self,
id: AcpiPciId,
register: usize,
value: u16,
) -> Result<(), AcpiError>;
unsafe fn write_pci_config_u32(
&mut self,
id: AcpiPciId,
register: usize,
value: u32,
) -> Result<(), AcpiError>;
unsafe fn write_pci_config_u64(
&mut self,
id: AcpiPciId,
register: usize,
value: u64,
) -> Result<(), AcpiError>;
unsafe fn signal_fatal(
&mut self,
fatal_type: u32,
code: u32,
argument: u32,
) -> Result<(), AcpiError>;
unsafe fn signal_breakpoint(
&mut self,
message: &str,
) -> Result<(), AcpiError>;
// Provided methods
unsafe fn initialize(&mut self) -> Result<(), AcpiError> { ... }
unsafe fn terminate(&mut self) -> Result<(), AcpiError> { ... }
unsafe fn predefined_override(
&mut self,
predefined_object: &AcpiPredefinedNames<'_>,
) -> Result<Option<String>, AcpiError> { ... }
unsafe fn table_override(
&mut self,
table: &AcpiTableHeader<'_>,
) -> Result<Option<AcpiTableHeader<'_>>, AcpiError> { ... }
unsafe fn physical_table_override(
&mut self,
table: &AcpiTableHeader<'_>,
) -> Result<Option<(AcpiPhysicalAddress, u32)>, AcpiError> { ... }
unsafe fn enter_sleep(
&mut self,
state: u8,
reg_a: u32,
reg_b: u32,
) -> Result<(), AcpiError> { ... }
}
Expand description
The interface between ACPICA and the host OS. Each method in this trait is mapped to an AcpiOs...
function,
which will be called on the object registered with register_interface
.
§Optional Methods
Some methods are only present if certain features of the crate are enabled or disabled:
create_cache
,delete_cache
,purge_cache
,acquire_object
, andrelease_object
are only present if the crate featurebuiltin_cache
is disabledcreate_lock
,delete_lock
,acquire_lock
, andrelease_lock
are only present if the crate featurebuiltin_lock
is disabledcreate_semaphore
,delete_semaphore
,wait_semaphore
, andsignal_semaphore
are only present if the crate featurebuiltin_semaphore
is disabled
§Safety
This trait is unsafe to implement because some functions have restrictions on their implementation as well as their caller. This is indicated per method under the heading “Implementation Safety”.
As well as this, it is undefined behaviour for a panic to unwind across an FFI boundary from rust code to C code.
Users of this library who have panic unwinding enabled are responsible for ensuring that a panic never unwinds out of a method in this trait.
If the OS is built with panic=abort
, this is not an issue.
Required Methods§
Sourcefn get_root_pointer(&mut self) -> AcpiPhysicalAddress
fn get_root_pointer(&mut self) -> AcpiPhysicalAddress
Gets a physical pointer to the RSDP.
§Implementation Safety
- The returned pointer must point to the system’s RSDP.
Sourceunsafe fn map_memory(
&mut self,
physical_address: AcpiPhysicalAddress,
length: usize,
) -> Result<*mut u8, AcpiMappingError>
unsafe fn map_memory( &mut self, physical_address: AcpiPhysicalAddress, length: usize, ) -> Result<*mut u8, AcpiMappingError>
Map length
bytes of physical memory starting at physical_address
, and return the virtual address where they have been mapped.
§Safety
- This function is only called from
AcpiOsMapMemory
- The memory at
physical_address
is valid for writes forlength
bytes
§Implementation Safety
- The memory must stay mapped until
unmap_memory
is called.
Sourceunsafe fn unmap_memory(&mut self, address: *mut u8, length: usize)
unsafe fn unmap_memory(&mut self, address: *mut u8, length: usize)
Unmap length
pages bytes of memory which were previously allocated with map_memory
§Safety
- This function is only called from
AcpiOsUnmapMemory
address
is a pointer which was previously returned frommap_memory
Sourcefn get_physical_address(
&mut self,
logical_address: *mut u8,
) -> Result<Option<AcpiPhysicalAddress>, AcpiError>
fn get_physical_address( &mut self, logical_address: *mut u8, ) -> Result<Option<AcpiPhysicalAddress>, AcpiError>
Translate a logical address to the physical address it’s mapped to.
§Return value
Ok(Some(address))
: The translation was successfulOk(None)
: The translation was successful but the virtual address is not mappedErr(e)
: There was an error carrying out the translation
Sourceunsafe fn read_physical_u8(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u8, AcpiError>
unsafe fn read_physical_u8( &mut self, address: AcpiPhysicalAddress, ) -> Result<u8, AcpiError>
Read a u8
from the given physical address.
§Safety
- The given physical address is valid for reads
- This method is only called from
AcpiOsReadMemory
§Implementation Safety
- As this read could be from memory mapped IO, the read should be volatile
If you want your implementation of this method to look the same as read_physical_u16
, ..._u32
, and ..._u64
,
Read the documentation for these methods before implementing this one as the size of the type makes a difference in implementing the method soundly.
Sourceunsafe fn read_physical_u16(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u16, AcpiError>
unsafe fn read_physical_u16( &mut self, address: AcpiPhysicalAddress, ) -> Result<u16, AcpiError>
Read a u16
from the given physical address.
§Safety
- The given physical address is valid for reads
- This method is only called from
AcpiOsReadMemory
§Implementation Safety
- As this read could be from memory mapped IO, the read should be volatile
- The physical address may not be 2 byte aligned, so the read should be unaligned
These requirements can be difficult to satisfy at the same time.
If you are alright with using unstable compiler intrinsics, the core::intrinsics::unaligned_volatile_load
method.
Otherwise, it is possible to read the data as a [u8; 2]
and then transmute it into a u16
.
Sourceunsafe fn read_physical_u32(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u32, AcpiError>
unsafe fn read_physical_u32( &mut self, address: AcpiPhysicalAddress, ) -> Result<u32, AcpiError>
Read a u32
from the given physical address.
§Safety
- The given physical address is valid for reads
- This method is only called from
AcpiOsReadMemory
§Implementation Safety
- As this read could be from memory mapped IO, the read should be volatile
- The physical address may not be 4 byte aligned, so the read should be unaligned
These requirements can be difficult to satisfy at the same time.
If you are alright with using unstable compiler intrinsics, the core::intrinsics::unaligned_volatile_load
method.
Otherwise, it is possible to read the data as a [u8; 4]
and then transmute it into a u32
.
Sourceunsafe fn read_physical_u64(
&mut self,
address: AcpiPhysicalAddress,
) -> Result<u64, AcpiError>
unsafe fn read_physical_u64( &mut self, address: AcpiPhysicalAddress, ) -> Result<u64, AcpiError>
Read a u64
from the given physical address.
§Safety
- The given physical address is valid for reads
- This method is only called from
AcpiOsReadMemory
§Implementation Safety
- As this read could be from memory mapped IO, the read should be volatile
- The physical address may not be 8 byte aligned, so the read should be unaligned
These requirements can be difficult to satisfy at the same time.
If you are alright with using unstable compiler intrinsics, the core::intrinsics::unaligned_volatile_load
method.
Otherwise, it is possible to read the data as a [u8; 8]
and then transmute it into a u64
.
Sourceunsafe fn write_physical_u8(
&mut self,
address: AcpiPhysicalAddress,
value: u8,
) -> Result<(), AcpiError>
unsafe fn write_physical_u8( &mut self, address: AcpiPhysicalAddress, value: u8, ) -> Result<(), AcpiError>
Read a u8
from the given physical address.
§Safety
- The given physical address is valid for writes
- This method is only called from
AcpiOsWriteMemory
§Implementation Safety
- As this read could be to memory mapped IO, the write should be volatile
If you want your implementation of this method to look the same as write_physical_u16
, ..._u32
, and ..._u64
,
Read the documentation for these methods before implementing this one as the size of the type makes a difference in implementing the method soundly.
Sourceunsafe fn write_physical_u16(
&mut self,
address: AcpiPhysicalAddress,
value: u16,
) -> Result<(), AcpiError>
unsafe fn write_physical_u16( &mut self, address: AcpiPhysicalAddress, value: u16, ) -> Result<(), AcpiError>
Read a u16
from the given physical address.
§Safety
- The given physical address is valid for writes
- This method is only called from
AcpiOsWriteMemory
§Implementation Safety
- As this read could be to memory mapped IO, the write should be volatile
- The physical address may not be 2 byte aligned, so the read should be unaligned
These requirements can be difficult to satisfy at the same time.
If you are alright with using unstable compiler intrinsics, the core::intrinsics::unaligned_volatile_store
method.
Otherwise, it is possible to transmute the data into a [u8; 2]
before writing it.
Sourceunsafe fn write_physical_u32(
&mut self,
address: AcpiPhysicalAddress,
value: u32,
) -> Result<(), AcpiError>
unsafe fn write_physical_u32( &mut self, address: AcpiPhysicalAddress, value: u32, ) -> Result<(), AcpiError>
Read a u32
from the given physical address.
§Safety
- The given physical address is valid for writes
- This method is only called from
AcpiOsWriteMemory
§Implementation Safety
- As this read could be to memory mapped IO, the write should be volatile
- The physical address may not be 4 byte aligned, so the read should be unaligned
These requirements can be difficult to satisfy at the same time.
If you are alright with using unstable compiler intrinsics, the core::intrinsics::unaligned_volatile_store
method.
Otherwise, it is possible to transmute the data into a [u8; 4]
before writing it.
Sourceunsafe fn write_physical_u64(
&mut self,
address: AcpiPhysicalAddress,
value: u64,
) -> Result<(), AcpiError>
unsafe fn write_physical_u64( &mut self, address: AcpiPhysicalAddress, value: u64, ) -> Result<(), AcpiError>
Read a u64
from the given physical address.
§Safety
- The given physical address is valid for writes
- This method is only called from
AcpiOsWriteMemory
§Implementation Safety
- As this read could be to memory mapped IO, the write should be volatile
- The physical address may not be 8 byte aligned, so the read should be unaligned
These requirements can be difficult to satisfy at the same time.
If you are alright with using unstable compiler intrinsics, the core::intrinsics::unaligned_volatile_store
method.
Otherwise, it is possible to transmute the data into a [u8; 8]
before writing it.
Sourceunsafe fn readable(&mut self, pointer: *mut c_void, length: usize) -> bool
unsafe fn readable(&mut self, pointer: *mut c_void, length: usize) -> bool
Check whether pointer
is valid for reads of length
bytes.
This is only in terms of the memory being mapped with the right permissions and valid, not in terms of rust’s ownership rules.
§Return Value
true
if the pointer is valid forlength
bytes of readsfalse
if the pointer is not valid
§Safety
- This method is only called from
AcpiOsReadable
Sourceunsafe fn writable(&mut self, pointer: *mut c_void, length: usize) -> bool
unsafe fn writable(&mut self, pointer: *mut c_void, length: usize) -> bool
Check whether pointer
is valid for writes of length
bytes.
This is only in terms of the memory being mapped with the right permissions and valid, not in terms of rust’s ownership rules.
§Return Value
true
if the pointer is valid forlength
bytes of writesfalse
if the pointer is not valid
§Safety
- This method is only called from
AcpiOsWritable
Sourceunsafe fn install_interrupt_handler(
&mut self,
interrupt_number: u32,
callback: AcpiInterruptCallback,
) -> Result<(), AcpiError>
unsafe fn install_interrupt_handler( &mut self, interrupt_number: u32, callback: AcpiInterruptCallback, ) -> Result<(), AcpiError>
Register the given callback
to run in the interrupt handler for the given interrupt_number
§Safety
- This method is only called from
AcpiOsInstallInterruptHandler
Sourceunsafe fn remove_interrupt_handler(
&mut self,
interrupt_number: u32,
tag: AcpiInterruptCallbackTag,
) -> Result<(), AcpiError>
unsafe fn remove_interrupt_handler( &mut self, interrupt_number: u32, tag: AcpiInterruptCallbackTag, ) -> Result<(), AcpiError>
Remove an interrupt handler which was previously registered with install_interrupt_handler
.
The passed tag
should be compared to each registered handler using is_tag
, and whichever handler returns true
should be removed.
If no handler is found, AcpiError::NotExist
should be returned.
§Safety
- This method is only called from
AcpiOsRemoveInterruptHandler
§Implementation Safety
- If the handler is found, it must be removed and not called again and
Ok
returned. - If the handler is not found,
AcpiError::NotExist
must be returned.
Sourcefn get_thread_id(&mut self) -> u64
fn get_thread_id(&mut self) -> u64
Sourceunsafe fn execute(
&mut self,
callback: AcpiThreadCallback,
) -> Result<(), AcpiError>
unsafe fn execute( &mut self, callback: AcpiThreadCallback, ) -> Result<(), AcpiError>
Run the callback in a new kernel thread. The call
method of the given callback
must be run, and then the kernel thread should be destroyed.
The OS should keep track of which kernel threads were spawned using this method so that wait_for_events
can be implemented correctly.
§Safety
- This method is only called from
AcpiOsExecute
§Return value
Ok(())
: The thread is queued and ready to executeErr(e)
: There was an error creating the thread
Sourceunsafe fn wait_for_events(&mut self)
unsafe fn wait_for_events(&mut self)
Sourceunsafe fn stall(&mut self, micros: usize)
unsafe fn stall(&mut self, micros: usize)
Loop for the given number of microseconds, without sleeping the kernel thread
§Safety
- This method is only called from
AcpiOsStall
§Implementation Safety
- This method must not return until the given number of microseconds has elapsed. The OS should attempt not to overshoot the target time by too much.
Sourcefn printf(&mut self, message: Arguments<'_>)
fn printf(&mut self, message: Arguments<'_>)
Print a message to the kernel’s output.
Multiple calls to printf
may be used to print a single line of output, and ACPICA will write a newline character at the end of each line.
For this reason, the OS should not add its own newline characters or this could break formatting.
If your kernel has a macro which behaves like the standard print!
macro, the implementation of this method can be as simple as
fn printf(&mut self, message: core::fmt::Arguments) {
print!("{message}");
}
Sourceunsafe fn read_port_u8(
&mut self,
address: AcpiIoAddress,
) -> Result<u8, AcpiError>
unsafe fn read_port_u8( &mut self, address: AcpiIoAddress, ) -> Result<u8, AcpiError>
Sourceunsafe fn read_port_u16(
&mut self,
address: AcpiIoAddress,
) -> Result<u16, AcpiError>
unsafe fn read_port_u16( &mut self, address: AcpiIoAddress, ) -> Result<u16, AcpiError>
Sourceunsafe fn read_port_u32(
&mut self,
address: AcpiIoAddress,
) -> Result<u32, AcpiError>
unsafe fn read_port_u32( &mut self, address: AcpiIoAddress, ) -> Result<u32, AcpiError>
Sourceunsafe fn write_port_u8(
&mut self,
address: AcpiIoAddress,
value: u8,
) -> Result<(), AcpiError>
unsafe fn write_port_u8( &mut self, address: AcpiIoAddress, value: u8, ) -> Result<(), AcpiError>
Sourceunsafe fn write_port_u16(
&mut self,
address: AcpiIoAddress,
value: u16,
) -> Result<(), AcpiError>
unsafe fn write_port_u16( &mut self, address: AcpiIoAddress, value: u16, ) -> Result<(), AcpiError>
Sourceunsafe fn write_port_u32(
&mut self,
address: AcpiIoAddress,
value: u32,
) -> Result<(), AcpiError>
unsafe fn write_port_u32( &mut self, address: AcpiIoAddress, value: u32, ) -> Result<(), AcpiError>
Sourceunsafe fn read_pci_config_u8(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u8, AcpiError>
unsafe fn read_pci_config_u8( &mut self, id: AcpiPciId, register: usize, ) -> Result<u8, AcpiError>
Sourceunsafe fn read_pci_config_u16(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u16, AcpiError>
unsafe fn read_pci_config_u16( &mut self, id: AcpiPciId, register: usize, ) -> Result<u16, AcpiError>
Sourceunsafe fn read_pci_config_u32(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u32, AcpiError>
unsafe fn read_pci_config_u32( &mut self, id: AcpiPciId, register: usize, ) -> Result<u32, AcpiError>
Sourceunsafe fn read_pci_config_u64(
&mut self,
id: AcpiPciId,
register: usize,
) -> Result<u64, AcpiError>
unsafe fn read_pci_config_u64( &mut self, id: AcpiPciId, register: usize, ) -> Result<u64, AcpiError>
Sourceunsafe fn write_pci_config_u8(
&mut self,
id: AcpiPciId,
register: usize,
value: u8,
) -> Result<(), AcpiError>
unsafe fn write_pci_config_u8( &mut self, id: AcpiPciId, register: usize, value: u8, ) -> Result<(), AcpiError>
Sourceunsafe fn write_pci_config_u16(
&mut self,
id: AcpiPciId,
register: usize,
value: u16,
) -> Result<(), AcpiError>
unsafe fn write_pci_config_u16( &mut self, id: AcpiPciId, register: usize, value: u16, ) -> Result<(), AcpiError>
Sourceunsafe fn write_pci_config_u32(
&mut self,
id: AcpiPciId,
register: usize,
value: u32,
) -> Result<(), AcpiError>
unsafe fn write_pci_config_u32( &mut self, id: AcpiPciId, register: usize, value: u32, ) -> Result<(), AcpiError>
Sourceunsafe fn write_pci_config_u64(
&mut self,
id: AcpiPciId,
register: usize,
value: u64,
) -> Result<(), AcpiError>
unsafe fn write_pci_config_u64( &mut self, id: AcpiPciId, register: usize, value: u64, ) -> Result<(), AcpiError>
Provided Methods§
Sourceunsafe fn initialize(&mut self) -> Result<(), AcpiError>
unsafe fn initialize(&mut self) -> Result<(), AcpiError>
Method called when ACPICA initialises. The default implementation of this method is a no-op.
§Safety
- This method is only called from
AcpiOsInitialize
Sourceunsafe fn terminate(&mut self) -> Result<(), AcpiError>
unsafe fn terminate(&mut self) -> Result<(), AcpiError>
Method called when ACPICA shuts down. The default implementation of this method is a no-op
§Safety
- This method is only called from
AcpiOsTerminate
- After this method is called, the object will be dropped and no other methods will be called
Sourceunsafe fn predefined_override(
&mut self,
predefined_object: &AcpiPredefinedNames<'_>,
) -> Result<Option<String>, AcpiError>
unsafe fn predefined_override( &mut self, predefined_object: &AcpiPredefinedNames<'_>, ) -> Result<Option<String>, AcpiError>
Sourceunsafe fn table_override(
&mut self,
table: &AcpiTableHeader<'_>,
) -> Result<Option<AcpiTableHeader<'_>>, AcpiError>
unsafe fn table_override( &mut self, table: &AcpiTableHeader<'_>, ) -> Result<Option<AcpiTableHeader<'_>>, AcpiError>
Allows the OS to override an ACPI table using a logical address.
This method is called once on each ACPI table in the order they are listed in the DSDT/XSDT,
and when tables are loaded by the Load
AML instruction. To keep the original table, return Ok(None)
.
To override the table using a physical address instead, use physical_table_override
§Safety
- This method is only called from
AcpiOsTableOverride
Sourceunsafe fn physical_table_override(
&mut self,
table: &AcpiTableHeader<'_>,
) -> Result<Option<(AcpiPhysicalAddress, u32)>, AcpiError>
unsafe fn physical_table_override( &mut self, table: &AcpiTableHeader<'_>, ) -> Result<Option<(AcpiPhysicalAddress, u32)>, AcpiError>
Allows the OS to override an ACPI table using a physical address.
To keep the original table, return Ok(None)
§Safety
- This method is only called from
AcpiOsPhysicalTableOverride
§Implementation Safety
- The returned physical address must point to a valid new ACPI table with the returned length
- The memory indicated by the returned pointer and length is now managed by ACPICA and must not be written to while ACPICA is active
Sourceunsafe fn enter_sleep(
&mut self,
state: u8,
reg_a: u32,
reg_b: u32,
) -> Result<(), AcpiError>
unsafe fn enter_sleep( &mut self, state: u8, reg_a: u32, reg_b: u32, ) -> Result<(), AcpiError>
Called just before the system enters a sleep state. This method allows the OS to do any final processing before entering the new state. The default implementation is a no-op.
§Safety
- This method is only called from
AcpiOsEnterSleep