1 /*******************************************************************************
3 * ACPI Component Architecture Operating System Layer (OSL) for ReactOS *
5 *******************************************************************************/
13 #define NUM_SEMAPHORES 128
15 static PKINTERRUPT AcpiInterrupt
;
16 static BOOLEAN AcpiInterruptHandlerRegistered
= FALSE
;
17 static ACPI_OSD_HANDLER AcpiIrqHandler
= NULL
;
18 static PVOID AcpiIrqContext
= NULL
;
19 static ULONG AcpiIrqNumber
= 0;
21 static PVOID IVTVirtualAddress
= NULL
;
24 typedef struct semaphore_entry
31 static SEMAPHORE_ENTRY AcpiGbl_Semaphores
[NUM_SEMAPHORES
];
36 IN PVOID DeferredContext
,
37 IN PVOID SystemArgument1
,
38 IN PVOID SystemArgument2
)
40 ACPI_OSD_EXEC_CALLBACK Routine
= (ACPI_OSD_EXEC_CALLBACK
)SystemArgument1
;
42 DPRINT("OslDpcStub()\n");
43 DPRINT("Calling [%p]([%p])\n", Routine
, SystemArgument2
);
44 (*Routine
)(SystemArgument2
);
49 PKINTERRUPT Interrupt
,
54 Status
= (*AcpiIrqHandler
)(AcpiIrqContext
);
56 if (ACPI_SUCCESS(Status
))
63 AcpiOsRemoveInterruptHandler (
64 UINT32 InterruptNumber
,
65 ACPI_OSD_HANDLER ServiceRoutine
);
68 AcpiOsInitialize (void)
70 DPRINT("AcpiOsInitialize called\n");
73 /* Verboseness level of the acpica core */
74 AcpiDbgLevel
= 0x00FFFFFF;
75 AcpiDbgLayer
= 0xFFFFFFFF;
80 for (i
= 0; i
< NUM_SEMAPHORES
; i
++)
82 AcpiGbl_Semaphores
[i
].OsHandle
= NULL
;
85 KeInitializeDpc(&AcpiDpc
, OslDpcStub
, NULL
);
93 DPRINT("AcpiOsTerminate() called\n");
95 if (AcpiInterruptHandlerRegistered
)
96 AcpiOsRemoveInterruptHandler(AcpiIrqNumber
, AcpiIrqHandler
);
101 void ACPI_INTERNAL_VAR_XFACE
107 va_start (Args
, Fmt
);
109 AcpiOsVprintf (Fmt
, Args
);
121 vDbgPrintEx (-1, DPFLTR_ERROR_LEVEL
, Fmt
, Args
);
127 AcpiOsAllocate (ACPI_SIZE size
)
129 DPRINT("AcpiOsAllocate size %d\n",size
);
130 return ExAllocatePool(NonPagedPool
, size
);
134 AcpiOsCallocate(ACPI_SIZE size
)
136 PVOID ptr
= ExAllocatePool(NonPagedPool
, size
);
138 memset(ptr
, 0, size
);
143 AcpiOsFree(void *ptr
)
146 DPRINT1("Attempt to free null pointer!!!\n");
150 #ifndef ACPI_USE_LOCAL_CACHE
153 AcpiOsAcquireObjectHelper (
155 SIZE_T NumberOfBytes
,
158 void* Alloc
= ExAllocatePool(PoolType
, NumberOfBytes
);
160 /* acpica expects memory allocated from cache to be zeroed */
161 RtlZeroMemory(Alloc
,NumberOfBytes
);
170 ACPI_CACHE_T
**ReturnCache
)
172 PNPAGED_LOOKASIDE_LIST Lookaside
=
173 ExAllocatePool(NonPagedPool
,sizeof(NPAGED_LOOKASIDE_LIST
));
175 ExInitializeNPagedLookasideList(Lookaside
,
176 (PALLOCATE_FUNCTION
)AcpiOsAcquireObjectHelper
,// custom memory allocator
182 *ReturnCache
= (ACPI_CACHE_T
*)Lookaside
;
184 DPRINT("AcpiOsCreateCache %p\n", Lookaside
);
192 DPRINT("AcpiOsDeleteCache %p\n", Cache
);
193 ExDeleteNPagedLookasideList(
194 (PNPAGED_LOOKASIDE_LIST
) Cache
);
203 DPRINT("AcpiOsPurgeCache\n");
204 /* No such functionality for LookAside lists */
209 AcpiOsAcquireObject (
212 PNPAGED_LOOKASIDE_LIST List
= (PNPAGED_LOOKASIDE_LIST
)Cache
;
213 DPRINT("AcpiOsAcquireObject from %p\n", Cache
);
215 ExAllocateFromNPagedLookasideList(List
);
218 RtlZeroMemory(ptr
,List
->L
.Size
);
223 AcpiOsReleaseObject (
227 DPRINT("AcpiOsReleaseObject %p from %p\n",Object
, Cache
);
228 ExFreeToNPagedLookasideList(
229 (PNPAGED_LOOKASIDE_LIST
)Cache
,
238 ACPI_PHYSICAL_ADDRESS phys
,
241 PHYSICAL_ADDRESS Address
;
243 DPRINT("AcpiOsMapMemory(phys 0x%X size 0x%X)\n", (ULONG
)phys
, length
);
246 IVTVirtualAddress
= ExAllocatePool(NonPagedPool
, length
);
247 return IVTVirtualAddress
;
250 Address
.QuadPart
= (ULONG
)phys
;
251 return MmMapIoSpace(Address
, length
, MmNonCached
);
259 DPRINT("AcpiOsUnmapMemory()\n");
263 ExFreePool(IVTVirtualAddress
);
266 MmUnmapIoSpace(virt
, length
);
270 AcpiOsInstallInterruptHandler (
271 UINT32 InterruptNumber
,
272 ACPI_OSD_HANDLER ServiceRoutine
,
280 DPRINT("AcpiOsInstallInterruptHandler()\n");
281 Vector
= HalGetInterruptVector(
289 AcpiIrqNumber
= InterruptNumber
;
290 AcpiIrqHandler
= ServiceRoutine
;
291 AcpiIrqContext
= Context
;
292 AcpiInterruptHandlerRegistered
= TRUE
;
294 Status
= IoConnectInterrupt(
302 LevelSensitive
, /* FIXME: LevelSensitive or Latched? */
307 if (!NT_SUCCESS(Status
))
309 DPRINT("Could not connect to interrupt %d\n", Vector
);
316 AcpiOsRemoveInterruptHandler (
317 UINT32 InterruptNumber
,
318 ACPI_OSD_HANDLER ServiceRoutine
)
320 DPRINT("AcpiOsRemoveInterruptHandler()\n");
321 if (AcpiInterruptHandlerRegistered
)
323 IoDisconnectInterrupt(AcpiInterrupt
);
324 AcpiInterrupt
= NULL
;
325 AcpiInterruptHandlerRegistered
= FALSE
;
332 AcpiOsStall (UINT32 microseconds
)
334 DPRINT("AcpiOsStall %d\n",microseconds
);
335 KeStallExecutionProcessor(microseconds
);
340 AcpiOsSleep (ACPI_INTEGER milliseconds
)
342 DPRINT("AcpiOsSleep %d\n", milliseconds
);
343 KeStallExecutionProcessor(milliseconds
*1000);
349 ACPI_IO_ADDRESS Address
,
353 DPRINT("AcpiOsReadPort %p, width %d\n",Address
,Width
);
358 *Value
= READ_PORT_UCHAR((PUCHAR
)Address
);
362 *Value
= READ_PORT_USHORT((PUSHORT
)Address
);
366 *Value
= READ_PORT_ULONG((PULONG
)Address
);
369 DPRINT1("AcpiOsReadPort got bad width: %d\n",Width
);
370 return (AE_BAD_PARAMETER
);
378 ACPI_IO_ADDRESS Address
,
382 DPRINT("AcpiOsWritePort %p, width %d\n",Address
,Width
);
386 WRITE_PORT_UCHAR((PUCHAR
)Address
, Value
);
390 WRITE_PORT_USHORT((PUSHORT
)Address
, Value
);
394 WRITE_PORT_ULONG((PULONG
)Address
, Value
);
398 DPRINT1("AcpiOsWritePort got bad width: %d\n",Width
);
399 return (AE_BAD_PARAMETER
);
407 ACPI_PHYSICAL_ADDRESS Address
,
411 DPRINT("AcpiOsReadMemory %p\n", Address
);
415 *Value
= (*(PUCHAR
)(ULONG
)Address
);
418 *Value
= (*(PUSHORT
)(ULONG
)Address
);
421 *Value
= (*(PULONG
)(ULONG
)Address
);
425 DPRINT1("AcpiOsReadMemory got bad width: %d\n",Width
);
426 return (AE_BAD_PARAMETER
);
435 ACPI_PHYSICAL_ADDRESS Address
,
439 DPRINT("AcpiOsWriteMemory %p\n", Address
);
443 *(PUCHAR
)(ULONG
)Address
= Value
;
446 *(PUSHORT
)(ULONG
)Address
= Value
;
449 *(PULONG
)(ULONG
)Address
= Value
;
453 DPRINT1("AcpiOsWriteMemory got bad width: %d\n",Width
);
454 return (AE_BAD_PARAMETER
);
462 AcpiOsReadPciConfiguration (
469 PCI_SLOT_NUMBER slot
;
471 if (Register
== 0 || PciId
->Device
== 0 ||
472 Register
+ Width
> PCI_COMMON_HDR_LENGTH
)
476 slot
.u
.bits
.DeviceNumber
= PciId
->Device
;
477 slot
.u
.bits
.FunctionNumber
= PciId
->Function
;
479 DPRINT("AcpiOsReadPciConfiguration, slot=0x%X, func=0x%X\n", slot
.u
.AsULONG
, Register
);
480 Status
= HalGetBusDataByOffset(PCIConfiguration
,
487 if (NT_SUCCESS(Status
))
494 AcpiOsWritePciConfiguration (
502 PCI_SLOT_NUMBER slot
;
504 if (Register
== 0 || PciId
->Device
== 0 ||
505 Register
+ Width
> PCI_COMMON_HDR_LENGTH
)
509 slot
.u
.bits
.DeviceNumber
= PciId
->Device
;
510 slot
.u
.bits
.FunctionNumber
= PciId
->Function
;
512 DPRINT("AcpiOsWritePciConfiguration, slot=0x%x\n", slot
.u
.AsULONG
);
513 Status
= HalSetBusDataByOffset(PCIConfiguration
,
520 if (NT_SUCCESS(Status
))
527 AcpiOsCreateSemaphore (
530 ACPI_SEMAPHORE
*OutHandle
)
534 Mutex
= ExAllocatePool(NonPagedPool
, sizeof(FAST_MUTEX
));
538 DPRINT("AcpiOsCreateSemaphore() at 0x%X\n", Mutex
);
540 ExInitializeFastMutex(Mutex
);
547 AcpiOsDeleteSemaphore (
548 ACPI_SEMAPHORE Handle
)
550 PFAST_MUTEX Mutex
= (PFAST_MUTEX
)Handle
;
552 DPRINT("AcpiOsDeleteSemaphore(handle 0x%X)\n", Handle
);
555 return AE_BAD_PARAMETER
;
563 ACPI_SEMAPHORE Handle
,
567 PFAST_MUTEX Mutex
= (PFAST_MUTEX
)Handle
;
569 if (!Mutex
|| (units
< 1))
571 DPRINT("AcpiOsWaitSemaphore(handle 0x%X, units %d) Bad parameters\n",
573 return AE_BAD_PARAMETER
;
576 DPRINT("Waiting for semaphore %p\n", Handle
);
579 /* HACK: We enter here at a high IRQL sometimes
580 * because we get called from DPCs and ISRs and
581 * we can't use a fast mutex at that IRQL */
582 if (KeGetCurrentIrql() <= APC_LEVEL
)
583 ExAcquireFastMutex(Mutex
);
589 AcpiOsSignalSemaphore (
593 PFAST_MUTEX Mutex
= (PFAST_MUTEX
)Handle
;
595 DPRINT("AcpiOsSignalSemaphore %p\n",Handle
);
598 /* HACK: We enter here at a high IRQL sometimes
599 * because we get called from DPCs and ISRs and
600 * we can't use a fast mutex at that IRQL */
601 if (KeGetCurrentIrql() <= APC_LEVEL
)
602 ExReleaseFastMutex(Mutex
);
609 ACPI_SPINLOCK
*OutHandle
)
611 DPRINT("AcpiOsCreateLock\n");
612 return (AcpiOsCreateSemaphore (1, 1, OutHandle
));
617 ACPI_SPINLOCK Handle
)
619 DPRINT("AcpiOsDeleteLock %p\n", Handle
);
620 AcpiOsDeleteSemaphore (Handle
);
628 DPRINT("AcpiOsAcquireLock, %p\n", Handle
);
629 AcpiOsWaitSemaphore (Handle
, 1, 0xFFFF);
636 ACPI_SPINLOCK Handle
,
637 ACPI_CPU_FLAGS Flags
)
639 DPRINT("AcpiOsReleaseLock %p\n",Handle
);
640 AcpiOsSignalSemaphore (Handle
, 1);
651 case ACPI_SIGNAL_FATAL
:
653 AcpiOsPrintf ("AcpiOsBreakpoint: %s ****\n", Info
);
655 AcpiOsPrintf ("AcpiOsBreakpoint ****\n");
657 case ACPI_SIGNAL_BREAKPOINT
:
659 AcpiOsPrintf ("AcpiOsBreakpoint: %s ****\n", Info
);
661 AcpiOsPrintf ("AcpiOsBreakpoint ****\n");
670 AcpiOsGetThreadId (void)
672 return (ULONG
)PsGetCurrentThreadId();
677 ACPI_EXECUTE_TYPE Type
,
678 ACPI_OSD_EXEC_CALLBACK Function
,
681 DPRINT("AcpiOsExecute\n");
683 KeInsertQueueDpc(&AcpiDpc
, (PVOID
)Function
, (PVOID
)Context
);
685 #ifdef _MULTI_THREADED
686 //_beginthread (Function, (unsigned) 0, Context);
693 AcpiOsGetTimer (void)
695 DPRINT("AcpiOsGetTimer\n");
697 KeQueryTickCount(&Timer
);
699 return Timer
.QuadPart
;
708 DPRINT("AcpiOsDerivePciId\n");
713 AcpiOsPredefinedOverride (
714 const ACPI_PREDEFINED_NAMES
*InitVal
,
717 if (!InitVal
|| !NewVal
)
718 return AE_BAD_PARAMETER
;
720 *NewVal
= ACPI_OS_NAME
;
721 DPRINT("AcpiOsPredefinedOverride\n");
725 ACPI_PHYSICAL_ADDRESS
726 AcpiOsGetRootPointer (
730 AcpiOsTableOverride (
731 ACPI_TABLE_HEADER
*ExistingTable
,
732 ACPI_TABLE_HEADER
**NewTable
)
734 DPRINT("AcpiOsTableOverride\n");
740 AcpiOsValidateInterface (
743 DPRINT("AcpiOsValidateInterface\n");
748 AcpiOsValidateAddress (
750 ACPI_PHYSICAL_ADDRESS Address
,
753 DPRINT("AcpiOsValidateAddress\n");
757 ACPI_PHYSICAL_ADDRESS
758 AcpiOsGetRootPointer (
761 DPRINT("AcpiOsGetRootPointer\n");
762 ACPI_PHYSICAL_ADDRESS pa
= 0;
764 AcpiFindRootPointer(&pa
);