- Update to new ACPI driver by Samuel Serapion (and fixes by me)
[reactos.git] / reactos / drivers / bus / acpi / acpica / osl / osl.c
1 /*******************************************************************************
2 * *
3 * ACPI Component Architecture Operating System Layer (OSL) for ReactOS *
4 * *
5 *******************************************************************************/
6
7 #include <acpi.h>
8
9 #define NDEBUG
10 #include <debug.h>
11
12 #define NUM_SEMAPHORES 128
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 static KDPC AcpiDpc;
20 static PVOID IVTVirtualAddress = NULL;
21
22
23 typedef struct semaphore_entry
24 {
25 UINT16 MaxUnits;
26 UINT16 CurrentUnits;
27 void *OsHandle;
28 } SEMAPHORE_ENTRY;
29
30 static SEMAPHORE_ENTRY AcpiGbl_Semaphores[NUM_SEMAPHORES];
31
32 VOID NTAPI
33 OslDpcStub(
34 IN PKDPC Dpc,
35 IN PVOID DeferredContext,
36 IN PVOID SystemArgument1,
37 IN PVOID SystemArgument2)
38 {
39 ACPI_OSD_EXEC_CALLBACK Routine = (ACPI_OSD_EXEC_CALLBACK)SystemArgument1;
40
41 DPRINT("OslDpcStub()\n");
42 DPRINT("Calling [%p]([%p])\n", Routine, SystemArgument2);
43 (*Routine)(SystemArgument2);
44 }
45
46 BOOLEAN NTAPI
47 OslIsrStub(
48 PKINTERRUPT Interrupt,
49 PVOID ServiceContext)
50 {
51 INT32 Status;
52
53 Status = (*AcpiIrqHandler)(AcpiIrqContext);
54
55 if (ACPI_SUCCESS(Status))
56 return TRUE;
57 else
58 return FALSE;
59 }
60
61 ACPI_STATUS
62 AcpiOsRemoveInterruptHandler (
63 UINT32 InterruptNumber,
64 ACPI_OSD_HANDLER ServiceRoutine);
65
66 ACPI_STATUS
67 AcpiOsInitialize (void)
68 {
69 DPRINT("AcpiOsInitialize called\n");
70
71 #ifndef NDEBUG
72 /* Verboseness level of the acpica core */
73 AcpiDbgLevel = 0x00FFFFFF;
74 AcpiDbgLayer = 0xFFFFFFFF;
75 #endif
76
77 UINT32 i;
78
79 for (i = 0; i < NUM_SEMAPHORES; i++)
80 {
81 AcpiGbl_Semaphores[i].OsHandle = NULL;
82 }
83
84 KeInitializeDpc(&AcpiDpc, OslDpcStub, NULL);
85
86 return AE_OK;
87 }
88
89 ACPI_STATUS
90 AcpiOsTerminate(void)
91 {
92 DPRINT1("AcpiOsTerminate() called\n");
93
94 if (AcpiInterruptHandlerRegistered)
95 AcpiOsRemoveInterruptHandler(AcpiIrqNumber, AcpiIrqHandler);
96
97 return AE_OK;
98 }
99
100 void ACPI_INTERNAL_VAR_XFACE
101 AcpiOsPrintf (
102 const char *Fmt,
103 ...)
104 {
105 va_list Args;
106 va_start (Args, Fmt);
107
108 AcpiOsVprintf (Fmt, Args);
109
110 va_end (Args);
111 return;
112 }
113
114 void
115 AcpiOsVprintf (
116 const char *Fmt,
117 va_list Args)
118 {
119 vDbgPrintEx (-1, DPFLTR_ERROR_LEVEL, Fmt, Args);
120 return;
121 }
122
123 void *
124 AcpiOsAllocate (ACPI_SIZE size)
125 {
126 DPRINT("AcpiOsAllocate size %d\n",size);
127 return ExAllocatePool(NonPagedPool, size);
128 }
129
130 void *
131 AcpiOsCallocate(ACPI_SIZE size)
132 {
133 PVOID ptr = ExAllocatePool(NonPagedPool, size);
134 if (ptr)
135 memset(ptr, 0, size);
136 return ptr;
137 }
138
139 void
140 AcpiOsFree(void *ptr)
141 {
142 if (!ptr)
143 DPRINT1("Attempt to free null pointer!!!\n");
144 ExFreePool(ptr);
145 }
146
147 #ifndef ACPI_USE_LOCAL_CACHE
148
149 void*
150 AcpiOsAcquireObjectHelper (
151 POOL_TYPE PoolType,
152 SIZE_T NumberOfBytes,
153 ULONG Tag)
154 {
155 void* Alloc = ExAllocatePool(PoolType, NumberOfBytes);
156
157 /* acpica expects memory allocated from cache to be zeroed */
158 RtlZeroMemory(Alloc,NumberOfBytes);
159 return Alloc;
160 }
161
162 ACPI_STATUS
163 AcpiOsCreateCache (
164 char *CacheName,
165 UINT16 ObjectSize,
166 UINT16 MaxDepth,
167 ACPI_CACHE_T **ReturnCache)
168 {
169 PNPAGED_LOOKASIDE_LIST Lookaside =
170 ExAllocatePool(NonPagedPool,sizeof(NPAGED_LOOKASIDE_LIST));
171
172 ExInitializeNPagedLookasideList(Lookaside,
173 (PALLOCATE_FUNCTION)AcpiOsAcquireObjectHelper,// custom memory allocator
174 NULL,
175 0,
176 ObjectSize,
177 'IPCA',
178 0);
179 *ReturnCache = (ACPI_CACHE_T *)Lookaside;
180
181 DPRINT("AcpiOsCreateCache %p\n", Lookaside);
182 return (AE_OK);
183 }
184
185 ACPI_STATUS
186 AcpiOsDeleteCache (
187 ACPI_CACHE_T *Cache)
188 {
189 DPRINT("AcpiOsDeleteCache %p\n", Cache);
190 ExDeleteNPagedLookasideList(
191 (PNPAGED_LOOKASIDE_LIST) Cache);
192 ExFreePool(Cache);
193 return (AE_OK);
194 }
195
196 ACPI_STATUS
197 AcpiOsPurgeCache (
198 ACPI_CACHE_T *Cache)
199 {
200 DPRINT("AcpiOsPurgeCache\n");
201 /* No such functionality for LookAside lists */
202 return (AE_OK);
203 }
204
205 void *
206 AcpiOsAcquireObject (
207 ACPI_CACHE_T *Cache)
208 {
209 PNPAGED_LOOKASIDE_LIST List = (PNPAGED_LOOKASIDE_LIST)Cache;
210 DPRINT("AcpiOsAcquireObject from %p\n", Cache);
211 void* ptr =
212 ExAllocateFromNPagedLookasideList(List);
213 ASSERT(ptr);
214
215 RtlZeroMemory(ptr,List->L.Size);
216 return ptr;
217 }
218
219 ACPI_STATUS
220 AcpiOsReleaseObject (
221 ACPI_CACHE_T *Cache,
222 void *Object)
223 {
224 DPRINT("AcpiOsReleaseObject %p from %p\n",Object, Cache);
225 ExFreeToNPagedLookasideList(
226 (PNPAGED_LOOKASIDE_LIST)Cache,
227 Object);
228 return (AE_OK);
229 }
230
231 #endif
232
233 void *
234 AcpiOsMapMemory (
235 ACPI_PHYSICAL_ADDRESS phys,
236 ACPI_SIZE length)
237 {
238 PHYSICAL_ADDRESS Address;
239
240 DPRINT("AcpiOsMapMemory(phys 0x%X size 0x%X)\n", (ULONG)phys, length);
241 if (phys == 0x0)
242 {
243 IVTVirtualAddress = ExAllocatePool(NonPagedPool, length);
244 return IVTVirtualAddress;
245 }
246
247 Address.QuadPart = (ULONG)phys;
248 return MmMapIoSpace(Address, length, MmNonCached);
249 }
250
251 void
252 AcpiOsUnmapMemory (
253 void *virt,
254 ACPI_SIZE length)
255 {
256 DPRINT("AcpiOsUnmapMemory()\n");
257
258 if (virt == 0x0)
259 {
260 ExFreePool(IVTVirtualAddress);
261 return;
262 }
263 MmUnmapIoSpace(virt, length);
264 }
265
266 UINT32
267 AcpiOsInstallInterruptHandler (
268 UINT32 InterruptNumber,
269 ACPI_OSD_HANDLER ServiceRoutine,
270 void *Context)
271 {
272 ULONG Vector;
273 KIRQL DIrql;
274 KAFFINITY Affinity;
275 NTSTATUS Status;
276
277 DPRINT("AcpiOsInstallInterruptHandler()\n");
278 Vector = HalGetInterruptVector(
279 Internal,
280 0,
281 InterruptNumber,
282 0,
283 &DIrql,
284 &Affinity);
285
286 AcpiIrqNumber = InterruptNumber;
287 AcpiIrqHandler = ServiceRoutine;
288 AcpiIrqContext = Context;
289 AcpiInterruptHandlerRegistered = TRUE;
290
291 Status = IoConnectInterrupt(
292 &AcpiInterrupt,
293 OslIsrStub,
294 NULL,
295 NULL,
296 Vector,
297 DIrql,
298 DIrql,
299 LevelSensitive, /* FIXME: LevelSensitive or Latched? */
300 TRUE,
301 Affinity,
302 FALSE);
303
304 if (!NT_SUCCESS(Status))
305 {
306 DPRINT("Could not connect to interrupt %d\n", Vector);
307 return AE_ERROR;
308 }
309 return AE_OK;
310 }
311
312 ACPI_STATUS
313 AcpiOsRemoveInterruptHandler (
314 UINT32 InterruptNumber,
315 ACPI_OSD_HANDLER ServiceRoutine)
316 {
317 DPRINT("AcpiOsRemoveInterruptHandler()\n");
318 if (AcpiInterruptHandlerRegistered)
319 {
320 IoDisconnectInterrupt(AcpiInterrupt);
321 AcpiInterrupt = NULL;
322 AcpiInterruptHandlerRegistered = FALSE;
323 }
324
325 return AE_OK;
326 }
327
328 void
329 AcpiOsStall (UINT32 microseconds)
330 {
331 DPRINT1("AcpiOsStall %d\n",microseconds);
332 KeStallExecutionProcessor(microseconds);
333 return;
334 }
335
336 void
337 AcpiOsSleep (ACPI_INTEGER milliseconds)
338 {
339 DPRINT1("AcpiOsSleep %d\n", milliseconds);
340 KeStallExecutionProcessor(milliseconds*1000);
341 return;
342 }
343
344 ACPI_STATUS
345 AcpiOsReadPort (
346 ACPI_IO_ADDRESS Address,
347 UINT32 *Value,
348 UINT32 Width)
349 {
350 DPRINT("AcpiOsReadPort %p, width %d\n",Address,Width);
351
352 switch (Width)
353 {
354 case 8:
355 *Value = READ_PORT_UCHAR((PUCHAR)Address);
356 break;
357
358 case 16:
359 *Value = READ_PORT_USHORT((PUSHORT)Address);
360 break;
361
362 case 32:
363 *Value = READ_PORT_ULONG((PULONG)Address);
364 break;
365 default:
366 DPRINT1("AcpiOsReadPort got bad width: %d\n",Width);
367 return (AE_BAD_PARAMETER);
368 break;
369 }
370 return (AE_OK);
371 }
372
373 ACPI_STATUS
374 AcpiOsWritePort (
375 ACPI_IO_ADDRESS Address,
376 UINT32 Value,
377 UINT32 Width)
378 {
379 DPRINT("AcpiOsWritePort %p, width %d\n",Address,Width);
380 switch (Width)
381 {
382 case 8:
383 WRITE_PORT_UCHAR((PUCHAR)Address, Value);
384 break;
385
386 case 16:
387 WRITE_PORT_USHORT((PUSHORT)Address, Value);
388 break;
389
390 case 32:
391 WRITE_PORT_ULONG((PULONG)Address, Value);
392 break;
393
394 default:
395 DPRINT1("AcpiOsWritePort got bad width: %d\n",Width);
396 return (AE_BAD_PARAMETER);
397 break;
398 }
399 return (AE_OK);
400 }
401
402 ACPI_STATUS
403 AcpiOsReadMemory (
404 ACPI_PHYSICAL_ADDRESS Address,
405 UINT32 *Value,
406 UINT32 Width)
407 {
408 DPRINT("AcpiOsReadMemory %p\n", Address);
409 switch (Width)
410 {
411 case 8:
412 *Value = (*(PUCHAR)(ULONG)Address);
413 break;
414 case 16:
415 *Value = (*(PUSHORT)(ULONG)Address);
416 break;
417 case 32:
418 *Value = (*(PULONG)(ULONG)Address);
419 break;
420
421 default:
422 DPRINT1("AcpiOsReadMemory got bad width: %d\n",Width);
423 return (AE_BAD_PARAMETER);
424 break;
425 }
426 return (AE_OK);
427 }
428
429
430 ACPI_STATUS
431 AcpiOsWriteMemory (
432 ACPI_PHYSICAL_ADDRESS Address,
433 UINT32 Value,
434 UINT32 Width)
435 {
436 DPRINT("AcpiOsWriteMemory %p\n", Address);
437 switch (Width)
438 {
439 case 8:
440 *(PUCHAR)(ULONG)Address = Value;
441 break;
442 case 16:
443 *(PUSHORT)(ULONG)Address = Value;
444 break;
445 case 32:
446 *(PULONG)(ULONG)Address = Value;
447 break;
448
449 default:
450 DPRINT1("AcpiOsWriteMemory got bad width: %d\n",Width);
451 return (AE_BAD_PARAMETER);
452 break;
453 }
454
455 return (AE_OK);
456 }
457
458 ACPI_STATUS
459 AcpiOsReadPciConfiguration (
460 ACPI_PCI_ID *PciId,
461 UINT32 Register,
462 void *Value,
463 UINT32 Width)
464 {
465 NTSTATUS Status;
466 PCI_SLOT_NUMBER slot;
467
468 if (Register == 0)
469 return AE_ERROR;
470
471 slot.u.AsULONG = 0;
472 slot.u.bits.DeviceNumber = PciId->Bus;
473 slot.u.bits.FunctionNumber = PciId->Function;
474
475 DPRINT("AcpiOsReadPciConfiguration, slot=0x%X, func=0x%X\n", slot.u.AsULONG, Register);
476 Status = HalGetBusDataByOffset(PCIConfiguration,
477 PciId->Bus,
478 slot.u.AsULONG,
479 Value,
480 Register,
481 Width);
482
483 if (NT_SUCCESS(Status))
484 return AE_OK;
485 else
486 return AE_ERROR;
487 }
488
489 ACPI_STATUS
490 AcpiOsWritePciConfiguration (
491 ACPI_PCI_ID *PciId,
492 UINT32 Register,
493 ACPI_INTEGER Value,
494 UINT32 Width)
495 {
496 NTSTATUS Status;
497 ULONG buf = Value;
498 PCI_SLOT_NUMBER slot;
499
500 if (Register == 0)
501 return AE_ERROR;
502
503 slot.u.AsULONG = 0;
504 slot.u.bits.DeviceNumber = PciId->Bus;
505 slot.u.bits.FunctionNumber = PciId->Function;
506
507 DPRINT("AcpiOsWritePciConfiguration, slot=0x%x\n", slot.u.AsULONG);
508 Status = HalSetBusDataByOffset(PCIConfiguration,
509 PciId->Bus,
510 slot.u.AsULONG,
511 &buf,
512 Register,
513 Width);
514
515 if (NT_SUCCESS(Status))
516 return AE_OK;
517 else
518 return AE_ERROR;
519 }
520
521 ACPI_STATUS
522 AcpiOsCreateSemaphore (
523 UINT32 MaxUnits,
524 UINT32 InitialUnits,
525 ACPI_SEMAPHORE *OutHandle)
526 {
527 PFAST_MUTEX Mutex;
528
529 Mutex = ExAllocatePool(NonPagedPool, sizeof(FAST_MUTEX));
530 if (!Mutex)
531 return AE_NO_MEMORY;
532
533 DPRINT("AcpiOsCreateSemaphore() at 0x%X\n", Mutex);
534
535 ExInitializeFastMutex(Mutex);
536
537 *OutHandle = Mutex;
538 return AE_OK;
539 }
540
541 ACPI_STATUS
542 AcpiOsDeleteSemaphore (
543 ACPI_SEMAPHORE Handle)
544 {
545 PFAST_MUTEX Mutex = (PFAST_MUTEX)Handle;
546
547 DPRINT("AcpiOsDeleteSemaphore(handle 0x%X)\n", Handle);
548
549 if (!Mutex)
550 return AE_BAD_PARAMETER;
551
552 ExFreePool(Mutex);
553 return AE_OK;
554 }
555
556 ACPI_STATUS
557 AcpiOsWaitSemaphore(
558 ACPI_SEMAPHORE Handle,
559 UINT32 units,
560 UINT16 timeout)
561 {
562 PFAST_MUTEX Mutex = (PFAST_MUTEX)Handle;
563
564 if (!Mutex || (units < 1))
565 {
566 DPRINT("AcpiOsWaitSemaphore(handle 0x%X, units %d) Bad parameters\n",
567 Mutex, units);
568 return AE_BAD_PARAMETER;
569 }
570
571 DPRINT("Waiting for semaphore %p\n", Handle);
572 ASSERT(Mutex);
573
574 ExAcquireFastMutex(Mutex);
575 return AE_OK;
576 }
577
578 ACPI_STATUS
579 AcpiOsSignalSemaphore (
580 ACPI_HANDLE Handle,
581 UINT32 Units)
582 {
583 PFAST_MUTEX Mutex = (PFAST_MUTEX)Handle;
584
585 DPRINT("AcpiOsSignalSemaphore %p\n",Handle);
586 ASSERT(Mutex);
587
588 ExReleaseFastMutex(Mutex);
589 return AE_OK;
590 }
591
592 ACPI_STATUS
593 AcpiOsCreateLock (
594 ACPI_SPINLOCK *OutHandle)
595 {
596 DPRINT("AcpiOsCreateLock\n");
597 return (AcpiOsCreateSemaphore (1, 1, OutHandle));
598 }
599
600 void
601 AcpiOsDeleteLock (
602 ACPI_SPINLOCK Handle)
603 {
604 DPRINT("AcpiOsDeleteLock %p\n", Handle);
605 AcpiOsDeleteSemaphore (Handle);
606 }
607
608
609 ACPI_CPU_FLAGS
610 AcpiOsAcquireLock (
611 ACPI_HANDLE Handle)
612 {
613 DPRINT("AcpiOsAcquireLock, %p\n", Handle);
614 AcpiOsWaitSemaphore (Handle, 1, 0xFFFF);
615 return (0);
616 }
617
618
619 void
620 AcpiOsReleaseLock (
621 ACPI_SPINLOCK Handle,
622 ACPI_CPU_FLAGS Flags)
623 {
624 DPRINT("AcpiOsReleaseLock %p\n",Handle);
625 AcpiOsSignalSemaphore (Handle, 1);
626 }
627
628 ACPI_STATUS
629 AcpiOsSignal (
630 UINT32 Function,
631 void *Info)
632 {
633
634 switch (Function)
635 {
636 case ACPI_SIGNAL_FATAL:
637 if (Info)
638 AcpiOsPrintf ("AcpiOsBreakpoint: %s ****\n", Info);
639 else
640 AcpiOsPrintf ("AcpiOsBreakpoint ****\n");
641 break;
642 case ACPI_SIGNAL_BREAKPOINT:
643 if (Info)
644 AcpiOsPrintf ("AcpiOsBreakpoint: %s ****\n", Info);
645 else
646 AcpiOsPrintf ("AcpiOsBreakpoint ****\n");
647 break;
648 }
649
650 return (AE_OK);
651 }
652
653
654 ACPI_THREAD_ID
655 AcpiOsGetThreadId (void)
656 {
657 return (ULONG)PsGetCurrentThreadId();
658 }
659
660 ACPI_STATUS
661 AcpiOsExecute (
662 ACPI_EXECUTE_TYPE Type,
663 ACPI_OSD_EXEC_CALLBACK Function,
664 void *Context)
665 {
666 DPRINT1("AcpiOsExecute\n");
667
668 KeInsertQueueDpc(&AcpiDpc, (PVOID)Function, (PVOID)Context);
669
670 #ifdef _MULTI_THREADED
671 //_beginthread (Function, (unsigned) 0, Context);
672 #endif
673
674 return 0;
675 }
676
677 UINT64
678 AcpiOsGetTimer (void)
679 {
680 DPRINT("AcpiOsGetTimer\n");
681 LARGE_INTEGER Timer;
682 KeQueryTickCount(&Timer);
683
684 return Timer.QuadPart;
685 }
686
687 void
688 AcpiOsDerivePciId(
689 ACPI_HANDLE rhandle,
690 ACPI_HANDLE chandle,
691 ACPI_PCI_ID **PciId)
692 {
693 DPRINT("AcpiOsDerivePciId\n");
694 return;
695 }
696
697 ACPI_STATUS
698 AcpiOsPredefinedOverride (
699 const ACPI_PREDEFINED_NAMES *InitVal,
700 ACPI_STRING *NewVal)
701 {
702 if (!InitVal || !NewVal)
703 return AE_BAD_PARAMETER;
704
705 *NewVal = ACPI_OS_NAME;
706 DPRINT("AcpiOsPredefinedOverride\n");
707 return AE_OK;
708 }
709
710 ACPI_PHYSICAL_ADDRESS
711 AcpiOsGetRootPointer (
712 void);
713
714 ACPI_STATUS
715 AcpiOsTableOverride (
716 ACPI_TABLE_HEADER *ExistingTable,
717 ACPI_TABLE_HEADER **NewTable)
718 {
719 DPRINT("AcpiOsTableOverride\n");
720 *NewTable = NULL;
721 return (AE_OK);
722 }
723
724 ACPI_STATUS
725 AcpiOsValidateInterface (
726 char *Interface)
727 {
728 DPRINT("AcpiOsValidateInterface\n");
729 return (AE_OK);
730 }
731
732 ACPI_STATUS
733 AcpiOsValidateAddress (
734 UINT8 SpaceId,
735 ACPI_PHYSICAL_ADDRESS Address,
736 ACPI_SIZE Length)
737 {
738 DPRINT("AcpiOsValidateAddress\n");
739 return (AE_OK);
740 }
741
742 ACPI_PHYSICAL_ADDRESS
743 AcpiOsGetRootPointer (
744 void)
745 {
746 DPRINT("AcpiOsGetRootPointer\n");
747 ACPI_PHYSICAL_ADDRESS pa = 0;
748
749 AcpiFindRootPointer(&pa);
750 return pa;
751 }