xref: /reactos/drivers/bus/acpi/osl.c (revision d5399189)
1 /*******************************************************************************
2 *                                                                              *
3 * ACPI Component Architecture Operating System Layer (OSL) for ReactOS         *
4 *                                                                              *
5 *******************************************************************************/
6 
7 #include "precomp.h"
8 
9 #include <pseh/pseh2.h>
10 
11 #define NDEBUG
12 #include <debug.h>
13 
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;
19 
20 ACPI_STATUS
21 AcpiOsInitialize (void)
22 {
23     DPRINT("AcpiOsInitialize called\n");
24 
25 #ifndef NDEBUG
26     /* Verboseness level of the acpica core */
27     AcpiDbgLevel = 0x00FFFFFF;
28     AcpiDbgLayer = 0xFFFFFFFF;
29 #endif
30 
31     return AE_OK;
32 }
33 
34 ACPI_STATUS
35 AcpiOsTerminate(void)
36 {
37     DPRINT("AcpiOsTerminate() called\n");
38 
39     return AE_OK;
40 }
41 
42 ACPI_PHYSICAL_ADDRESS
43 AcpiOsGetRootPointer (
44     void)
45 {
46     ACPI_PHYSICAL_ADDRESS pa = 0;
47 
48     DPRINT("AcpiOsGetRootPointer\n");
49 
50     AcpiFindRootPointer(&pa);
51     return pa;
52 }
53 
54 ACPI_STATUS
55 AcpiOsPredefinedOverride(
56     const ACPI_PREDEFINED_NAMES *PredefinedObject,
57     ACPI_STRING                 *NewValue)
58 {
59     if (!PredefinedObject || !NewValue)
60     {
61         DPRINT1("Invalid parameter\n");
62         return AE_BAD_PARAMETER;
63     }
64 
65     /* No override */
66     *NewValue = NULL;
67 
68     return AE_OK;
69 }
70 
71 ACPI_STATUS
72 AcpiOsTableOverride(
73     ACPI_TABLE_HEADER *ExistingTable,
74     ACPI_TABLE_HEADER **NewTable)
75 {
76     if (!ExistingTable || !NewTable)
77     {
78         DPRINT1("Invalid parameter\n");
79         return AE_BAD_PARAMETER;
80     }
81 
82     /* No override */
83     *NewTable = NULL;
84 
85     return AE_OK;
86 }
87 
88 ACPI_STATUS
89 AcpiOsPhysicalTableOverride(
90     ACPI_TABLE_HEADER       *ExistingTable,
91     ACPI_PHYSICAL_ADDRESS   *NewAddress,
92     UINT32                  *NewTableLength)
93 {
94     if (!ExistingTable || !NewAddress || !NewTableLength)
95     {
96         DPRINT1("Invalid parameter\n");
97         return AE_BAD_PARAMETER;
98     }
99 
100     /* No override */
101     *NewAddress     = 0;
102     *NewTableLength = 0;
103 
104     return AE_OK;
105 }
106 
107 void *
108 AcpiOsMapMemory (
109     ACPI_PHYSICAL_ADDRESS   phys,
110     ACPI_SIZE               length)
111 {
112     PHYSICAL_ADDRESS Address;
113     PVOID Ptr;
114 
115     DPRINT("AcpiOsMapMemory(phys 0x%p  size 0x%X)\n", phys, length);
116 
117     Address.QuadPart = (ULONG)phys;
118     Ptr = MmMapIoSpace(Address, length, MmNonCached);
119     if (!Ptr)
120     {
121         DPRINT1("Mapping failed\n");
122     }
123 
124     return Ptr;
125 }
126 
127 void
128 AcpiOsUnmapMemory (
129     void                    *virt,
130     ACPI_SIZE               length)
131 {
132     DPRINT("AcpiOsMapMemory(phys 0x%p  size 0x%X)\n", virt, length);
133 
134     ASSERT(virt);
135 
136     MmUnmapIoSpace(virt, length);
137 }
138 
139 ACPI_STATUS
140 AcpiOsGetPhysicalAddress(
141     void *LogicalAddress,
142     ACPI_PHYSICAL_ADDRESS *PhysicalAddress)
143 {
144     PHYSICAL_ADDRESS PhysAddr;
145 
146     if (!LogicalAddress || !PhysicalAddress)
147     {
148         DPRINT1("Bad parameter\n");
149         return AE_BAD_PARAMETER;
150     }
151 
152     PhysAddr = MmGetPhysicalAddress(LogicalAddress);
153 
154     *PhysicalAddress = (ACPI_PHYSICAL_ADDRESS)PhysAddr.QuadPart;
155 
156     return AE_OK;
157 }
158 
159 void *
160 AcpiOsAllocate (ACPI_SIZE size)
161 {
162     DPRINT("AcpiOsAllocate size %d\n",size);
163     return ExAllocatePoolWithTag(NonPagedPool, size, 'ipcA');
164 }
165 
166 void
167 AcpiOsFree(void *ptr)
168 {
169     if (!ptr)
170         DPRINT1("Attempt to free null pointer!!!\n");
171     ExFreePoolWithTag(ptr, 'ipcA');
172 }
173 
174 BOOLEAN
175 AcpiOsReadable(
176     void *Memory,
177     ACPI_SIZE Length)
178 {
179     BOOLEAN Ret = FALSE;
180 
181     _SEH2_TRY
182     {
183         ProbeForRead(Memory, Length, sizeof(UCHAR));
184         Ret = TRUE;
185     }
186     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
187     {
188         Ret = FALSE;
189     }
190     _SEH2_END;
191 
192     return Ret;
193 }
194 
195 BOOLEAN
196 AcpiOsWritable(
197     void *Memory,
198     ACPI_SIZE Length)
199 {
200     BOOLEAN Ret = FALSE;
201 
202     _SEH2_TRY
203     {
204         ProbeForWrite(Memory, Length, sizeof(UCHAR));
205         Ret = TRUE;
206     }
207     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
208     {
209         Ret = FALSE;
210     }
211     _SEH2_END;
212 
213     return Ret;
214 }
215 
216 ACPI_THREAD_ID
217 AcpiOsGetThreadId (void)
218 {
219     /* Thread ID must be non-zero */
220     return (ULONG_PTR)PsGetCurrentThreadId() + 1;
221 }
222 
223 ACPI_STATUS
224 AcpiOsExecute (
225     ACPI_EXECUTE_TYPE       Type,
226     ACPI_OSD_EXEC_CALLBACK  Function,
227     void                    *Context)
228 {
229     HANDLE ThreadHandle;
230     OBJECT_ATTRIBUTES ObjectAttributes;
231     NTSTATUS Status;
232 
233     DPRINT("AcpiOsExecute\n");
234 
235     InitializeObjectAttributes(&ObjectAttributes,
236                                NULL,
237                                OBJ_KERNEL_HANDLE,
238                                NULL,
239                                NULL);
240 
241     Status = PsCreateSystemThread(&ThreadHandle,
242                                   THREAD_ALL_ACCESS,
243                                   &ObjectAttributes,
244                                   NULL,
245                                   NULL,
246                                   (PKSTART_ROUTINE)Function,
247                                   Context);
248     if (!NT_SUCCESS(Status))
249         return AE_ERROR;
250 
251     ZwClose(ThreadHandle);
252 
253     return AE_OK;
254 }
255 
256 void
257 AcpiOsSleep (UINT64 milliseconds)
258 {
259     DPRINT("AcpiOsSleep %d\n", milliseconds);
260     KeStallExecutionProcessor(milliseconds*1000);
261 }
262 
263 void
264 AcpiOsStall (UINT32 microseconds)
265 {
266     DPRINT("AcpiOsStall %d\n",microseconds);
267     KeStallExecutionProcessor(microseconds);
268 }
269 
270 ACPI_STATUS
271 AcpiOsCreateMutex(
272     ACPI_MUTEX *OutHandle)
273 {
274     PFAST_MUTEX Mutex;
275 
276     if (!OutHandle)
277     {
278         DPRINT1("Bad parameter\n");
279         return AE_BAD_PARAMETER;
280     }
281 
282     Mutex = ExAllocatePoolWithTag(NonPagedPool, sizeof(FAST_MUTEX), 'LpcA');
283     if (!Mutex) return AE_NO_MEMORY;
284 
285     ExInitializeFastMutex(Mutex);
286 
287     *OutHandle = (ACPI_MUTEX)Mutex;
288 
289     return AE_OK;
290 }
291 
292 void
293 AcpiOsDeleteMutex(
294     ACPI_MUTEX Handle)
295 {
296     if (!Handle)
297     {
298         DPRINT1("Bad parameter\n");
299         return;
300     }
301 
302     ExFreePoolWithTag(Handle, 'LpcA');
303 }
304 
305 ACPI_STATUS
306 AcpiOsAcquireMutex(
307     ACPI_MUTEX Handle,
308     UINT16 Timeout)
309 {
310     if (!Handle)
311     {
312         DPRINT1("Bad parameter\n");
313         return AE_BAD_PARAMETER;
314     }
315 
316     /* Check what the caller wants us to do */
317     if (Timeout == ACPI_DO_NOT_WAIT)
318     {
319         /* Try to acquire without waiting */
320         if (!ExTryToAcquireFastMutex((PFAST_MUTEX)Handle))
321             return AE_TIME;
322     }
323     else
324     {
325         /* Block until we get it */
326         ExAcquireFastMutex((PFAST_MUTEX)Handle);
327     }
328 
329     return AE_OK;
330 }
331 
332 void
333 AcpiOsReleaseMutex(
334     ACPI_MUTEX Handle)
335 {
336     if (!Handle)
337     {
338         DPRINT1("Bad parameter\n");
339         return;
340     }
341 
342     ExReleaseFastMutex((PFAST_MUTEX)Handle);
343 }
344 
345 typedef struct _ACPI_SEM {
346     UINT32 CurrentUnits;
347     KEVENT Event;
348     KSPIN_LOCK Lock;
349 } ACPI_SEM, *PACPI_SEM;
350 
351 ACPI_STATUS
352 AcpiOsCreateSemaphore(
353     UINT32 MaxUnits,
354     UINT32 InitialUnits,
355     ACPI_SEMAPHORE *OutHandle)
356 {
357     PACPI_SEM Sem;
358 
359     if (!OutHandle)
360     {
361         DPRINT1("Bad parameter\n");
362         return AE_BAD_PARAMETER;
363     }
364 
365     Sem = ExAllocatePoolWithTag(NonPagedPool, sizeof(ACPI_SEM), 'LpcA');
366     if (!Sem) return AE_NO_MEMORY;
367 
368     Sem->CurrentUnits = InitialUnits;
369     KeInitializeEvent(&Sem->Event, SynchronizationEvent, Sem->CurrentUnits != 0);
370     KeInitializeSpinLock(&Sem->Lock);
371 
372     *OutHandle = (ACPI_SEMAPHORE)Sem;
373 
374     return AE_OK;
375 }
376 
377 ACPI_STATUS
378 AcpiOsDeleteSemaphore(
379     ACPI_SEMAPHORE Handle)
380 {
381     if (!Handle)
382     {
383         DPRINT1("Bad parameter\n");
384         return AE_BAD_PARAMETER;
385     }
386 
387     ExFreePoolWithTag(Handle, 'LpcA');
388 
389     return AE_OK;
390 }
391 
392 ACPI_STATUS
393 AcpiOsWaitSemaphore(
394     ACPI_SEMAPHORE Handle,
395     UINT32 Units,
396     UINT16 Timeout)
397 {
398     PACPI_SEM Sem = Handle;
399     KIRQL OldIrql;
400 
401     if (!Handle)
402     {
403         DPRINT1("Bad parameter\n");
404         return AE_BAD_PARAMETER;
405     }
406 
407     KeAcquireSpinLock(&Sem->Lock, &OldIrql);
408 
409     /* Make sure we can wait if we have fewer units than we need */
410     if ((Timeout == ACPI_DO_NOT_WAIT) && (Sem->CurrentUnits < Units))
411     {
412         /* We can't so we must bail now */
413         KeReleaseSpinLock(&Sem->Lock, OldIrql);
414         return AE_TIME;
415     }
416 
417     /* Time to block until we get enough units */
418     while (Sem->CurrentUnits < Units)
419     {
420         KeReleaseSpinLock(&Sem->Lock, OldIrql);
421         KeWaitForSingleObject(&Sem->Event,
422                               Executive,
423                               KernelMode,
424                               FALSE,
425                               NULL);
426         KeAcquireSpinLock(&Sem->Lock, &OldIrql);
427     }
428 
429     Sem->CurrentUnits -= Units;
430 
431     if (Sem->CurrentUnits != 0) KeSetEvent(&Sem->Event, IO_NO_INCREMENT, FALSE);
432 
433     KeReleaseSpinLock(&Sem->Lock, OldIrql);
434 
435     return AE_OK;
436 }
437 
438 ACPI_STATUS
439 AcpiOsSignalSemaphore(
440     ACPI_SEMAPHORE Handle,
441     UINT32 Units)
442 {
443     PACPI_SEM Sem = Handle;
444     KIRQL OldIrql;
445 
446     if (!Handle)
447     {
448         DPRINT1("Bad parameter\n");
449         return AE_BAD_PARAMETER;
450     }
451 
452     KeAcquireSpinLock(&Sem->Lock, &OldIrql);
453 
454     Sem->CurrentUnits += Units;
455     KeSetEvent(&Sem->Event, IO_NO_INCREMENT, FALSE);
456 
457     KeReleaseSpinLock(&Sem->Lock, OldIrql);
458 
459     return AE_OK;
460 }
461 
462 ACPI_STATUS
463 AcpiOsCreateLock(
464     ACPI_SPINLOCK *OutHandle)
465 {
466     PKSPIN_LOCK SpinLock;
467 
468     if (!OutHandle)
469     {
470         DPRINT1("Bad parameter\n");
471         return AE_BAD_PARAMETER;
472     }
473 
474     SpinLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSPIN_LOCK), 'LpcA');
475     if (!SpinLock) return AE_NO_MEMORY;
476 
477     KeInitializeSpinLock(SpinLock);
478 
479     *OutHandle = (ACPI_SPINLOCK)SpinLock;
480 
481     return AE_OK;
482 }
483 
484 void
485 AcpiOsDeleteLock(
486     ACPI_SPINLOCK Handle)
487 {
488     if (!Handle)
489     {
490         DPRINT1("Bad parameter\n");
491         return;
492     }
493 
494     ExFreePoolWithTag(Handle, 'LpcA');
495 }
496 
497 ACPI_CPU_FLAGS
498 AcpiOsAcquireLock(
499     ACPI_SPINLOCK Handle)
500 {
501     KIRQL OldIrql;
502 
503     if ((OldIrql = KeGetCurrentIrql()) >= DISPATCH_LEVEL)
504     {
505         KeAcquireSpinLockAtDpcLevel((PKSPIN_LOCK)Handle);
506     }
507     else
508     {
509         KeAcquireSpinLock((PKSPIN_LOCK)Handle, &OldIrql);
510     }
511 
512     return (ACPI_CPU_FLAGS)OldIrql;
513 }
514 
515 void
516 AcpiOsReleaseLock(
517     ACPI_SPINLOCK Handle,
518     ACPI_CPU_FLAGS Flags)
519 {
520     KIRQL OldIrql = (KIRQL)Flags;
521 
522     if (OldIrql >= DISPATCH_LEVEL)
523     {
524         KeReleaseSpinLockFromDpcLevel((PKSPIN_LOCK)Handle);
525     }
526     else
527     {
528         KeReleaseSpinLock((PKSPIN_LOCK)Handle, OldIrql);
529     }
530 }
531 
532 BOOLEAN NTAPI
533 OslIsrStub(
534   PKINTERRUPT Interrupt,
535   PVOID ServiceContext)
536 {
537   INT32 Status;
538 
539   Status = (*AcpiIrqHandler)(AcpiIrqContext);
540 
541   if (Status == ACPI_INTERRUPT_HANDLED)
542     return TRUE;
543   else
544     return FALSE;
545 }
546 
547 UINT32
548 AcpiOsInstallInterruptHandler (
549     UINT32                  InterruptNumber,
550     ACPI_OSD_HANDLER        ServiceRoutine,
551     void                    *Context)
552 {
553     ULONG Vector;
554     KIRQL DIrql;
555     KAFFINITY Affinity;
556     NTSTATUS Status;
557 
558     if (AcpiInterruptHandlerRegistered)
559     {
560         DPRINT1("Reregister interrupt attempt failed\n");
561         return AE_ALREADY_EXISTS;
562     }
563 
564     if (!ServiceRoutine)
565     {
566         DPRINT1("Bad parameter\n");
567         return AE_BAD_PARAMETER;
568     }
569 
570     DPRINT("AcpiOsInstallInterruptHandler()\n");
571     Vector = HalGetInterruptVector(
572         Internal,
573         0,
574         InterruptNumber,
575         InterruptNumber,
576         &DIrql,
577         &Affinity);
578 
579     AcpiIrqNumber = InterruptNumber;
580     AcpiIrqHandler = ServiceRoutine;
581     AcpiIrqContext = Context;
582     AcpiInterruptHandlerRegistered = TRUE;
583 
584     Status = IoConnectInterrupt(
585         &AcpiInterrupt,
586         OslIsrStub,
587         NULL,
588         NULL,
589         Vector,
590         DIrql,
591         DIrql,
592         LevelSensitive,
593         TRUE,
594         Affinity,
595         FALSE);
596 
597     if (!NT_SUCCESS(Status))
598     {
599         DPRINT("Could not connect to interrupt %d\n", Vector);
600         return AE_ERROR;
601     }
602     return AE_OK;
603 }
604 
605 ACPI_STATUS
606 AcpiOsRemoveInterruptHandler (
607     UINT32                  InterruptNumber,
608     ACPI_OSD_HANDLER        ServiceRoutine)
609 {
610     DPRINT("AcpiOsRemoveInterruptHandler()\n");
611 
612     if (!ServiceRoutine)
613     {
614         DPRINT1("Bad parameter\n");
615         return AE_BAD_PARAMETER;
616     }
617 
618     if (AcpiInterruptHandlerRegistered)
619     {
620         IoDisconnectInterrupt(AcpiInterrupt);
621         AcpiInterrupt = NULL;
622         AcpiInterruptHandlerRegistered = FALSE;
623     }
624     else
625     {
626         DPRINT1("Trying to remove non-existing interrupt handler\n");
627         return AE_NOT_EXIST;
628     }
629 
630     return AE_OK;
631 }
632 
633 ACPI_STATUS
634 AcpiOsReadMemory (
635     ACPI_PHYSICAL_ADDRESS   Address,
636     UINT64                  *Value,
637     UINT32                  Width)
638 {
639     DPRINT("AcpiOsReadMemory %p\n", Address);
640     switch (Width)
641     {
642     case 8:
643         *Value = (*(PUCHAR)(ULONG_PTR)Address);
644         break;
645 
646     case 16:
647         *Value = (*(PUSHORT)(ULONG_PTR)Address);
648         break;
649 
650     case 32:
651         *Value = (*(PULONG)(ULONG_PTR)Address);
652         break;
653 
654     case 64:
655         *Value = (*(PULONGLONG)(ULONG_PTR)Address);
656         break;
657 
658     default:
659         DPRINT1("AcpiOsReadMemory got bad width: %d\n",Width);
660         return (AE_BAD_PARAMETER);
661         break;
662     }
663     return (AE_OK);
664 }
665 
666 ACPI_STATUS
667 AcpiOsWriteMemory (
668     ACPI_PHYSICAL_ADDRESS   Address,
669     UINT64                  Value,
670     UINT32                  Width)
671 {
672     DPRINT("AcpiOsWriteMemory %p\n", Address);
673     switch (Width)
674     {
675     case 8:
676         *(PUCHAR)(ULONG_PTR)Address = Value;
677         break;
678 
679     case 16:
680         *(PUSHORT)(ULONG_PTR)Address = Value;
681         break;
682 
683     case 32:
684         *(PULONG)(ULONG_PTR)Address = Value;
685         break;
686 
687     case 64:
688         *(PULONGLONG)(ULONG_PTR)Address = Value;
689         break;
690 
691     default:
692         DPRINT1("AcpiOsWriteMemory got bad width: %d\n",Width);
693         return (AE_BAD_PARAMETER);
694         break;
695     }
696 
697     return (AE_OK);
698 }
699 
700 ACPI_STATUS
701 AcpiOsReadPort (
702     ACPI_IO_ADDRESS         Address,
703     UINT32                  *Value,
704     UINT32                  Width)
705 {
706     DPRINT("AcpiOsReadPort %p, width %d\n",Address,Width);
707 
708     switch (Width)
709     {
710     case 8:
711         *Value = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)Address);
712         break;
713 
714     case 16:
715         *Value = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)Address);
716         break;
717 
718     case 32:
719         *Value = READ_PORT_ULONG((PULONG)(ULONG_PTR)Address);
720         break;
721 
722     default:
723         DPRINT1("AcpiOsReadPort got bad width: %d\n",Width);
724         return (AE_BAD_PARAMETER);
725         break;
726     }
727     return (AE_OK);
728 }
729 
730 ACPI_STATUS
731 AcpiOsWritePort (
732     ACPI_IO_ADDRESS         Address,
733     UINT32                  Value,
734     UINT32                  Width)
735 {
736     DPRINT("AcpiOsWritePort %p, width %d\n",Address,Width);
737     switch (Width)
738     {
739     case 8:
740         WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)Address, Value);
741         break;
742 
743     case 16:
744         WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)Address, Value);
745         break;
746 
747     case 32:
748         WRITE_PORT_ULONG((PULONG)(ULONG_PTR)Address, Value);
749         break;
750 
751     default:
752         DPRINT1("AcpiOsWritePort got bad width: %d\n",Width);
753         return (AE_BAD_PARAMETER);
754         break;
755     }
756     return (AE_OK);
757 }
758 
759 BOOLEAN
760 OslIsPciDevicePresent(ULONG BusNumber, ULONG SlotNumber)
761 {
762     UINT32 ReadLength;
763     PCI_COMMON_CONFIG PciConfig;
764 
765     /* Detect device presence by reading the PCI configuration space */
766 
767     ReadLength = HalGetBusDataByOffset(PCIConfiguration,
768                                        BusNumber,
769                                        SlotNumber,
770                                        &PciConfig,
771                                        0,
772                                        sizeof(PciConfig));
773     if (ReadLength == 0)
774     {
775         DPRINT("PCI device is not present\n");
776         return FALSE;
777     }
778 
779     ASSERT(ReadLength >= 2);
780 
781     if (PciConfig.VendorID == PCI_INVALID_VENDORID)
782     {
783         DPRINT("Invalid vendor ID in PCI configuration space\n");
784         return FALSE;
785     }
786 
787     DPRINT("PCI device is present\n");
788 
789     return TRUE;
790 }
791 
792 ACPI_STATUS
793 AcpiOsReadPciConfiguration (
794     ACPI_PCI_ID             *PciId,
795     UINT32                  Reg,
796     UINT64                  *Value,
797     UINT32                  Width)
798 {
799     PCI_SLOT_NUMBER slot;
800 
801     slot.u.AsULONG = 0;
802     slot.u.bits.DeviceNumber = PciId->Device;
803     slot.u.bits.FunctionNumber = PciId->Function;
804 
805     DPRINT("AcpiOsReadPciConfiguration, slot=0x%X, func=0x%X\n", slot.u.AsULONG, Reg);
806 
807     if (!OslIsPciDevicePresent(PciId->Bus, slot.u.AsULONG))
808         return AE_NOT_FOUND;
809 
810     /* Width is in BITS */
811     HalGetBusDataByOffset(PCIConfiguration,
812         PciId->Bus,
813         slot.u.AsULONG,
814         Value,
815         Reg,
816         (Width >> 3));
817 
818     return AE_OK;
819 }
820 
821 ACPI_STATUS
822 AcpiOsWritePciConfiguration (
823     ACPI_PCI_ID              *PciId,
824     UINT32                   Reg,
825     UINT64                   Value,
826     UINT32                   Width)
827 {
828     ULONG buf = Value;
829     PCI_SLOT_NUMBER slot;
830 
831     slot.u.AsULONG = 0;
832     slot.u.bits.DeviceNumber = PciId->Device;
833     slot.u.bits.FunctionNumber = PciId->Function;
834 
835     DPRINT("AcpiOsWritePciConfiguration, slot=0x%x\n", slot.u.AsULONG);
836     if (!OslIsPciDevicePresent(PciId->Bus, slot.u.AsULONG))
837         return AE_NOT_FOUND;
838 
839     /* Width is in BITS */
840     HalSetBusDataByOffset(PCIConfiguration,
841         PciId->Bus,
842         slot.u.AsULONG,
843         &buf,
844         Reg,
845         (Width >> 3));
846 
847     return AE_OK;
848 }
849 
850 void ACPI_INTERNAL_VAR_XFACE
851 AcpiOsPrintf (
852     const char              *Fmt,
853     ...)
854 {
855     va_list                 Args;
856     va_start (Args, Fmt);
857 
858     AcpiOsVprintf (Fmt, Args);
859 
860     va_end (Args);
861     return;
862 }
863 
864 void
865 AcpiOsVprintf (
866     const char              *Fmt,
867     va_list                 Args)
868 {
869 #ifndef NDEBUG
870     vDbgPrintEx (-1, DPFLTR_ERROR_LEVEL, Fmt, Args);
871 #endif
872     return;
873 }
874 
875 void
876 AcpiOsRedirectOutput(
877     void *Destination)
878 {
879     /* No-op */
880     DPRINT1("Output redirection not supported\n");
881 }
882 
883 UINT64
884 AcpiOsGetTimer(
885     void)
886 {
887     LARGE_INTEGER CurrentTime;
888 
889     KeQuerySystemTime(&CurrentTime);
890     return CurrentTime.QuadPart;
891 }
892 
893 void
894 AcpiOsWaitEventsComplete(void)
895 {
896     /*
897      * Wait for all asynchronous events to complete.
898      * This implementation does nothing.
899      */
900     return;
901 }
902 
903 ACPI_STATUS
904 AcpiOsSignal (
905     UINT32                  Function,
906     void                    *Info)
907 {
908     ACPI_SIGNAL_FATAL_INFO *FatalInfo = Info;
909 
910     switch (Function)
911     {
912     case ACPI_SIGNAL_FATAL:
913         if (Info)
914             DPRINT1 ("AcpiOsBreakpoint: %d %d %d ****\n", FatalInfo->Type, FatalInfo->Code, FatalInfo->Argument);
915         else
916             DPRINT1 ("AcpiOsBreakpoint ****\n");
917         break;
918     case ACPI_SIGNAL_BREAKPOINT:
919         if (Info)
920             DPRINT1 ("AcpiOsBreakpoint: %s ****\n", Info);
921         else
922             DPRINT1 ("AcpiOsBreakpoint ****\n");
923         break;
924     }
925 
926     ASSERT(FALSE);
927 
928     return (AE_OK);
929 }
930 
931 ACPI_STATUS
932 AcpiOsEnterSleep(
933     UINT8 SleepState,
934     UINT32 RegaValue,
935     UINT32 RegbValue)
936 {
937     DPRINT1("Entering sleep state S%u.\n", SleepState);
938     return AE_OK;
939 }
940 
941 ACPI_STATUS
942 AcpiOsGetLine(
943     char *Buffer,
944     UINT32 BufferLength,
945     UINT32 *BytesRead)
946 {
947     DPRINT1("File reading not supported\n");
948     return AE_ERROR;
949 }
950