1 /*******************************************************************************
3 * ACPI Component Architecture Operating System Layer (OSL) for ReactOS *
5 *******************************************************************************/
9 #include <pseh/pseh2.h>
14 static PKINTERRUPT AcpiInterrupt
;
15 static BOOLEAN AcpiInterruptHandlerRegistered
= FALSE
;
16 static ACPI_OSD_HANDLER AcpiIrqHandler
= NULL
;
17 static PVOID AcpiIrqContext
= NULL
;
18 static ULONG AcpiIrqNumber
= 0;
21 AcpiOsInitialize (void)
23 DPRINT("AcpiOsInitialize called\n");
26 /* Verboseness level of the acpica core */
27 AcpiDbgLevel
= 0x00FFFFFF;
28 AcpiDbgLayer
= 0xFFFFFFFF;
37 DPRINT("AcpiOsTerminate() called\n");
43 AcpiOsGetRootPointer (
46 ACPI_PHYSICAL_ADDRESS pa
= 0;
48 DPRINT("AcpiOsGetRootPointer\n");
50 AcpiFindRootPointer(&pa
);
55 AcpiOsPredefinedOverride(
56 const ACPI_PREDEFINED_NAMES
*PredefinedObject
,
57 ACPI_STRING
*NewValue
)
59 if (!PredefinedObject
|| !NewValue
)
61 DPRINT1("Invalid parameter\n");
62 return AE_BAD_PARAMETER
;
73 ACPI_TABLE_HEADER
*ExistingTable
,
74 ACPI_TABLE_HEADER
**NewTable
)
76 if (!ExistingTable
|| !NewTable
)
78 DPRINT1("Invalid parameter\n");
79 return AE_BAD_PARAMETER
;
89 AcpiOsPhysicalTableOverride(
90 ACPI_TABLE_HEADER
*ExistingTable
,
91 ACPI_PHYSICAL_ADDRESS
*NewAddress
,
92 UINT32
*NewTableLength
)
94 if (!ExistingTable
|| !NewAddress
|| !NewTableLength
)
96 DPRINT1("Invalid parameter\n");
97 return AE_BAD_PARAMETER
;
109 ACPI_PHYSICAL_ADDRESS phys
,
112 PHYSICAL_ADDRESS Address
;
115 DPRINT("AcpiOsMapMemory(phys 0x%p size 0x%X)\n", phys
, length
);
117 Address
.QuadPart
= (ULONG
)phys
;
118 Ptr
= MmMapIoSpace(Address
, length
, MmNonCached
);
121 DPRINT1("Mapping failed\n");
132 DPRINT("AcpiOsMapMemory(phys 0x%p size 0x%X)\n", virt
, length
);
136 MmUnmapIoSpace(virt
, length
);
140 AcpiOsGetPhysicalAddress(
141 void *LogicalAddress
,
142 ACPI_PHYSICAL_ADDRESS
*PhysicalAddress
)
144 PHYSICAL_ADDRESS PhysAddr
;
146 if (!LogicalAddress
|| !PhysicalAddress
)
148 DPRINT1("Bad parameter\n");
149 return AE_BAD_PARAMETER
;
152 PhysAddr
= MmGetPhysicalAddress(LogicalAddress
);
154 *PhysicalAddress
= (ACPI_PHYSICAL_ADDRESS
)PhysAddr
.QuadPart
;
160 AcpiOsAllocate (ACPI_SIZE size
)
162 DPRINT("AcpiOsAllocate size %d\n",size
);
163 return ExAllocatePoolWithTag(NonPagedPool
, size
, 'ipcA');
167 AcpiOsFree(void *ptr
)
170 DPRINT1("Attempt to free null pointer!!!\n");
171 ExFreePoolWithTag(ptr
, 'ipcA');
183 ProbeForRead(Memory
, Length
, sizeof(UCHAR
));
186 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
204 ProbeForWrite(Memory
, Length
, sizeof(UCHAR
));
207 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
217 AcpiOsGetThreadId (void)
219 /* Thread ID must be non-zero */
220 return (ULONG
)PsGetCurrentThreadId() + 1;
225 ACPI_EXECUTE_TYPE Type
,
226 ACPI_OSD_EXEC_CALLBACK Function
,
230 OBJECT_ATTRIBUTES ObjectAttributes
;
233 DPRINT("AcpiOsExecute\n");
235 InitializeObjectAttributes(&ObjectAttributes
,
241 Status
= PsCreateSystemThread(&ThreadHandle
,
246 (PKSTART_ROUTINE
)Function
,
248 if (!NT_SUCCESS(Status
))
251 ZwClose(ThreadHandle
);
257 AcpiOsSleep (UINT64 milliseconds
)
259 DPRINT("AcpiOsSleep %d\n", milliseconds
);
260 KeStallExecutionProcessor(milliseconds
*1000);
264 AcpiOsStall (UINT32 microseconds
)
266 DPRINT("AcpiOsStall %d\n",microseconds
);
267 KeStallExecutionProcessor(microseconds
);
272 ACPI_MUTEX
*OutHandle
)
278 DPRINT1("Bad parameter\n");
279 return AE_BAD_PARAMETER
;
282 Mutex
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(FAST_MUTEX
), 'LpcA');
283 if (!Mutex
) return AE_NO_MEMORY
;
285 ExInitializeFastMutex(Mutex
);
287 *OutHandle
= (ACPI_MUTEX
)Mutex
;
298 DPRINT1("Bad parameter\n");
302 ExFreePoolWithTag(Handle
, 'LpcA');
312 DPRINT1("Bad parameter\n");
313 return AE_BAD_PARAMETER
;
316 /* Check what the caller wants us to do */
317 if (Timeout
== ACPI_DO_NOT_WAIT
)
319 /* Try to acquire without waiting */
320 if (!ExTryToAcquireFastMutex((PFAST_MUTEX
)Handle
))
325 /* Block until we get it */
326 ExAcquireFastMutex((PFAST_MUTEX
)Handle
);
338 DPRINT1("Bad parameter\n");
342 ExReleaseFastMutex((PFAST_MUTEX
)Handle
);
345 typedef struct _ACPI_SEM
{
349 } ACPI_SEM
, *PACPI_SEM
;
352 AcpiOsCreateSemaphore(
355 ACPI_SEMAPHORE
*OutHandle
)
361 DPRINT1("Bad parameter\n");
362 return AE_BAD_PARAMETER
;
365 Sem
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(ACPI_SEM
), 'LpcA');
366 if (!Sem
) return AE_NO_MEMORY
;
368 Sem
->CurrentUnits
= InitialUnits
;
369 KeInitializeEvent(&Sem
->Event
, SynchronizationEvent
, Sem
->CurrentUnits
!= 0);
370 KeInitializeSpinLock(&Sem
->Lock
);
372 *OutHandle
= (ACPI_SEMAPHORE
)Sem
;
378 AcpiOsDeleteSemaphore(
379 ACPI_SEMAPHORE Handle
)
383 DPRINT1("Bad parameter\n");
384 return AE_BAD_PARAMETER
;
387 ExFreePoolWithTag(Handle
, 'LpcA');
394 ACPI_SEMAPHORE Handle
,
398 PACPI_SEM Sem
= Handle
;
403 DPRINT1("Bad parameter\n");
404 return AE_BAD_PARAMETER
;
407 KeAcquireSpinLock(&Sem
->Lock
, &OldIrql
);
409 /* Make sure we can wait if we have fewer units than we need */
410 if ((Timeout
== ACPI_DO_NOT_WAIT
) && (Sem
->CurrentUnits
< Units
))
412 /* We can't so we must bail now */
413 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
417 /* Time to block until we get enough units */
418 while (Sem
->CurrentUnits
< Units
)
420 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
421 KeWaitForSingleObject(&Sem
->Event
,
426 KeAcquireSpinLock(&Sem
->Lock
, &OldIrql
);
429 Sem
->CurrentUnits
-= Units
;
431 if (Sem
->CurrentUnits
!= 0) KeSetEvent(&Sem
->Event
, IO_NO_INCREMENT
, FALSE
);
433 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
439 AcpiOsSignalSemaphore(
440 ACPI_SEMAPHORE Handle
,
443 PACPI_SEM Sem
= Handle
;
448 DPRINT1("Bad parameter\n");
449 return AE_BAD_PARAMETER
;
452 KeAcquireSpinLock(&Sem
->Lock
, &OldIrql
);
454 Sem
->CurrentUnits
+= Units
;
455 KeSetEvent(&Sem
->Event
, IO_NO_INCREMENT
, FALSE
);
457 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
464 ACPI_SPINLOCK
*OutHandle
)
466 PKSPIN_LOCK SpinLock
;
470 DPRINT1("Bad parameter\n");
471 return AE_BAD_PARAMETER
;
474 SpinLock
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(KSPIN_LOCK
), 'LpcA');
475 if (!SpinLock
) return AE_NO_MEMORY
;
477 KeInitializeSpinLock(SpinLock
);
479 *OutHandle
= (ACPI_SPINLOCK
)SpinLock
;
486 ACPI_SPINLOCK Handle
)
490 DPRINT1("Bad parameter\n");
494 ExFreePoolWithTag(Handle
, 'LpcA');
499 ACPI_SPINLOCK Handle
)
503 if ((OldIrql
= KeGetCurrentIrql()) >= DISPATCH_LEVEL
)
505 KeAcquireSpinLockAtDpcLevel((PKSPIN_LOCK
)Handle
);
509 KeAcquireSpinLock((PKSPIN_LOCK
)Handle
, &OldIrql
);
512 return (ACPI_CPU_FLAGS
)OldIrql
;
517 ACPI_SPINLOCK Handle
,
518 ACPI_CPU_FLAGS Flags
)
520 KIRQL OldIrql
= (KIRQL
)Flags
;
522 if (OldIrql
>= DISPATCH_LEVEL
)
524 KeReleaseSpinLockFromDpcLevel((PKSPIN_LOCK
)Handle
);
528 KeReleaseSpinLock((PKSPIN_LOCK
)Handle
, OldIrql
);
534 PKINTERRUPT Interrupt
,
535 PVOID ServiceContext
)
539 Status
= (*AcpiIrqHandler
)(AcpiIrqContext
);
541 if (Status
== ACPI_INTERRUPT_HANDLED
)
548 AcpiOsInstallInterruptHandler (
549 UINT32 InterruptNumber
,
550 ACPI_OSD_HANDLER ServiceRoutine
,
558 if (AcpiInterruptHandlerRegistered
)
560 DPRINT1("Reregister interrupt attempt failed\n");
561 return AE_ALREADY_EXISTS
;
566 DPRINT1("Bad parameter\n");
567 return AE_BAD_PARAMETER
;
570 DPRINT("AcpiOsInstallInterruptHandler()\n");
571 Vector
= HalGetInterruptVector(
579 AcpiIrqNumber
= InterruptNumber
;
580 AcpiIrqHandler
= ServiceRoutine
;
581 AcpiIrqContext
= Context
;
582 AcpiInterruptHandlerRegistered
= TRUE
;
584 Status
= IoConnectInterrupt(
597 if (!NT_SUCCESS(Status
))
599 DPRINT("Could not connect to interrupt %d\n", Vector
);
606 AcpiOsRemoveInterruptHandler (
607 UINT32 InterruptNumber
,
608 ACPI_OSD_HANDLER ServiceRoutine
)
610 DPRINT("AcpiOsRemoveInterruptHandler()\n");
614 DPRINT1("Bad parameter\n");
615 return AE_BAD_PARAMETER
;
618 if (AcpiInterruptHandlerRegistered
)
620 IoDisconnectInterrupt(AcpiInterrupt
);
621 AcpiInterrupt
= NULL
;
622 AcpiInterruptHandlerRegistered
= FALSE
;
626 DPRINT1("Trying to remove non-existing interrupt handler\n");
635 ACPI_PHYSICAL_ADDRESS Address
,
639 DPRINT("AcpiOsReadMemory %p\n", Address
);
643 *Value
= (*(PUCHAR
)(ULONG_PTR
)Address
);
647 *Value
= (*(PUSHORT
)(ULONG_PTR
)Address
);
651 *Value
= (*(PULONG
)(ULONG_PTR
)Address
);
655 *Value
= (*(PULONGLONG
)(ULONG_PTR
)Address
);
659 DPRINT1("AcpiOsReadMemory got bad width: %d\n",Width
);
660 return (AE_BAD_PARAMETER
);
668 ACPI_PHYSICAL_ADDRESS Address
,
672 DPRINT("AcpiOsWriteMemory %p\n", Address
);
676 *(PUCHAR
)(ULONG_PTR
)Address
= Value
;
680 *(PUSHORT
)(ULONG_PTR
)Address
= Value
;
684 *(PULONG
)(ULONG_PTR
)Address
= Value
;
688 *(PULONGLONG
)(ULONG_PTR
)Address
= Value
;
692 DPRINT1("AcpiOsWriteMemory got bad width: %d\n",Width
);
693 return (AE_BAD_PARAMETER
);
702 ACPI_IO_ADDRESS Address
,
706 DPRINT("AcpiOsReadPort %p, width %d\n",Address
,Width
);
711 *Value
= READ_PORT_UCHAR((PUCHAR
)(ULONG_PTR
)Address
);
715 *Value
= READ_PORT_USHORT((PUSHORT
)(ULONG_PTR
)Address
);
719 *Value
= READ_PORT_ULONG((PULONG
)(ULONG_PTR
)Address
);
723 DPRINT1("AcpiOsReadPort got bad width: %d\n",Width
);
724 return (AE_BAD_PARAMETER
);
732 ACPI_IO_ADDRESS Address
,
736 DPRINT("AcpiOsWritePort %p, width %d\n",Address
,Width
);
740 WRITE_PORT_UCHAR((PUCHAR
)(ULONG_PTR
)Address
, Value
);
744 WRITE_PORT_USHORT((PUSHORT
)(ULONG_PTR
)Address
, Value
);
748 WRITE_PORT_ULONG((PULONG
)(ULONG_PTR
)Address
, Value
);
752 DPRINT1("AcpiOsWritePort got bad width: %d\n",Width
);
753 return (AE_BAD_PARAMETER
);
760 OslIsPciDevicePresent(ULONG BusNumber
, ULONG SlotNumber
)
763 PCI_COMMON_CONFIG PciConfig
;
765 /* Detect device presence by reading the PCI configuration space */
767 ReadLength
= HalGetBusDataByOffset(PCIConfiguration
,
775 DPRINT("PCI device is not present\n");
779 ASSERT(ReadLength
>= 2);
781 if (PciConfig
.VendorID
== PCI_INVALID_VENDORID
)
783 DPRINT("Invalid vendor ID in PCI configuration space\n");
787 DPRINT("PCI device is present\n");
793 AcpiOsReadPciConfiguration (
799 PCI_SLOT_NUMBER slot
;
802 slot
.u
.bits
.DeviceNumber
= PciId
->Device
;
803 slot
.u
.bits
.FunctionNumber
= PciId
->Function
;
805 DPRINT("AcpiOsReadPciConfiguration, slot=0x%X, func=0x%X\n", slot
.u
.AsULONG
, Reg
);
807 if (!OslIsPciDevicePresent(PciId
->Bus
, slot
.u
.AsULONG
))
810 /* Width is in BITS */
811 HalGetBusDataByOffset(PCIConfiguration
,
822 AcpiOsWritePciConfiguration (
829 PCI_SLOT_NUMBER slot
;
832 slot
.u
.bits
.DeviceNumber
= PciId
->Device
;
833 slot
.u
.bits
.FunctionNumber
= PciId
->Function
;
835 DPRINT("AcpiOsWritePciConfiguration, slot=0x%x\n", slot
.u
.AsULONG
);
836 if (!OslIsPciDevicePresent(PciId
->Bus
, slot
.u
.AsULONG
))
839 /* Width is in BITS */
840 HalSetBusDataByOffset(PCIConfiguration
,
850 void ACPI_INTERNAL_VAR_XFACE
856 va_start (Args
, Fmt
);
858 AcpiOsVprintf (Fmt
, Args
);
870 vDbgPrintEx (-1, DPFLTR_ERROR_LEVEL
, Fmt
, Args
);
876 AcpiOsRedirectOutput(
880 DPRINT1("Output redirection not supported\n");
887 LARGE_INTEGER CurrentTime
;
889 KeQuerySystemTime(&CurrentTime
);
890 return CurrentTime
.QuadPart
;
894 AcpiOsWaitEventsComplete(void)
897 * Wait for all asynchronous events to complete.
898 * This implementation does nothing.
908 ACPI_SIGNAL_FATAL_INFO
*FatalInfo
= Info
;
912 case ACPI_SIGNAL_FATAL
:
914 DPRINT1 ("AcpiOsBreakpoint: %d %d %d ****\n", FatalInfo
->Type
, FatalInfo
->Code
, FatalInfo
->Argument
);
916 DPRINT1 ("AcpiOsBreakpoint ****\n");
918 case ACPI_SIGNAL_BREAKPOINT
:
920 DPRINT1 ("AcpiOsBreakpoint: %s ****\n", Info
);
922 DPRINT1 ("AcpiOsBreakpoint ****\n");
937 DPRINT1("File reading not supported\n");