branch update for HEAD-2003021201
[reactos.git] / drivers / bus / acpi / ospm / osl.c
1 /*******************************************************************************
2 *                                                                              *
3 * ACPI Component Architecture Operating System Layer (OSL) for ReactOS         *
4 *                                                                              *
5 *******************************************************************************/
6
7 /*
8  *  Copyright (C) 2000 Andrew Henroid
9  *  Copyright (C) 2001 Andrew Grover
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  */
25 #include <acpisys.h>
26
27 #define NDEBUG
28 #include <debug.h>
29
30 static PKINTERRUPT AcpiInterrupt;
31 static BOOLEAN AcpiInterruptHandlerRegistered = FALSE;
32 static OSD_HANDLER AcpiIrqHandler = NULL;
33 static PVOID AcpiIrqContext = NULL;
34 static ULONG AcpiIrqNumber = 0;
35 static KDPC AcpiDpc;
36 static PVOID IVTVirtualAddress = NULL;
37 static PVOID BDAVirtualAddress = NULL;
38
39
40 VOID STDCALL
41 OslDpcStub(
42   IN PKDPC Dpc,
43   IN PVOID DeferredContext,
44   IN PVOID SystemArgument1,
45   IN PVOID SystemArgument2)
46 {
47   OSD_EXECUTION_CALLBACK Routine = (OSD_EXECUTION_CALLBACK)SystemArgument1;
48
49   DPRINT("OslDpcStub()\n");
50
51   DPRINT("Calling [%p]([%p])\n", Routine, SystemArgument2);
52
53   (*Routine)(SystemArgument2);
54 }
55
56
57 ACPI_STATUS
58 acpi_os_remove_interrupt_handler(
59   u32 irq,
60   OSD_HANDLER handler);
61
62
63 ACPI_STATUS
64 acpi_os_initialize(void)
65 {
66   DPRINT("acpi_os_initialize()\n");
67
68   KeInitializeDpc(&AcpiDpc, OslDpcStub, NULL);
69
70         return AE_OK;
71 }
72
73 ACPI_STATUS
74 acpi_os_terminate(void)
75 {
76   DPRINT("acpi_os_terminate()\n");
77
78   if (AcpiInterruptHandlerRegistered) {
79     acpi_os_remove_interrupt_handler(AcpiIrqNumber, AcpiIrqHandler);
80   }
81
82   return AE_OK;
83 }
84
85 s32
86 acpi_os_printf(const NATIVE_CHAR *fmt,...)
87 {
88         LONG Size;
89         va_list args;
90         va_start(args, fmt);
91         Size = acpi_os_vprintf(fmt, args);
92         va_end(args);
93         return Size;
94 }
95
96 s32
97 acpi_os_vprintf(const NATIVE_CHAR *fmt, va_list args)
98 {
99         static char Buffer[512];
100   LONG Size = vsprintf(Buffer, fmt, args);
101
102         DbgPrint("%s", Buffer);
103         return Size;
104 }
105
106 void *
107 acpi_os_allocate(u32 size)
108 {
109   return ExAllocatePool(NonPagedPool, size);
110 }
111
112 void *
113 acpi_os_callocate(u32 size)
114 {
115   PVOID ptr = ExAllocatePool(NonPagedPool, size);
116   if (ptr)
117     memset(ptr, 0, size);
118   return ptr;
119 }
120
121 void
122 acpi_os_free(void *ptr)
123 {
124   if (ptr) {
125     /* FIXME: There is at least one bug somewhere that
126               results in an attempt to release a null pointer */
127     ExFreePool(ptr);
128   }
129 }
130
131 ACPI_STATUS
132 acpi_os_map_memory(ACPI_PHYSICAL_ADDRESS phys, u32 size, void **virt)
133 {
134   PHYSICAL_ADDRESS Address;
135   PVOID Virtual;
136
137   DPRINT("acpi_os_map_memory(phys 0x%X  size 0x%X)\n", (ULONG)phys, size);
138
139   if (phys == 0x0) {
140     /* Real mode Interrupt Vector Table */
141     Virtual = ExAllocatePool(NonPagedPool, size);
142     if (NT_SUCCESS(NtVdmControl(0, Virtual))) {
143       IVTVirtualAddress = Virtual;
144       *virt = Virtual;
145       return AE_OK;
146     } else {
147       return AE_ERROR;
148     }
149   }
150
151   Address.QuadPart = (ULONG)phys;
152   *virt = MmMapIoSpace(Address, size, FALSE);
153   if (!*virt)
154     return AE_ERROR;
155  
156   return AE_OK;
157 }
158
159 void
160 acpi_os_unmap_memory(void *virt, u32 size)
161 {
162   DPRINT("acpi_os_unmap_memory()\n");
163
164   if (virt == IVTVirtualAddress) {
165     /* Real mode Interrupt Vector Table */
166     ExFreePool(IVTVirtualAddress);
167     IVTVirtualAddress = NULL;
168     return;
169   }
170   MmUnmapIoSpace(virt, size);
171 }
172
173 ACPI_STATUS
174 acpi_os_get_physical_address(void *virt, ACPI_PHYSICAL_ADDRESS *phys)
175 {
176   PHYSICAL_ADDRESS Address;
177
178   DPRINT("acpi_os_get_physical_address()\n");
179
180   if (!phys || !virt)
181     return AE_BAD_PARAMETER;
182
183   Address = MmGetPhysicalAddress(virt);
184
185   *phys = (ULONG)Address.QuadPart;
186
187   return AE_OK;
188 }
189
190 BOOLEAN STDCALL
191 OslIsrStub(
192   PKINTERRUPT Interrupt,
193   PVOID ServiceContext)
194 {
195   INT32 Status;
196
197   Status = (*AcpiIrqHandler)(AcpiIrqContext);
198
199   if (Status == INTERRUPT_HANDLED)
200     return TRUE;
201   else
202     return FALSE;
203 }
204
205 ACPI_STATUS
206 acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
207 {
208   ULONG Vector;
209   KIRQL DIrql;
210   KAFFINITY Affinity;
211   NTSTATUS Status;
212
213   DPRINT("acpi_os_install_interrupt_handler()\n");
214
215   Vector = HalGetInterruptVector(
216     Internal,
217     0,
218     0,
219     irq,
220     &DIrql,
221     &Affinity);
222
223   Status = IoConnectInterrupt(
224     &AcpiInterrupt,
225     OslIsrStub,
226     NULL,
227     NULL,
228     Vector,
229     DIrql,
230     DIrql,
231     LevelSensitive, /* FIXME: LevelSensitive or Latched? */
232     FALSE,
233     Affinity,
234     FALSE);
235   if (!NT_SUCCESS(Status)) {
236           DPRINT("Could not connect to interrupt %d\n", Vector);
237     return AE_ERROR;
238   }
239
240   AcpiIrqNumber = irq;
241   AcpiIrqHandler = handler;
242   AcpiIrqContext = context;
243   AcpiInterruptHandlerRegistered = TRUE;
244
245         return AE_OK;
246 }
247
248 ACPI_STATUS
249 acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
250 {
251   DPRINT("acpi_os_remove_interrupt_handler()\n");
252
253   if (AcpiInterruptHandlerRegistered) {
254     IoDisconnectInterrupt(AcpiInterrupt);
255     AcpiInterrupt = NULL;
256     AcpiInterruptHandlerRegistered = FALSE;
257   }
258
259   return AE_OK;
260 }
261
262 void
263 acpi_os_sleep(u32 sec, u32 ms)
264 {
265   /* FIXME: Wait */
266 }
267
268 void
269 acpi_os_sleep_usec(u32 us)
270 {
271   KeStallExecutionProcessor(us);
272 }
273
274 u8
275 acpi_os_in8(ACPI_IO_ADDRESS port)
276 {
277   return READ_PORT_UCHAR((PUCHAR)port);
278 }
279
280 u16
281 acpi_os_in16(ACPI_IO_ADDRESS port)
282 {
283   return READ_PORT_USHORT((PUSHORT)port);
284 }
285
286 u32
287 acpi_os_in32(ACPI_IO_ADDRESS port)
288 {
289   return READ_PORT_ULONG((PULONG)port);
290 }
291
292 void
293 acpi_os_out8(ACPI_IO_ADDRESS port, u8 val)
294 {
295   WRITE_PORT_UCHAR((PUCHAR)port, val);
296 }
297
298 void
299 acpi_os_out16(ACPI_IO_ADDRESS port, u16 val)
300 {
301   WRITE_PORT_USHORT((PUSHORT)port, val);
302 }
303
304 void
305 acpi_os_out32(ACPI_IO_ADDRESS port, u32 val)
306 {
307   WRITE_PORT_ULONG((PULONG)port, val);
308 }
309
310 UINT8
311 acpi_os_mem_in8 (ACPI_PHYSICAL_ADDRESS phys_addr)
312 {
313   return (*(PUCHAR)(ULONG)phys_addr);
314 }
315
316 UINT16
317 acpi_os_mem_in16 (ACPI_PHYSICAL_ADDRESS phys_addr)
318 {
319   return (*(PUSHORT)(ULONG)phys_addr);
320 }
321
322 UINT32
323 acpi_os_mem_in32 (ACPI_PHYSICAL_ADDRESS phys_addr)
324 {
325   return (*(PULONG)(ULONG)phys_addr);
326 }
327
328 void
329 acpi_os_mem_out8 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT8 value)
330 {
331   *(PUCHAR)(ULONG)phys_addr = value;
332 }
333
334 void
335 acpi_os_mem_out16 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT16 value)
336 {
337   *(PUSHORT)(ULONG)phys_addr = value;
338 }
339
340 void
341 acpi_os_mem_out32 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT32 value)
342 {
343   *(PULONG)(ULONG)phys_addr = value;
344 }
345
346 ACPI_STATUS
347 acpi_os_read_pci_cfg_byte(
348         u32 bus,
349         u32 func,
350         u32 addr,
351         u8 * val)
352 {
353   /* FIXME: What do we do here? */
354
355   DPRINT("acpi_os_read_pci_cfg_byte is not implemented");
356
357   return AE_ERROR;
358 }
359
360 ACPI_STATUS
361 acpi_os_read_pci_cfg_word(
362         u32 bus,
363         u32 func,
364         u32 addr,
365         u16 * val)
366 {
367   /* FIXME: What do we do here? */
368
369   DPRINT("acpi_os_read_pci_cfg_word is not implemented");
370
371   return AE_ERROR;
372 }
373
374 ACPI_STATUS
375 acpi_os_read_pci_cfg_dword(
376         u32 bus,
377         u32 func,
378         u32 addr,
379         u32 * val)
380 {
381   /* FIXME: What do we do here? */
382
383   DPRINT("acpi_os_read_pci_cfg_dword is not implemented");
384
385   return AE_ERROR;
386 }
387
388 ACPI_STATUS
389 acpi_os_write_pci_cfg_byte(
390         u32 bus,
391         u32 func,
392         u32 addr,
393         u8 val)
394 {
395   /* FIXME: What do we do here? */
396
397   DPRINT("acpi_os_write_pci_cfg_byte is not implemented");
398
399   return AE_ERROR;
400 }
401
402 ACPI_STATUS
403 acpi_os_write_pci_cfg_word(
404         u32 bus,
405         u32 func,
406         u32 addr,
407         u16 val)
408 {
409   /* FIXME: What do we do here? */
410
411   DPRINT("acpi_os_write_pci_cfg_word is not implemented");
412
413   return AE_ERROR;
414 }
415
416 ACPI_STATUS
417 acpi_os_write_pci_cfg_dword(
418         u32 bus,
419         u32 func,
420         u32 addr,
421         u32 val)
422 {
423   /* FIXME: What do we do here? */
424
425   DPRINT("acpi_os_write_pci_cfg_dword is not implemented");
426
427   return AE_ERROR;
428 }
429
430 ACPI_STATUS
431 acpi_os_load_module (
432         char *module_name)
433 {
434   DPRINT("acpi_os_load_module()\n");
435
436   if (!module_name)
437     return AE_BAD_PARAMETER;
438
439   return AE_OK;
440 }
441
442 ACPI_STATUS
443 acpi_os_unload_module (
444         char *module_name)
445 {
446   DPRINT("acpi_os_unload_module()\n");
447
448   if (!module_name)
449     return AE_BAD_PARAMETER;
450
451   return AE_OK;
452 }
453
454 ACPI_STATUS
455 acpi_os_queue_for_execution(
456         u32                     priority,
457         OSD_EXECUTION_CALLBACK  function,
458         void                    *context)
459 {
460   ACPI_STATUS Status = AE_OK;
461
462   DPRINT("acpi_os_queue_for_execution()\n");
463
464   if (!function)
465     return AE_BAD_PARAMETER;
466
467   DPRINT("Scheduling task [%p](%p) for execution.\n", function, context);
468
469 #if 0
470   switch (priority) {
471   case OSD_PRIORITY_MED:
472     KeSetImportanceDpc(&AcpiDpc, MediumImportance);
473   case OSD_PRIORITY_LO:
474     KeSetImportanceDpc(&AcpiDpc, LowImportance);
475   case OSD_PRIORITY_HIGH:
476   default:
477     KeSetImportanceDpc(&AcpiDpc, HighImportance);
478   }
479 #endif
480
481   KeInsertQueueDpc(&AcpiDpc, (PVOID)function, (PVOID)context);
482
483   return Status;
484 }
485
486 ACPI_STATUS
487 acpi_os_create_semaphore(
488         u32             max_units,
489         u32             initial_units,
490         ACPI_HANDLE     *handle)
491 {
492   PFAST_MUTEX Mutex;
493
494   Mutex = ExAllocatePool(NonPagedPool, sizeof(FAST_MUTEX));
495   if (!Mutex)
496     return AE_NO_MEMORY;
497
498   DPRINT("acpi_os_create_semaphore() at 0x%X\n", Mutex);
499
500   ExInitializeFastMutex(Mutex);
501
502   *handle = Mutex;
503   return AE_OK;
504 }
505
506 ACPI_STATUS
507 acpi_os_delete_semaphore(
508         ACPI_HANDLE handle)
509 {
510   PFAST_MUTEX Mutex = (PFAST_MUTEX)handle;
511
512   DPRINT("acpi_os_delete_semaphore(handle 0x%X)\n", handle);
513
514   if (!Mutex) 
515     return AE_BAD_PARAMETER;
516
517   ExFreePool(Mutex);
518
519   return AE_OK;
520 }
521
522 ACPI_STATUS
523 acpi_os_wait_semaphore(
524         ACPI_HANDLE     handle,
525         u32                     units,
526         u32                     timeout)
527 {
528   ACPI_STATUS Status = AE_OK;
529   PFAST_MUTEX Mutex = (PFAST_MUTEX)handle;
530
531   if (!Mutex || (units < 1)) {
532     DPRINT("acpi_os_wait_semaphore(handle 0x%X, units %d) Bad parameters\n",
533       handle, units);
534     return AE_BAD_PARAMETER;
535   }
536
537   DPRINT("Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout);
538
539   //ExAcquireFastMutex(Mutex);
540
541   return AE_OK;
542 }
543
544 ACPI_STATUS
545 acpi_os_signal_semaphore(
546     ACPI_HANDLE             handle, 
547     u32                     units)
548 {
549   PFAST_MUTEX Mutex = (PFAST_MUTEX)handle;
550
551   if (!Mutex || (units < 1)) {
552     DPRINT("acpi_os_signal_semaphore(handle 0x%X) Bad parameter\n", handle);
553     return AE_BAD_PARAMETER;
554   }
555
556   DPRINT("Signaling semaphore[%p|%d]\n", handle, units);
557
558   //ExReleaseFastMutex(Mutex);
559
560   return AE_OK;
561 }
562
563 ACPI_STATUS
564 acpi_os_breakpoint(NATIVE_CHAR *msg)
565 {
566         DPRINT1("BREAKPOINT: %s", msg);
567         return AE_OK;
568 }
569
570 void
571 acpi_os_dbg_trap(char *msg)
572
573 {
574   DPRINT1("TRAP: %s", msg);
575 }
576
577 void
578 acpi_os_dbg_assert(void *failure, void *file, u32 line, NATIVE_CHAR *msg)
579 {
580   DPRINT1("ASSERT: %s\n", msg);
581 }
582
583 u32
584 acpi_os_get_line(NATIVE_CHAR *buffer)
585 {
586         return 0;
587 }
588
589 u8
590 acpi_os_readable(void *ptr, u32 len)
591 {
592   /* Always readable */
593         return TRUE;
594 }
595
596 u8
597 acpi_os_writable(void *ptr, u32 len)
598 {
599   /* Always writable */
600         return TRUE;
601 }
602
603 u32
604 acpi_os_get_thread_id (void)
605 {
606   return (ULONG)PsGetCurrentThreadId();
607 }