Anonymous user
ACPICA: Difference between revisions
no edit summary
[unchecked revision] | [unchecked revision] |
No edit summary |
No edit summary |
||
(33 intermediate revisions by 10 users not shown) | |||
Line 1:
{{ACPI}}
The ACPI Component Architecture '''ACPICA''' provides an operating system (OS)-independent reference implementation of the [[ACPI|Advanced Configuration and Power Interface]]. It can be adapted to any host OS. The ACPICA code is meant to be directly integrated into the host OS, as a kernel-resident subsystem. Hosting the ACPICA requires no changes to the core ACPICA code. However, it does require a small OS-specific interface layer, which must be written specifically for each host OS.
Line 14 ⟶ 16:
==== AcpiOsTerminate ====
ACPI_STATUS AcpiOsTerminate()
This is called during ACPICA Shutdown (which is not the computer shutdown, just the
==== AcpiOsGetRootPointer ====
ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer()
ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer()
{
AcpiFindRootPointer(&Ret);
return Ret;
}
where AcpiFindRootPointer is part of ACPICA itself.
Note: The ACPI specification is highly portable specification, however, it has a static part which is generally non-portable: the location of the Root System Descriptor Pointer. This pointer may be found in many different ways depending on the chipset. On PC-compatible computers (without EFI) it is located in lower memory generally somewhere between 0x80000 and 0x100000. However, even within the PC compatible platform, an EFI-enabled board will export the RSDP to the OS on when it loads it through the EFI system tables. Other boards on server machines which are not PC-compatibles, like embedded and handheld devices which implement ACPI will again, not all be expected to position the RSDP in the same place as any other board. The RSDP is therefore located in a chipset-specific manner; From the time the OS has the RSDP, the rest of ACPI is completely portable. However, the way the RSDP is found is not. This would be the reason that the ACPICA code wouldn't try to provide routines to expressly find the RSDP in a portable manner. If your system uses EFI, locate it in the system tables or use Multiboot2 compliant loader, which provides the RSDP for you.
==== AcpiOsPredefinedOverride ====
ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
This function allows the host to override the predefined objects in the ACPI namespace. It is called when a new object is found in the
==== AcpiOsTableOverride ====
ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_TABLE_HEADER **NewTable)
The same of AcpiOsPredefinedOverride but for entire
=== Memory Management ===
Line 42 ⟶ 49:
==== AcpiOsUnmapMemory ====
void AcpiOsUnmapMemory(void *where, ACPI_SIZE length)
Unmap pages mapped using AcpiOsMapMemory.
'''Note:''' for the last two functions you might need a separated heap.
==== AcpiOsGetPhysicalAddress ====
ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
Line 65 ⟶ 73:
#define ACPI_USE_LOCAL_CACHE 1
=== Multithreading and Scheduling Services ===
To use all the features of ACPICA you need Scheduling support too.
==== AcpiOsGetThreadId ====
ACPI_THREAD_ID AcpiOsGetThreadId()
Line 72 ⟶ 80:
==== AcpiOsExecute ====
ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
Create a new
Function(Context);
==== AcpiOsSleep ====
void AcpiOsSleep(UINT64 Milliseconds)
Line 80 ⟶ 89:
void AcpiOsStall(UINT32 Microseconds)
Stall the thread for ''n'' microseconds. Note: this should not put the thread in the sleep queue. The thread should keep on running. Just looping.
=== Mutual Exclusion and Synchronization ===
Yes, you need Spinlocks, Mutexes and Semaphores too. Nobody said it was easy. :)
==== AcpiOsCreateMutex ====
ACPI_STATUS AcpiOsCreateMutex(ACPI_MUTEX *OutHandle)
Create space for a new
==== AcpiOsDeleteMutex ====
void AcpiOsDeleteMutex(ACPI_MUTEX Handle)
Line 91 ⟶ 102:
ACPI_STATUS AcpiOsAcquireMutex(ACPI_MUTEX Handle, UINT16 Timeout)
This would be silly too if not for the Timeout parameter. Timeout can be one of:
* 0: acquire the
* 1 - +inf: acquire the
* -1 (0xFFFF): acquire the
==== AcpiOsReleaseMutex ====
void AcpiOsReleaseMutex(ACPI_MUTEX Handle)
Line 99 ⟶ 111:
==== AcpiOsCreateSemaphore ====
ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
Create a new
==== AcpiOsDeleteSemaphore ====
ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
-_-
==== AcpiOsWaitSemaphore ====
ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
Line 111 ⟶ 125:
==== AcpiOsCreateLock ====
ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
Create a new spinlock and put its address in *OutHandle. Spinlock should disable interrupts on the current
==== AcpiOsDeleteLock ====
void AcpiOsDeleteLock(ACPI_HANDLE Handle)
Line 120 ⟶ 135:
void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
Release the lock. ''Flags'' is the return value of AcquireLock. If you used this to store the interrupt state, now is the moment to use it.
=== Interrupt Handling ===
==== AcpiOsInstallInterruptHandler ====
Line 125 ⟶ 141:
ACPI sometimes fires interrupt. ACPICA will take care of them. ''InterruptLevel'' is the IRQ number that ACPI will use. Handler is an internal function of ACPICA which handles interrupts. Context is the parameter to be past to the Handler.
If you're lucky, your IRQ manager uses handlers of this form:
uint32_t
In this case just assign the handler to the
#include <Irq.h>
ACPI_OSD_HANDLER ServiceRout;
Line 146 ⟶ 162:
==== AcpiOsRemoveInterruptHandler ====
ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER Handler)
Just UnregisterIrq (InterruptNumber). Handler is provided in case you have an
== Using ACPICA in your OS ==
Line 158 ⟶ 175:
This is in addition to writing an AcpiOs interface layer, and it is not well indicated by the reference manual that you have to actually edit header files. Many of the macros defined in the headers are documented, though.
=== Visual Studio experience ===
From Visual Studio, although there is little organization in the files, it is relatively easy to port. In the provided/generate directory, there is a VC 9.0 solution. The only project required for integration is "AcpiSubsystem". Copy this project along with all the files listed (you can keep the old directory structure). #define's can be used to configure certain aspects of it, and perhaps changing #ifdef WIN32 to #ifdef X86 might be a good idea (Win64 -> x64). Once this is done though the base of it is in place, and actypes.h is the only header file that needs any modification (that listed above). It might be an idea to change the option "Compile as C code" to default - it's all .c anyway. This allows you to add C++ to the project without problems. Once this is done, add OSL.c or OSLPP.cpp, write your OS layer and you are done.
== Code Examples ==
Here are some examples of different operations that ACPICA can help with.
=== Power Off ===
To power off the machine:
AcpiEnterSleepStatePrep(5);
cli(); // disable interrupts
AcpiEnterSleepState(5);
panic("power off"); // in case it didn't work!
== External links ==
*[
*[
[[Category:
|