enable the timer device once it is available (NicJA)
[AROS.git] / arch / all-pc / acpica / acpios_aros.c
blob16a5243b2898024ef7740820130b41fd5a59c8ad
1 /*
2 * Copyright (C) 2012-2018, The AROS Development Team
3 * All right reserved.
4 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
6 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
7 */
9 #ifndef __ACPICA_NOLIBBASE__
10 #define __ACPICA_NOLIBBASE__
11 #endif /* !__ACPICA_NOLIBBASE__ */
13 #include <aros/debug.h>
15 #include "acpica_intern.h"
17 #include <hardware/efi/config.h>
19 #include <proto/exec.h>
20 #include <proto/timer.h>
21 #include <proto/efi.h>
22 #include <proto/kernel.h>
24 #include <proto/acpica.h>
26 #include <asm/io.h>
27 #include <exec/resident.h>
28 #include <devices/timer.h>
30 #define _COMPONENT ACPI_OS_SERVICES
31 ACPI_MODULE_NAME ("osarosxf")
33 #define DLOCK(a)
35 /* FIXME: __aros_getbase_ACPICABase() for internal use should be handled
36 properly by genmodule
38 #undef __aros_getbase_ACPICABase
39 struct Library *__aros_getbase_ACPICABase(void);
41 ACPI_STATUS AcpiOsInitialize (void)
43 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
45 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
47 if ((ACPICABase->ab_TimeMsgPort = CreateMsgPort())) {
48 D(bug("[ACPI] %s: MsgPort @ %p\n", __func__, ACPICABase->ab_TimeMsgPort));
49 if ((ACPICABase->ab_TimeRequest = CreateIORequest(ACPICABase->ab_TimeMsgPort, sizeof(*ACPICABase->ab_TimeRequest)))) {
50 D(bug("[ACPI] %s: TimeRequest @ %p\n", __func__, ACPICABase->ab_TimeRequest));
52 if (ACPICABase->ab_Flags & ACPICAF_TIMER)
53 if (0 == OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)ACPICABase->ab_TimeRequest, 0))
55 ACPICABase->ab_TimerBase = (struct Library *)ACPICABase->ab_TimeRequest->tr_node.io_Device;
58 return AE_OK;
60 DeleteMsgPort(ACPICABase->ab_TimeMsgPort);
63 D(bug("[ACPI] %s: Failed\n", __func__));
65 return AE_NO_MEMORY;
68 ACPI_STATUS AcpiOsTerminate (void)
70 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
72 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
74 if (ACPICABase->ab_TimeRequest->tr_node.io_Device)
76 ACPICABase->ab_TimerBase = NULL;
77 CloseDevice((struct IORequest *)ACPICABase->ab_TimeRequest);
80 DeleteIORequest(ACPICABase->ab_TimeRequest);
81 DeleteMsgPort(ACPICABase->ab_TimeMsgPort);
83 return AE_OK;
86 ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void)
88 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
90 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
92 if (ACPICABase->ab_RootPointer == 0) {
93 struct Library *EFIBase = OpenResource("efi.resource");
94 if (EFIBase) {
95 const uuid_t acpi_20_guid = ACPI_20_TABLE_GUID;
96 const uuid_t acpi_10_guid = ACPI_TABLE_GUID;
97 ACPICABase->ab_RootPointer = (ACPI_PHYSICAL_ADDRESS)EFI_FindConfigTable(&acpi_20_guid);
99 /* No ACPI 2.0 table? */
100 if (ACPICABase->ab_RootPointer == 0) {
101 ACPICABase->ab_RootPointer = (ACPI_PHYSICAL_ADDRESS)EFI_FindConfigTable(&acpi_10_guid);
106 /* Nope, no EFI available... Scan the ROM area
108 if (ACPICABase->ab_RootPointer == 0) {
109 AcpiFindRootPointer(&ACPICABase->ab_RootPointer);
112 return ACPICABase->ab_RootPointer;
115 ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
117 *NewValue = NULL;
118 return AE_OK;
121 ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_TABLE_HEADER **NewTable)
123 *NewTable = NULL;
124 return AE_OK;
127 ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
129 *NewAddress = 0;
130 return AE_OK;
134 void *AcpiOsMapMemory (ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length)
136 return (void *)PhysicalAddress;
139 void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length)
141 return;
144 ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
146 *PhysicalAddress = (IPTR)LogicalAddress;
147 return AE_OK;
150 void *AcpiOsAllocate(ACPI_SIZE Size)
152 D(bug("[ACPI] %s(%d)\n", __func__, Size));
153 return AllocVec(Size, MEMF_PUBLIC);
156 void *AcpiOsAllocateZeroed(ACPI_SIZE Size)
158 D(bug("[ACPI] %s(%d)\n", __func__, Size));
159 return AllocVec(Size, MEMF_PUBLIC|MEMF_CLEAR);
162 void AcpiOsFree(void *Memory)
164 D(bug("[ACPI] %s(0x%p)\n", __func__, Memory));
165 FreeVec(Memory);
168 BOOLEAN AcpiOsReadable(void *Memory, ACPI_SIZE Length)
170 return TRUE;
173 BOOLEAN AcpiOsWritable(void *Memory, ACPI_SIZE Length)
175 /* First 4K page is not writable on any AROS architecture */
176 return ((IPTR)Memory < 4096) ? FALSE : TRUE;
179 ACPI_THREAD_ID AcpiOsGetThreadId(void)
181 ACPI_THREAD_ID tid;
183 DLOCK(bug("[ACPI] %s()\n", __func__));
185 tid = (ACPI_THREAD_ID)(ACPI_PHYSICAL_ADDRESS)FindTask(NULL);
187 /* If we are running during kernel bring-up, return
188 * TID 1
190 if (tid == 0)
191 tid = 1;
193 return tid;
196 ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
198 /* TODO: Create a thread */
199 bug("[ACPI] %s: FIXME!\n", __func__);
201 return AE_NOT_IMPLEMENTED;
204 void AcpiOsSleep(UINT64 Milliseconds)
206 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
208 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
210 ACPICABase->ab_TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
211 ACPICABase->ab_TimeRequest->tr_time.tv_secs = Milliseconds / 1000;
212 ACPICABase->ab_TimeRequest->tr_time.tv_micro = (Milliseconds % 1000) * 1000;
213 DoIO((struct IORequest *)ACPICABase->ab_TimeRequest);
216 void AcpiOsStall(UINT32 Microseconds)
218 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
220 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
222 ACPICABase->ab_TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
223 ACPICABase->ab_TimeRequest->tr_time.tv_secs = Microseconds / 1000000;
224 ACPICABase->ab_TimeRequest->tr_time.tv_micro = (Microseconds % 1000000);
225 DoIO((struct IORequest *)ACPICABase->ab_TimeRequest);
228 void AcpiOsWaitEventsComplete(void)
230 bug("[ACPI] %s: FIXME!\n", __func__);
233 ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
235 struct SignalSemaphore *Handle;
237 DLOCK(bug("[ACPI] %s()\n", __func__);)
239 Handle = ACPI_ALLOCATE(sizeof(*Handle));
240 if (Handle) {
241 InitSemaphore(Handle);
242 *OutHandle = Handle;
243 return AE_OK;
245 return AE_NO_MEMORY;
248 ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
250 DLOCK(bug("[ACPI] %s()\n", __func__);)
252 ACPI_FREE(Handle);
253 return AE_OK;
256 ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
258 DLOCK(bug("[ACPI] %s()\n", __func__);)
260 if (Timeout == ACPI_DO_NOT_WAIT) {
261 if (!AttemptSemaphore(Handle))
262 return AE_TIME;
264 else
266 /* Forever.. */
267 ObtainSemaphore(Handle);
270 return AE_OK;
273 ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
275 DLOCK(bug("[ACPI] %s()\n", __func__);)
277 ReleaseSemaphore(Handle);
278 return AE_OK;
281 /* FIXME: Use SpinLock primitives once they exist in kernel.resource! */
282 #define MIN_PRI -128
283 struct SpinLock {
284 volatile ULONG sl_Lock;
287 static inline struct SpinLock *CreateSpin(VOID)
289 DLOCK(bug("[ACPI] %s()\n", __func__));
291 return AllocVec(sizeof(struct SpinLock), MEMF_ANY | MEMF_CLEAR);
294 static inline void DeleteSpin(struct SpinLock *sl)
296 DLOCK(bug("[ACPI] %s()\n", __func__);)
298 Disable();
299 while (sl->sl_Lock > 0) {
300 Enable();
301 sl->sl_Lock--;
303 Enable();
305 FreeVec(sl);
308 static inline VOID LockSpin(struct SpinLock *sl)
310 BYTE pri, pri_lower;
311 struct Task *task = FindTask(NULL);
313 DLOCK(bug("[ACPI] %s()\n", __func__);)
315 pri = task->tc_Node.ln_Pri;
316 pri_lower = pri;
318 do {
319 Disable();
320 if (sl->sl_Lock == 0) {
321 sl->sl_Lock++;
322 if (pri_lower != pri)
323 SetTaskPri(task, pri);
324 break;
326 Enable();
327 if (pri_lower > MIN_PRI)
328 pri_lower--;
329 SetTaskPri(task, pri_lower);
330 } while (1);
333 static inline void UnlockSpin(struct SpinLock *sl)
335 DLOCK(bug("[ACPI] %s()\n", __func__));
337 sl->sl_Lock--;
338 Enable();
341 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
343 DLOCK(bug("[ACPI] %s()\n", __func__));
345 *OutHandle = CreateSpin();
347 return (*OutHandle == NULL) ? AE_NO_MEMORY : AE_OK;
350 void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
352 DeleteSpin(Handle);
355 ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
357 DLOCK(bug("[ACPI] %s()\n", __func__));
359 LockSpin(Handle);
360 return 1;
363 void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
365 DLOCK(bug("[ACPI] %s()\n", __func__));
367 if (Flags == 1)
368 UnlockSpin(Handle);
371 struct AcpiOsInt {
372 struct Interrupt ai_Interrupt;
373 ACPI_OSD_HANDLER ai_Handler;
374 void *ai_Context;
377 static AROS_INTH1(AcpiOsIntServer, struct AcpiOsInt *, ai)
379 AROS_INTFUNC_INIT
381 UINT32 ret;
383 D(bug("[ACPI] %s()\n", __func__));
385 ret = ai->ai_Handler(ai->ai_Context);
387 return (ret == ACPI_INTERRUPT_HANDLED) ? TRUE : FALSE;
389 AROS_INTFUNC_EXIT
392 ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context)
394 struct AcpiOsInt *ai;
396 D(bug("[ACPI] %s()\n", __func__));
398 if ((ai = ACPI_ALLOCATE(sizeof(*ai)))) {
399 ai->ai_Interrupt.is_Node.ln_Name = "ACPI";
400 ai->ai_Interrupt.is_Code = (APTR)AcpiOsIntServer;
401 ai->ai_Interrupt.is_Data = (APTR)ai;
402 ai->ai_Handler = Handler;
403 ai->ai_Context = Context;
404 AddIntServer(INTB_KERNEL + InterruptLevel, &ai->ai_Interrupt);
405 return AE_OK;
408 return AE_NO_MEMORY;
411 ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER Handler)
413 bug("[ACPI] %s: FIXME! (InterruptLevel=%d)\n", __func__, InterruptNumber);
415 return AE_NOT_IMPLEMENTED;
418 ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
420 switch (Width) {
421 case 8: *Value = *(UINT8 *)Address; break;
422 case 16: *Value = *(UINT16 *)Address; break;
423 case 32: *Value = *(UINT32 *)Address; break;
424 case 64: *Value = *(UINT64 *)Address; break;
425 default: *Value = ~0; break;
428 return AE_OK;
431 ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
433 switch (Width) {
434 case 8: *(UINT8 *)Address = (UINT8)Value; break;
435 case 16: *(UINT16 *)Address = (UINT16)Value; break;
436 case 32: *(UINT32 *)Address = (UINT32)Value; break;
437 case 64: *(UINT64 *)Address = (UINT64)Value; break;
438 default: break;
441 return AE_OK;
444 ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
446 switch (Width) {
447 case 8: *Value = inb(Address); break;
448 case 16: *Value = inw(Address); break;
449 case 32: *Value = inl(Address); break;
450 default: *Value = ~0; break;
452 return AE_OK;
455 ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
457 switch (Width) {
458 case 8: outb(Value,Address); break;
459 case 16: outw(Value,Address); break;
460 case 32: outl(Value,Address); break;
461 default: break;
463 return AE_OK;
466 static UINT8 *find_pci(struct ACPICABase *ACPICABase, ACPI_PCI_ID *PciId)
468 int i;
470 D(bug("[ACPI] %s()\n", __func__));
472 for (i = 0; i < ACPICABase->ab_PCIs; i++) {
473 ACPI_MCFG_ALLOCATION *ma = &ACPICABase->ab_PCI[i];
474 if (PciId->Segment != ma->PciSegment)
475 continue;
476 if (PciId->Bus < ma->StartBusNumber ||
477 PciId->Bus > ma->EndBusNumber)
478 continue;
480 return (UINT8 *)(ACPI_PHYSICAL_ADDRESS)ma->Address;
483 return NULL;
486 ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width)
488 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
489 UINT8 *ecam;
491 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
493 if ((ecam = find_pci(ACPICABase, PciId))) {
494 UINT32 offset = (PciId->Bus << 20) | (PciId->Device << 15) | (PciId->Function << 12) | Register;
495 switch (Width) {
496 case 8: *Value = *(volatile UINT8 *)(ecam + offset); break;
497 case 16: *Value = *(volatile UINT16 *)(ecam + offset); break;
498 case 32: *Value = *(volatile UINT32 *)(ecam + offset); break;
499 case 64: *Value = *(volatile UINT64 *)(ecam + offset); break;
500 default: *Value = 0; break;
503 return AE_OK;
506 return AE_NOT_FOUND;
509 ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width)
511 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
512 UINT8 *ecam;
514 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
516 if ((ecam = find_pci(ACPICABase, PciId))) {
517 UINT32 offset = (PciId->Bus << 20) | (PciId->Device << 15) | (PciId->Function << 12) | Register;
518 switch (Width) {
519 case 8: *(volatile UINT8 *)(ecam + offset) = Value & 0xff; break;
520 case 16: *(volatile UINT16 *)(ecam + offset) = Value & 0xffff; break;
521 case 32: *(volatile UINT32 *)(ecam + offset) = Value & 0xffffffff; break;
522 case 64: *(volatile UINT64 *)(ecam + offset) = Value; break;
523 default: break;
526 return AE_OK;
529 return AE_NOT_FOUND;
532 void AcpiOsPrintf(const char *Fmt, ...)
534 va_list Args;
536 va_start (Args, Fmt);
537 AcpiOsVprintf (Fmt, Args);
538 va_end (Args);
541 void AcpiOsVprintf(const char *Format, va_list Args)
543 vkprintf(Format, Args);
546 /* Return current time in 100ns units
548 UINT64 AcpiOsGetTimer(void)
550 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
551 struct Library *TimerBase;
552 struct timeval tv;
553 UINT64 retVal = 0;
555 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
557 if ((TimerBase = ACPICABase->ab_TimerBase))
559 D(bug("[ACPI] %s: TimerBase=0x%p\n", __func__, TimerBase));
561 GetSysTime(&tv);
563 D(bug("[ACPI] %s: GetSysTime returned\n", __func__));
564 retVal = (tv.tv_secs*1000000ULL + tv.tv_micro)*10;
566 return retVal;
569 ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
571 bug("FIXME: %s\n", __func__);
572 return AE_NOT_IMPLEMENTED;
575 ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead)
577 bug("[ACPI] %s: FIXME!\n", __func__);
579 return AE_NOT_IMPLEMENTED;
582 ACPI_STATUS
583 AcpiOsEnterSleep (
584 UINT8 SleepState,
585 UINT32 RegaValue,
586 UINT32 RegbValue)
588 D(bug("[ACPI] %s()\n", __func__));
590 return (AE_OK);
594 * AROS Custom Code
596 UINT8 AcpiGetInfoFlags(ACPI_DEVICE_INFO *DevInfo)
598 return DevInfo->Flags;
601 UINT8 *AcpiGetInfoLowDstates(ACPI_DEVICE_INFO *DevInfo)
603 if (DevInfo->Valid & ACPI_VALID_SXWS)
604 return DevInfo->LowestDstates;
605 return NULL;
608 UINT8 *AcpiGetInfoHighDstates(ACPI_DEVICE_INFO *DevInfo)
610 if (DevInfo->Valid & ACPI_VALID_SXDS)
611 return DevInfo->HighestDstates;
612 return NULL;
615 UINT64 AcpiGetInfoAddress(ACPI_DEVICE_INFO *DevInfo)
617 if (DevInfo->Valid & ACPI_VALID_ADR)
618 return DevInfo->Address;
619 return 0;
622 ACPI_PNP_DEVICE_ID *AcpiGetInfoHardwareId(ACPI_DEVICE_INFO *DevInfo)
624 if (DevInfo->Valid & ACPI_VALID_HID)
625 return &DevInfo->HardwareId;
626 return NULL;
629 ACPI_PNP_DEVICE_ID *AcpiGetInfoUniqueId(ACPI_DEVICE_INFO *DevInfo)
631 if (DevInfo->Valid & ACPI_VALID_UID)
632 return &DevInfo->UniqueId;
633 return NULL;
636 ACPI_PNP_DEVICE_ID *AcpiGetInfoClassCode(ACPI_DEVICE_INFO *DevInfo)
638 ACPI_PNP_DEVICE_ID *classCode = NULL;
639 #if defined(ACPI_VALID_CLS)
640 if (DevInfo->Valid & ACPI_VALID_CLS)
641 classCode = &DevInfo->ClassCode;
642 #endif
643 return classCode;
646 ACPI_PNP_DEVICE_ID_LIST *AcpiGetInfoCompatIdList(ACPI_DEVICE_INFO *DevInfo)
648 if (DevInfo->Valid & ACPI_VALID_CID)
649 return &DevInfo->CompatibleIdList;
650 return NULL;
653 LONG AcpiScanTables(const char *Signature, const struct Hook *Hook, APTR UserData)
655 int i;
656 LONG count;
658 D(bug("[ACPI] %s()\n", __func__));
660 for (count = 0, i = 1; ; i++) {
661 ACPI_STATUS err;
662 ACPI_TABLE_HEADER *hdr;
663 IPTR ok;
665 err = AcpiGetTable((ACPI_STRING)Signature, i, &hdr);
666 if (err != AE_OK)
667 break;
669 if (Hook) {
670 ok = CALLHOOKPKT((struct Hook *)Hook, hdr, UserData);
671 } else {
672 ok = TRUE;
674 if (ok)
675 count++;
678 return count;
681 #define ACPI_MAX_INIT_TABLES 64
683 static int ACPICA_InitTask(struct ACPICABase *ACPICABase)
685 ACPI_STATUS err;
686 const UINT8 initlevel = ACPI_FULL_INITIALIZATION;
688 D(bug("[ACPI] %s: Starting Full initialization...\n", __func__));
690 err = AcpiInitializeSubsystem();
691 if (ACPI_FAILURE(err)) {
692 D(bug("[ACPI] %s: AcpiInitializeSubsystem returned error %d\n", __func__, err));
693 return FALSE;
696 D(bug("[ACPI] %s: Subsystem Initialized\n", __func__));
698 err = AcpiLoadTables();
699 if (ACPI_FAILURE(err)) {
700 D(bug("[ACPI] %s: AcpiLoadTables returned error %d\n", __func__, err));
701 return FALSE;
704 D(bug("[ACPI] %s: Tables Initialized\n", __func__));
706 err = AcpiEnableSubsystem(initlevel);
707 if (ACPI_FAILURE(err)) {
708 D(bug("[ACPI] %s: AcpiEnableSubsystem(0x%02x) returned error %d\n", __func__, initlevel, err));
709 return FALSE;
712 D(bug("[ACPI] %s: Subsystem Enabled\n", __func__));
714 err = AcpiInitializeObjects(initlevel);
715 if (ACPI_FAILURE(err)) {
716 D(bug("[ACPI] %s: AcpiInitializeObjects(0x%02x) returned error %d\n", __func__, initlevel, err));
717 return FALSE;
720 D(bug("[ACPI] %s: Full initialization complete\n", __func__));
722 return TRUE;
725 int ACPICA_init(struct ACPICABase *ACPICABase)
727 ACPI_TABLE_MCFG *mcfg;
728 ACPI_STATUS err;
729 struct Library *KernelBase;
731 D(bug("[ACPI] %s: ACPICABase=0x%p\n", __func__, ACPICABase));
733 if ((KernelBase = OpenResource("kernel.resource"))) {
734 struct TagItem *cmdline = LibFindTagItem(KRN_CmdLine, KrnGetBootInfo());
736 if (cmdline && strcasestr((char *)cmdline->ti_Data, "noacpi")) {
737 D(bug("[ACPI] %s: Disabled from command line\n", __func__));
738 return FALSE;
741 ACPICABase->ab_Flags |= ACPICAF_ENABLED;
743 AcpiDbgLevel = ~0;
745 ACPICABase->ab_RootPointer = 0;
747 err = AcpiInitializeTables(NULL, ACPI_MAX_INIT_TABLES, TRUE);
748 if (ACPI_FAILURE(err)) {
749 D(bug("[ACPI] %s: AcpiInitializeTables returned error %d\n", __func__, err));
750 return FALSE;
753 if (AcpiGetTable("MCFG", 1, (ACPI_TABLE_HEADER **)&mcfg) == AE_OK) {
754 ACPICABase->ab_PCIs = (mcfg->Header.Length - sizeof(*mcfg)) / sizeof(ACPI_MCFG_ALLOCATION);
755 ACPICABase->ab_PCI = (ACPI_MCFG_ALLOCATION *)&mcfg[1];
756 } else {
757 ACPICABase->ab_PCIs = 0;
760 return TRUE;
762 ADD2INITLIB(ACPICA_init,0)
764 int ACPICA_expunge(struct ACPICABase *ACPICABase)
766 D(bug("[ACPI] %s()\n", __func__));
768 if ((ACPICABase->ab_Flags & ACPICAF_ENABLED) != 0)
769 AcpiTerminate();
771 return TRUE;
773 ADD2EXPUNGELIB(ACPICA_expunge, 0)
775 /******************* ACPICA Post Exec/Kernel Setup ******************/
777 extern void acpicapost_end(void);
779 static AROS_UFP3 (APTR, ACPICAPost,
780 AROS_UFPA(struct Library *, lh, D0),
781 AROS_UFPA(BPTR, segList, A0),
782 AROS_UFPA(struct ExecBase *, sysBase, A6));
784 static const TEXT acpicapost_namestring[] = "acpica.post";
785 static const TEXT acpicapost_versionstring[] = "acpica.post 1.0\n";
787 const struct Resident acpicapost_romtag =
789 RTC_MATCHWORD,
790 (struct Resident *)&acpicapost_romtag,
791 (APTR)&acpicapost_end,
792 RTF_COLDSTART,
794 NT_UNKNOWN,
795 119,
796 (STRPTR)acpicapost_namestring,
797 (STRPTR)acpicapost_versionstring,
798 (APTR)ACPICAPost
801 extern struct syscallx86_Handler x86_SCRebootHandler;
802 extern struct syscallx86_Handler x86_SCChangePMStateHandler;
804 static AROS_UFH3 (APTR, ACPICAPost,
805 AROS_UFHA(struct Library *, lh, D0),
806 AROS_UFHA(BPTR, segList, A0),
807 AROS_UFHA(struct ExecBase *, SysBase, A6)
810 AROS_USERFUNC_INIT
812 struct ACPICABase *ACPICABase;
814 D(bug("[ACPI] %s()\n", __func__));
816 /* If ACPICA isn't available, don't run */
817 ACPICABase = (struct ACPICABase *)OpenLibrary("acpica.library", 0);
818 if (!ACPICABase) {
819 D(bug("[ACPI] %s(): Can't open acpica.library. Quitting\n", __func__));
820 return NULL;
823 /* Start up the late initialization thread at the highest priority */
824 if (NewCreateTask(TASKTAG_PC, ACPICA_InitTask, TASKTAG_NAME, "ACPICA_InitTask",
825 TASKTAG_PRI, 127, TASKTAG_ARG1, ACPICABase, TAG_DONE) == NULL) {
826 bug("[ACPI] %s: Failed to start ACPI init task\n", __func__);
829 D(bug("[ACPI] %s: Finished\n", __func__));
831 AROS_USERFUNC_EXIT
833 return NULL;
836 void acpicapost_end(void) { };
838 /******************* Timer Setup - Runs after timer.device is initialised ******************/
840 extern void acpicatimer_end(void);
842 static AROS_UFP3 (APTR, ACPICATimerSetup,
843 AROS_UFPA(struct Library *, lh, D0),
844 AROS_UFPA(BPTR, segList, A0),
845 AROS_UFPA(struct ExecBase *, sysBase, A6));
847 static const TEXT acpicatimer_namestring[] = "acpica.timer";
848 static const TEXT acpicatimer_versionstring[] = "acpica.timer 1.0\n";
850 const struct Resident acpicatimer_romtag =
852 RTC_MATCHWORD,
853 (struct Resident *)&acpicatimer_romtag,
854 (APTR)&acpicatimer_end,
855 RTF_COLDSTART,
857 NT_UNKNOWN,
859 (STRPTR)acpicatimer_namestring,
860 (STRPTR)acpicatimer_versionstring,
861 (APTR)ACPICATimerSetup
864 extern struct syscallx86_Handler x86_SCRebootHandler;
865 extern struct syscallx86_Handler x86_SCChangePMStateHandler;
867 static AROS_UFH3 (APTR, ACPICATimerSetup,
868 AROS_UFHA(struct Library *, lh, D0),
869 AROS_UFHA(BPTR, segList, A0),
870 AROS_UFHA(struct ExecBase *, SysBase, A6)
873 AROS_USERFUNC_INIT
875 struct ACPICABase *ACPICABase;
877 D(bug("[ACPI] %s()\n", __func__));
879 /* If ACPICA isn't available, don't run */
880 ACPICABase = (struct ACPICABase *)OpenLibrary("acpica.library", 0);
881 if (!ACPICABase) {
882 D(bug("[ACPI] %s(): Can't open acpica.library. Quitting\n", __func__));
883 return NULL;
886 if (0 == OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)ACPICABase->ab_TimeRequest, 0))
888 ACPICABase->ab_Flags |= ACPICAF_TIMER;
889 ACPICABase->ab_TimerBase = (struct Library *)ACPICABase->ab_TimeRequest->tr_node.io_Device;
891 D(bug("[ACPI] %s: Finished\n", __func__));
893 AROS_USERFUNC_EXIT
895 return NULL;
898 void acpicatimer_end(void) { };