Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / arch / all-pc / acpica / generate / aros / acpios_aros.c
blob5b9ae2c0e0b1a3248e7be0bd7b037c1d922e8df8
1 /*
2 * Copyright (C) 2012, 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 */
8 #define __ACPICA_NOLIBBASE__
9 #define DEBUG 1
10 #include <aros/debug.h>
12 #include "acpica_intern.h"
14 #include <hardware/efi/config.h>
16 #include <proto/exec.h>
17 #include <proto/timer.h>
18 #include <proto/efi.h>
19 #include <proto/kernel.h>
21 #include <proto/acpica.h>
23 #include <asm/io.h>
25 #include <devices/timer.h>
27 #define _COMPONENT ACPI_OS_SERVICES
28 ACPI_MODULE_NAME ("osarosxf")
30 /* FIXME: __aros_getbase_ACPICABase() for internal use should be handled
31 properly by genmodule
33 #undef __aros_getbase_ACPICABase
34 struct Library *__aros_getbase_ACPICABase(void);
36 ACPI_STATUS AcpiOsInitialize (void)
38 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
40 D(bug("[ACPI]AcpiOsInitialize(): ACPICABase=0x%x\n", ACPICABase));
42 if ((ACPICABase->ab_TimeMsgPort = CreateMsgPort())) {
43 if ((ACPICABase->ab_TimeRequest = CreateIORequest(ACPICABase->ab_TimeMsgPort, sizeof(*ACPICABase->ab_TimeRequest)))) {
44 ACPICABase->ab_TimerBase = (struct Library *)ACPICABase->ab_TimeRequest->tr_node.io_Device;
45 return AE_OK;
47 DeleteMsgPort(ACPICABase->ab_TimeMsgPort);
50 return AE_NO_MEMORY;
53 ACPI_STATUS AcpiOsTerminate (void)
55 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
57 D(bug("[ACPI]AcpiOsTerminate(): ACPICABase=0x%x\n", ACPICABase));
59 DeleteIORequest(ACPICABase->ab_TimeRequest);
60 DeleteMsgPort(ACPICABase->ab_TimeMsgPort);
62 return AE_OK;
65 ACPI_PHYSICAL_ADDRESS AcpiOsGetRootPointer(void)
67 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
69 D(bug("[ACPI]AcpiOsGetRootPointer(): ACPICABase=0x%x\n", ACPICABase));
71 if (ACPICABase->ab_RootPointer == 0) {
72 struct Library *EFIBase = OpenResource("efi.resource");
73 if (EFIBase) {
74 const uuid_t acpi_20_guid = ACPI_20_TABLE_GUID;
75 const uuid_t acpi_10_guid = ACPI_TABLE_GUID;
76 ACPICABase->ab_RootPointer = (ACPI_PHYSICAL_ADDRESS)EFI_FindConfigTable(&acpi_20_guid);
78 /* No ACPI 2.0 table? */
79 if (ACPICABase->ab_RootPointer == 0) {
80 ACPICABase->ab_RootPointer = (ACPI_PHYSICAL_ADDRESS)EFI_FindConfigTable(&acpi_10_guid);
85 /* Nope, no EFI available... Scan the ROM area
87 if (ACPICABase->ab_RootPointer == 0) {
88 AcpiFindRootPointer(&ACPICABase->ab_RootPointer);
91 return ACPICABase->ab_RootPointer;
94 ACPI_STATUS AcpiOsPredefinedOverride(const ACPI_PREDEFINED_NAMES *PredefinedObject, ACPI_STRING *NewValue)
96 *NewValue = NULL;
97 return AE_OK;
100 ACPI_STATUS AcpiOsTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_TABLE_HEADER **NewTable)
102 *NewTable = NULL;
103 return AE_OK;
106 ACPI_STATUS AcpiOsPhysicalTableOverride(ACPI_TABLE_HEADER *ExistingTable, ACPI_PHYSICAL_ADDRESS *NewAddress, UINT32 *NewTableLength)
108 *NewAddress = 0;
109 return AE_OK;
112 void *AcpiOsMapMemory (ACPI_PHYSICAL_ADDRESS PhysicalAddress, ACPI_SIZE Length)
114 return (void *)PhysicalAddress;
117 void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length)
119 return;
122 ACPI_STATUS AcpiOsGetPhysicalAddress(void *LogicalAddress, ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
124 *PhysicalAddress = (IPTR)LogicalAddress;
125 return AE_OK;
128 void *AcpiOsAllocate(ACPI_SIZE Size)
130 return AllocVec(Size, MEMF_PUBLIC);
133 void AcpiOsFree(void *Memory)
135 FreeVec(Memory);
138 BOOLEAN AcpiOsReadable(void *Memory, ACPI_SIZE Length)
140 return TRUE;
143 BOOLEAN AcpiOsWritable(void *Memory, ACPI_SIZE Length)
145 /* First 4K page is not writable on any AROS architecture */
146 return ((IPTR)Memory < 4096) ? FALSE : TRUE;
149 ACPI_THREAD_ID AcpiOsGetThreadId(void)
151 ACPI_THREAD_ID tid;
153 tid = (ACPI_THREAD_ID)(ACPI_PHYSICAL_ADDRESS)FindTask(NULL);
155 /* If we are running during kernel bring-up, return
156 * TID 1
158 if (tid == 0)
159 tid = 1;
161 return tid;
164 ACPI_STATUS AcpiOsExecute(ACPI_EXECUTE_TYPE Type, ACPI_OSD_EXEC_CALLBACK Function, void *Context)
166 /* TODO: Create a thread */
167 bug("FIXME: %s\n", __func__);
168 return AE_NOT_IMPLEMENTED;
171 void AcpiOsSleep(UINT64 Milliseconds)
173 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
175 D(bug("[ACPI]AcpiOsSleep(): ACPICABase=0x%x\n", ACPICABase));
177 ACPICABase->ab_TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
178 ACPICABase->ab_TimeRequest->tr_time.tv_secs = Milliseconds / 1000;
179 ACPICABase->ab_TimeRequest->tr_time.tv_micro = (Milliseconds % 1000) * 1000;
180 DoIO((struct IORequest *)ACPICABase->ab_TimeRequest);
183 void AcpiOsStall(UINT32 Microseconds)
185 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
187 D(bug("[ACPI]AcpiOsStall(): ACPICABase=0x%x\n", ACPICABase));
189 ACPICABase->ab_TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
190 ACPICABase->ab_TimeRequest->tr_time.tv_secs = Microseconds / 1000000;
191 ACPICABase->ab_TimeRequest->tr_time.tv_micro = (Microseconds % 1000000);
192 DoIO((struct IORequest *)ACPICABase->ab_TimeRequest);
195 void AcpiOsWaitEventsComplete(void)
197 bug("FIXME: %s\n", __func__);
200 ACPI_STATUS AcpiOsCreateSemaphore(UINT32 MaxUnits, UINT32 InitialUnits, ACPI_SEMAPHORE *OutHandle)
202 struct SignalSemaphore *Handle;
204 Handle = ACPI_ALLOCATE(sizeof(*Handle));
205 if (Handle) {
206 InitSemaphore(Handle);
207 *OutHandle = Handle;
208 return AE_OK;
210 return AE_NO_MEMORY;
213 ACPI_STATUS AcpiOsDeleteSemaphore(ACPI_SEMAPHORE Handle)
215 ACPI_FREE(Handle);
216 return AE_OK;
219 ACPI_STATUS AcpiOsWaitSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units, UINT16 Timeout)
221 if (Timeout != 0xffff)
222 bug("FIXME: %s, Timeout=0x%04x\n", __func__, Timeout);
224 if (Timeout == 0) {
225 if (AttemptSemaphore(Handle)) {
226 return AE_OK;
227 } else {
228 return AE_TIME;
232 /* Forever.. */
233 ObtainSemaphore(Handle);
235 return AE_OK;
238 ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units)
240 ReleaseSemaphore(Handle);
241 return AE_OK;
244 /* FIXME: Use SpinLock primitives once they exist in kernel.resource! */
245 #define MIN_PRI -128
246 struct SpinLock {
247 volatile ULONG sl_Lock;
250 static inline struct SpinLock *CreateSpin(VOID)
252 return AllocVec(sizeof(struct SpinLock), MEMF_ANY | MEMF_CLEAR);
255 static inline void DeleteSpin(struct SpinLock *sl)
257 Disable();
258 while (sl->sl_Lock > 0) {
259 Enable();
260 sl->sl_Lock--;
262 Enable();
264 FreeVec(sl);
267 static inline VOID LockSpin(struct SpinLock *sl)
269 BYTE pri, pri_lower;
270 struct Task *task = FindTask(NULL);
272 pri = task->tc_Node.ln_Pri;
273 pri_lower = pri;
275 do {
276 Disable();
277 if (sl->sl_Lock == 0) {
278 sl->sl_Lock++;
279 if (pri_lower != pri)
280 SetTaskPri(task, pri);
281 break;
283 Enable();
284 if (pri_lower > MIN_PRI)
285 pri_lower--;
286 SetTaskPri(task, pri_lower);
287 } while (1);
290 static inline void UnlockSpin(struct SpinLock *sl)
292 sl->sl_Lock--;
293 Enable();
296 ACPI_STATUS AcpiOsCreateLock(ACPI_SPINLOCK *OutHandle)
298 *OutHandle = CreateSpin();
300 return (*OutHandle == NULL) ? AE_NO_MEMORY : AE_OK;
303 void AcpiOsDeleteLock(ACPI_SPINLOCK Handle)
305 DeleteSpin(Handle);
308 ACPI_CPU_FLAGS AcpiOsAcquireLock(ACPI_SPINLOCK Handle)
310 LockSpin(Handle);
311 return 1;
314 void AcpiOsReleaseLock(ACPI_SPINLOCK Handle, ACPI_CPU_FLAGS Flags)
316 if (Flags == 1)
317 UnlockSpin(Handle);
320 struct AcpiOsInt {
321 struct Interrupt ai_Interrupt;
322 ACPI_OSD_HANDLER ai_Handler;
323 void *ai_Context;
326 static AROS_INTH1(AcpiOsIntServer, struct AcpiOsInt *, ai)
328 AROS_INTFUNC_INIT
330 UINT32 ret;
332 ret = ai->ai_Handler(ai->ai_Context);
334 return (ret == ACPI_INTERRUPT_HANDLED) ? TRUE : FALSE;
336 AROS_INTFUNC_EXIT
339 ACPI_STATUS AcpiOsInstallInterruptHandler(UINT32 InterruptLevel, ACPI_OSD_HANDLER Handler, void *Context)
341 struct AcpiOsInt *ai;
343 if ((ai = ACPI_ALLOCATE(sizeof(*ai)))) {
344 ai->ai_Interrupt.is_Node.ln_Name = "ACPI";
345 ai->ai_Interrupt.is_Code = (APTR)AcpiOsIntServer;
346 ai->ai_Interrupt.is_Data = (APTR)ai;
347 ai->ai_Handler = Handler;
348 ai->ai_Context = Context;
349 AddIntServer(INTB_KERNEL + InterruptLevel, &ai->ai_Interrupt);
350 return AE_OK;
353 return AE_NO_MEMORY;
356 ACPI_STATUS AcpiOsRemoveInterruptHandler(UINT32 InterruptNumber, ACPI_OSD_HANDLER Handler)
358 bug("FIXME: %s (InterruptLevel=%d)\n", __func__, InterruptNumber);
359 return AE_NOT_IMPLEMENTED;
362 ACPI_STATUS AcpiOsReadMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 *Value, UINT32 Width)
364 switch (Width) {
365 case 8: *Value = *(UINT8 *)Address; break;
366 case 16: *Value = *(UINT16 *)Address; break;
367 case 32: *Value = *(UINT32 *)Address; break;
368 case 64: *Value = *(UINT64 *)Address; break;
369 default: *Value = ~0; break;
372 return AE_OK;
375 ACPI_STATUS AcpiOsWriteMemory(ACPI_PHYSICAL_ADDRESS Address, UINT64 Value, UINT32 Width)
377 switch (Width) {
378 case 8: *(UINT8 *)Address = (UINT8)Value; break;
379 case 16: *(UINT16 *)Address = (UINT16)Value; break;
380 case 32: *(UINT32 *)Address = (UINT32)Value; break;
381 case 64: *(UINT64 *)Address = (UINT64)Value; break;
382 default: break;
385 return AE_OK;
388 ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
390 switch (Width) {
391 case 8: *Value = inb(Address); break;
392 case 16: *Value = inw(Address); break;
393 case 32: *Value = inl(Address); break;
394 default: *Value = ~0; break;
396 return AE_OK;
399 ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
401 switch (Width) {
402 case 8: outb(Value,Address); break;
403 case 16: outw(Value,Address); break;
404 case 32: outl(Value,Address); break;
405 default: break;
407 return AE_OK;
410 static UINT8 *find_pci(struct ACPICABase *ACPICABase, ACPI_PCI_ID *PciId)
412 int i;
414 for (i = 0; i < ACPICABase->ab_PCIs; i++) {
415 ACPI_MCFG_ALLOCATION *ma = &ACPICABase->ab_PCI[i];
416 if (PciId->Segment != ma->PciSegment)
417 continue;
418 if (PciId->Bus < ma->StartBusNumber ||
419 PciId->Bus > ma->EndBusNumber)
420 continue;
422 return (UINT8 *)(ACPI_PHYSICAL_ADDRESS)ma->Address;
425 return NULL;
428 ACPI_STATUS AcpiOsReadPciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 *Value, UINT32 Width)
430 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
431 UINT8 *ecam;
433 D(bug("[ACPI]AcpiOsReadPciConfiguration(): ACPICABase=0x%x\n", ACPICABase));
435 if ((ecam = find_pci(ACPICABase, PciId))) {
436 UINT32 offset = (PciId->Bus << 20) | (PciId->Device << 15) | (PciId->Function << 12) | Register;
437 switch (Width) {
438 case 8: *Value = *(volatile UINT8 *)(ecam + offset); break;
439 case 16: *Value = *(volatile UINT16 *)(ecam + offset); break;
440 case 32: *Value = *(volatile UINT32 *)(ecam + offset); break;
441 case 64: *Value = *(volatile UINT64 *)(ecam + offset); break;
442 default: *Value = 0; break;
445 return AE_OK;
448 return AE_NOT_FOUND;
451 ACPI_STATUS AcpiOsWritePciConfiguration(ACPI_PCI_ID *PciId, UINT32 Register, UINT64 Value, UINT32 Width)
453 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
454 UINT8 *ecam;
456 D(bug("[ACPI]AcpiOsWritePciConfiguration(): ACPICABase=0x%x\n", ACPICABase));
458 if ((ecam = find_pci(ACPICABase, PciId))) {
459 UINT32 offset = (PciId->Bus << 20) | (PciId->Device << 15) | (PciId->Function << 12) | Register;
460 switch (Width) {
461 case 8: *(volatile UINT8 *)(ecam + offset) = Value & 0xff; break;
462 case 16: *(volatile UINT16 *)(ecam + offset) = Value & 0xffff; break;
463 case 32: *(volatile UINT32 *)(ecam + offset) = Value & 0xffffffff; break;
464 case 64: *(volatile UINT64 *)(ecam + offset) = Value; break;
465 default: break;
468 return AE_OK;
471 return AE_NOT_FOUND;
474 void AcpiOsPrintf(const char *Fmt, ...)
476 va_list Args;
478 va_start (Args, Fmt);
479 AcpiOsVprintf (Fmt, Args);
480 va_end (Args);
483 void AcpiOsVprintf(const char *Format, va_list Args)
485 vkprintf(Format, Args);
488 /* Return current time in 100ns units
490 UINT64 AcpiOsGetTimer(void)
492 struct ACPICABase *ACPICABase = (struct ACPICABase *)__aros_getbase_ACPICABase();
493 struct Library *TimerBase;
494 struct timeval tv;
496 D(bug("[ACPI]AcpiOsGetTimer(): ACPICABase=0x%x\n", ACPICABase));
498 TimerBase = ACPICABase->ab_TimerBase;
500 GetSysTime(&tv);
502 return (tv.tv_secs*1000000ULL + tv.tv_micro)*10;
505 ACPI_STATUS AcpiOsSignal(UINT32 Function, void *Info)
507 bug("FIXME: %s\n", __func__);
508 return AE_NOT_IMPLEMENTED;
511 ACPI_STATUS AcpiOsGetLine(char *Buffer, UINT32 BufferLength, UINT32 *BytesRead)
513 bug("FIXME: %s\n", __func__);
514 return AE_NOT_IMPLEMENTED;
518 * AROS Custom Code
520 LONG AcpiScanTables(const char *Signature, const struct Hook *Hook, APTR UserData)
522 int i;
523 LONG count;
525 for (count = 0, i = 1; ; i++) {
526 ACPI_STATUS err;
527 ACPI_TABLE_HEADER *hdr;
528 IPTR ok;
530 err = AcpiGetTable((ACPI_STRING)Signature, i, &hdr);
531 if (err != AE_OK)
532 break;
534 if (Hook) {
535 ok = CALLHOOKPKT((struct Hook *)Hook, hdr, UserData);
536 } else {
537 ok = TRUE;
539 if (ok)
540 count++;
543 return count;
546 #define ACPI_MAX_INIT_TABLES 64
548 static int ACPICA_InitTask(struct ACPICABase *ACPICABase)
550 ACPI_STATUS err;
551 const UINT8 initlevel = ACPI_FULL_INITIALIZATION;
553 err = AcpiInitializeSubsystem();
554 if (ACPI_FAILURE(err)) {
555 D(bug("%s: AcpiInitializeSubsystem() = %d\n", __func__, err));
556 return FALSE;
559 err = AcpiLoadTables();
560 if (ACPI_FAILURE(err)) {
561 D(bug("%s: AcpiLoadTables() = %d\n", __func__, err));
562 return FALSE;
565 err = AcpiEnableSubsystem(initlevel);
566 if (ACPI_FAILURE(err)) {
567 D(bug("%s: AcpiEnableSubsystem(0x%02x) = %d\n", __func__, initlevel, err));
568 return FALSE;
571 err = AcpiInitializeObjects(initlevel);
572 if (ACPI_FAILURE(err)) {
573 D(bug("%s: AcpiInitializeObjects(0x%02x) = %d\n", __func__, initlevel, err));
574 return FALSE;
577 D(bug("[ACPI] Full initialization complete\n"));
579 return TRUE;
582 int ACPICA_init(struct ACPICABase *ACPICABase)
584 ACPI_TABLE_MCFG *mcfg;
585 ACPI_STATUS err;
586 struct Library *KernelBase;
588 D(bug("[ACPI]ACPICA_init(ACPICABase=0x%x)\n", ACPICABase));
590 if ((KernelBase = OpenResource("kernel.resource"))) {
591 struct TagItem *cmdline = LibFindTagItem(KRN_CmdLine, KrnGetBootInfo());
593 if (cmdline && strcasestr((char *)cmdline->ti_Data, "noacpi")) {
594 D(bug("[ACPI] Disabled from command line\n"));
595 return FALSE;
599 AcpiDbgLevel = ~0;
601 ACPICABase->ab_RootPointer = 0;
603 err = AcpiInitializeTables(NULL, ACPI_MAX_INIT_TABLES, TRUE);
604 if (ACPI_FAILURE(err)) {
605 D(bug("%s: AcpiInitializeTables() = %d\n", __func__, err));
606 return FALSE;
609 if (AcpiGetTable("MCFG", 1, (ACPI_TABLE_HEADER **)&mcfg) == AE_OK) {
610 ACPICABase->ab_PCIs = (mcfg->Header.Length - sizeof(*mcfg)) / sizeof(ACPI_MCFG_ALLOCATION);
611 ACPICABase->ab_PCI = (ACPI_MCFG_ALLOCATION *)&mcfg[1];
612 } else {
613 ACPICABase->ab_PCIs = 0;
616 /* Everything else is in the late initialization thread,
617 * which will start at the highest priority once mulitasking begins
619 if (NewCreateTask(TASKTAG_PC, ACPICA_InitTask, TASKTAG_NAME, "ACPICA_InitTask", TASKTAG_PRI, 127, TASKTAG_ARG1, ACPICABase, TAG_DONE) == NULL) {
620 AcpiTerminate();
621 return FALSE;
624 return TRUE;
626 ADD2INITLIB(ACPICA_init,0)
628 int ACPICA_expunge(struct ACPICABase *ACPICABase)
630 AcpiTerminate();
632 return TRUE;
634 ADD2EXPUNGELIB(ACPICA_expunge, 0)