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
;
90 ACPI_PHYSICAL_ADDRESS phys
,
93 PHYSICAL_ADDRESS Address
;
96 DPRINT("AcpiOsMapMemory(phys 0x%p size 0x%X)\n", phys
, length
);
100 Address
.QuadPart
= (ULONG
)phys
;
101 Ptr
= MmMapIoSpace(Address
, length
, MmNonCached
);
104 DPRINT1("Mapping failed\n");
115 DPRINT("AcpiOsMapMemory(phys 0x%p size 0x%X)\n", virt
, length
);
119 MmUnmapIoSpace(virt
, length
);
123 AcpiOsGetPhysicalAddress(
124 void *LogicalAddress
,
125 ACPI_PHYSICAL_ADDRESS
*PhysicalAddress
)
127 PHYSICAL_ADDRESS PhysAddr
;
129 if (!LogicalAddress
|| !PhysicalAddress
)
131 DPRINT1("Bad parameter\n");
132 return AE_BAD_PARAMETER
;
135 PhysAddr
= MmGetPhysicalAddress(LogicalAddress
);
137 *PhysicalAddress
= (ACPI_PHYSICAL_ADDRESS
)PhysAddr
.QuadPart
;
143 AcpiOsAllocate (ACPI_SIZE size
)
145 DPRINT("AcpiOsAllocate size %d\n",size
);
146 return ExAllocatePoolWithTag(NonPagedPool
, size
, 'IPCA');
150 AcpiOsFree(void *ptr
)
153 DPRINT1("Attempt to free null pointer!!!\n");
154 ExFreePoolWithTag(ptr
, 'IPCA');
166 ProbeForRead(Memory
, Length
, sizeof(UCHAR
));
170 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
188 ProbeForWrite(Memory
, Length
, sizeof(UCHAR
));
192 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
202 AcpiOsGetThreadId (void)
204 /* Thread ID must be non-zero */
205 return (ULONG
)PsGetCurrentThreadId() + 1;
210 ACPI_EXECUTE_TYPE Type
,
211 ACPI_OSD_EXEC_CALLBACK Function
,
215 OBJECT_ATTRIBUTES ObjectAttributes
;
218 DPRINT("AcpiOsExecute\n");
220 InitializeObjectAttributes(&ObjectAttributes
,
226 Status
= PsCreateSystemThread(&ThreadHandle
,
231 (PKSTART_ROUTINE
)Function
,
233 if (!NT_SUCCESS(Status
))
236 ZwClose(ThreadHandle
);
242 AcpiOsSleep (UINT64 milliseconds
)
244 DPRINT("AcpiOsSleep %d\n", milliseconds
);
245 KeStallExecutionProcessor(milliseconds
*1000);
249 AcpiOsStall (UINT32 microseconds
)
251 DPRINT("AcpiOsStall %d\n",microseconds
);
252 KeStallExecutionProcessor(microseconds
);
257 ACPI_MUTEX
*OutHandle
)
263 DPRINT1("Bad parameter\n");
264 return AE_BAD_PARAMETER
;
267 Mutex
= ExAllocatePool(NonPagedPool
, sizeof(FAST_MUTEX
));
268 if (!Mutex
) return AE_NO_MEMORY
;
270 ExInitializeFastMutex(Mutex
);
272 *OutHandle
= (ACPI_MUTEX
)Mutex
;
283 DPRINT1("Bad parameter\n");
297 DPRINT1("Bad parameter\n");
298 return AE_BAD_PARAMETER
;
301 /* Check what the caller wants us to do */
302 if (Timeout
== ACPI_DO_NOT_WAIT
)
304 /* Try to acquire without waiting */
305 if (!ExTryToAcquireFastMutex((PFAST_MUTEX
)Handle
))
310 /* Block until we get it */
311 ExAcquireFastMutex((PFAST_MUTEX
)Handle
);
323 DPRINT1("Bad parameter\n");
327 ExReleaseFastMutex((PFAST_MUTEX
)Handle
);
330 typedef struct _ACPI_SEM
{
334 } ACPI_SEM
, *PACPI_SEM
;
337 AcpiOsCreateSemaphore(
340 ACPI_SEMAPHORE
*OutHandle
)
346 DPRINT1("Bad parameter\n");
347 return AE_BAD_PARAMETER
;
350 Sem
= ExAllocatePool(NonPagedPool
, sizeof(ACPI_SEM
));
351 if (!Sem
) return AE_NO_MEMORY
;
353 Sem
->CurrentUnits
= InitialUnits
;
354 KeInitializeEvent(&Sem
->Event
, SynchronizationEvent
, Sem
->CurrentUnits
!= 0);
355 KeInitializeSpinLock(&Sem
->Lock
);
357 *OutHandle
= (ACPI_SEMAPHORE
)Sem
;
363 AcpiOsDeleteSemaphore(
364 ACPI_SEMAPHORE Handle
)
368 DPRINT1("Bad parameter\n");
369 return AE_BAD_PARAMETER
;
379 ACPI_SEMAPHORE Handle
,
383 PACPI_SEM Sem
= Handle
;
388 DPRINT1("Bad parameter\n");
389 return AE_BAD_PARAMETER
;
392 KeAcquireSpinLock(&Sem
->Lock
, &OldIrql
);
394 /* Make sure we can wait if we have fewer units than we need */
395 if ((Timeout
== ACPI_DO_NOT_WAIT
) && (Sem
->CurrentUnits
< Units
))
397 /* We can't so we must bail now */
398 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
402 /* Time to block until we get enough units */
403 while (Sem
->CurrentUnits
< Units
)
405 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
406 KeWaitForSingleObject(&Sem
->Event
,
411 KeAcquireSpinLock(&Sem
->Lock
, &OldIrql
);
414 Sem
->CurrentUnits
-= Units
;
416 if (Sem
->CurrentUnits
!= 0) KeSetEvent(&Sem
->Event
, IO_NO_INCREMENT
, FALSE
);
418 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
424 AcpiOsSignalSemaphore(
425 ACPI_SEMAPHORE Handle
,
428 PACPI_SEM Sem
= Handle
;
433 DPRINT1("Bad parameter\n");
434 return AE_BAD_PARAMETER
;
437 KeAcquireSpinLock(&Sem
->Lock
, &OldIrql
);
439 Sem
->CurrentUnits
+= Units
;
440 KeSetEvent(&Sem
->Event
, IO_NO_INCREMENT
, FALSE
);
442 KeReleaseSpinLock(&Sem
->Lock
, OldIrql
);
449 ACPI_SPINLOCK
*OutHandle
)
451 PKSPIN_LOCK SpinLock
;
455 DPRINT1("Bad parameter\n");
456 return AE_BAD_PARAMETER
;
459 SpinLock
= ExAllocatePool(NonPagedPool
, sizeof(KSPIN_LOCK
));
460 if (!SpinLock
) return AE_NO_MEMORY
;
462 KeInitializeSpinLock(SpinLock
);
464 *OutHandle
= (ACPI_SPINLOCK
)SpinLock
;
471 ACPI_SPINLOCK Handle
)
475 DPRINT1("Bad parameter\n");
484 ACPI_SPINLOCK Handle
)
488 if ((OldIrql
= KeGetCurrentIrql()) >= DISPATCH_LEVEL
)
490 KeAcquireSpinLockAtDpcLevel((PKSPIN_LOCK
)Handle
);
494 KeAcquireSpinLock((PKSPIN_LOCK
)Handle
, &OldIrql
);
497 return (ACPI_CPU_FLAGS
)OldIrql
;
502 ACPI_SPINLOCK Handle
,
503 ACPI_CPU_FLAGS Flags
)
505 KIRQL OldIrql
= (KIRQL
)Flags
;
507 if (OldIrql
>= DISPATCH_LEVEL
)
509 KeReleaseSpinLockFromDpcLevel((PKSPIN_LOCK
)Handle
);
513 KeReleaseSpinLock((PKSPIN_LOCK
)Handle
, OldIrql
);
519 PKINTERRUPT Interrupt
,
520 PVOID ServiceContext
)
524 Status
= (*AcpiIrqHandler
)(AcpiIrqContext
);
526 if (Status
== ACPI_INTERRUPT_HANDLED
)
533 AcpiOsInstallInterruptHandler (
534 UINT32 InterruptNumber
,
535 ACPI_OSD_HANDLER ServiceRoutine
,
543 if (AcpiInterruptHandlerRegistered
)
545 DPRINT1("Reregister interrupt attempt failed\n");
546 return AE_ALREADY_EXISTS
;
551 DPRINT1("Bad parameter\n");
552 return AE_BAD_PARAMETER
;
555 DPRINT("AcpiOsInstallInterruptHandler()\n");
556 Vector
= HalGetInterruptVector(
564 AcpiIrqNumber
= InterruptNumber
;
565 AcpiIrqHandler
= ServiceRoutine
;
566 AcpiIrqContext
= Context
;
567 AcpiInterruptHandlerRegistered
= TRUE
;
569 Status
= IoConnectInterrupt(
582 if (!NT_SUCCESS(Status
))
584 DPRINT("Could not connect to interrupt %d\n", Vector
);
591 AcpiOsRemoveInterruptHandler (
592 UINT32 InterruptNumber
,
593 ACPI_OSD_HANDLER ServiceRoutine
)
595 DPRINT("AcpiOsRemoveInterruptHandler()\n");
599 DPRINT1("Bad parameter\n");
600 return AE_BAD_PARAMETER
;
603 if (AcpiInterruptHandlerRegistered
)
605 IoDisconnectInterrupt(AcpiInterrupt
);
606 AcpiInterrupt
= NULL
;
607 AcpiInterruptHandlerRegistered
= FALSE
;
611 DPRINT1("Trying to remove non-existing interrupt handler\n");
620 ACPI_PHYSICAL_ADDRESS Address
,
624 DPRINT("AcpiOsReadMemory %p\n", Address
);
628 *Value
= (*(PUCHAR
)(ULONG_PTR
)Address
);
631 *Value
= (*(PUSHORT
)(ULONG_PTR
)Address
);
634 *Value
= (*(PULONG
)(ULONG_PTR
)Address
);
638 DPRINT1("AcpiOsReadMemory got bad width: %d\n",Width
);
639 return (AE_BAD_PARAMETER
);
647 ACPI_PHYSICAL_ADDRESS Address
,
651 DPRINT("AcpiOsWriteMemory %p\n", Address
);
655 *(PUCHAR
)(ULONG_PTR
)Address
= Value
;
658 *(PUSHORT
)(ULONG_PTR
)Address
= Value
;
661 *(PULONG
)(ULONG_PTR
)Address
= Value
;
665 DPRINT1("AcpiOsWriteMemory got bad width: %d\n",Width
);
666 return (AE_BAD_PARAMETER
);
675 ACPI_IO_ADDRESS Address
,
679 DPRINT("AcpiOsReadPort %p, width %d\n",Address
,Width
);
684 *Value
= READ_PORT_UCHAR((PUCHAR
)Address
);
688 *Value
= READ_PORT_USHORT((PUSHORT
)Address
);
692 *Value
= READ_PORT_ULONG((PULONG
)Address
);
695 DPRINT1("AcpiOsReadPort got bad width: %d\n",Width
);
696 return (AE_BAD_PARAMETER
);
704 ACPI_IO_ADDRESS Address
,
708 DPRINT("AcpiOsWritePort %p, width %d\n",Address
,Width
);
712 WRITE_PORT_UCHAR((PUCHAR
)Address
, Value
);
716 WRITE_PORT_USHORT((PUSHORT
)Address
, Value
);
720 WRITE_PORT_ULONG((PULONG
)Address
, Value
);
724 DPRINT1("AcpiOsWritePort got bad width: %d\n",Width
);
725 return (AE_BAD_PARAMETER
);
732 OslIsPciDevicePresent(ULONG BusNumber
, ULONG SlotNumber
)
735 PCI_COMMON_CONFIG PciConfig
;
737 /* Detect device presence by reading the PCI configuration space */
739 ReadLength
= HalGetBusDataByOffset(PCIConfiguration
,
747 DPRINT("PCI device is not present\n");
751 ASSERT(ReadLength
>= 2);
753 if (PciConfig
.VendorID
== PCI_INVALID_VENDORID
)
755 DPRINT("Invalid vendor ID in PCI configuration space\n");
759 DPRINT("PCI device is present\n");
765 AcpiOsReadPciConfiguration (
771 PCI_SLOT_NUMBER slot
;
774 slot
.u
.bits
.DeviceNumber
= PciId
->Device
;
775 slot
.u
.bits
.FunctionNumber
= PciId
->Function
;
777 DPRINT("AcpiOsReadPciConfiguration, slot=0x%X, func=0x%X\n", slot
.u
.AsULONG
, Reg
);
779 if (!OslIsPciDevicePresent(PciId
->Bus
, slot
.u
.AsULONG
))
782 /* Width is in BITS */
783 HalGetBusDataByOffset(PCIConfiguration
,
794 AcpiOsWritePciConfiguration (
801 PCI_SLOT_NUMBER slot
;
804 slot
.u
.bits
.DeviceNumber
= PciId
->Device
;
805 slot
.u
.bits
.FunctionNumber
= PciId
->Function
;
807 DPRINT("AcpiOsWritePciConfiguration, slot=0x%x\n", slot
.u
.AsULONG
);
808 if (!OslIsPciDevicePresent(PciId
->Bus
, slot
.u
.AsULONG
))
811 /* Width is in BITS */
812 HalSetBusDataByOffset(PCIConfiguration
,
822 void ACPI_INTERNAL_VAR_XFACE
828 va_start (Args
, Fmt
);
830 AcpiOsVprintf (Fmt
, Args
);
842 vDbgPrintEx (-1, DPFLTR_ERROR_LEVEL
, Fmt
, Args
);
848 AcpiOsRedirectOutput(
852 DPRINT1("Output redirection not supported\n");
859 LARGE_INTEGER CurrentTime
;
861 KeQuerySystemTime(&CurrentTime
);
863 return CurrentTime
.QuadPart
;
871 ACPI_SIGNAL_FATAL_INFO
*FatalInfo
= Info
;
875 case ACPI_SIGNAL_FATAL
:
877 DPRINT1 ("AcpiOsBreakpoint: %d %d %d ****\n", FatalInfo
->Type
, FatalInfo
->Code
, FatalInfo
->Argument
);
879 DPRINT1 ("AcpiOsBreakpoint ****\n");
881 case ACPI_SIGNAL_BREAKPOINT
:
883 DPRINT1 ("AcpiOsBreakpoint: %s ****\n", Info
);
885 DPRINT1 ("AcpiOsBreakpoint ****\n");
900 DPRINT1("File reading not supported\n");