Fixed callback calling conventions (part 2).
[reactos.git] / reactos / 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 if ((ULONG)phys >= 0x100000) {
152 Address.QuadPart = (ULONG)phys;
153 *virt = MmMapIoSpace(Address, size, FALSE);
154 if (!*virt)
155 return AE_ERROR;
156 } else {
157 *virt = (PVOID)((ULONG)phys);
158 }
159
160 return AE_OK;
161 }
162
163 void
164 acpi_os_unmap_memory(void *virt, u32 size)
165 {
166 DPRINT("acpi_os_unmap_memory()\n");
167
168 if (virt == IVTVirtualAddress) {
169 /* Real mode Interrupt Vector Table */
170 ExFreePool(IVTVirtualAddress);
171 IVTVirtualAddress = NULL;
172 return;
173 }
174 /* FIXME: Causes "Memory area is NULL" bugcheck in marea.c */
175 //if ((ULONG)virt >= 0x100000)
176 //MmUnmapIoSpace(virt, size);
177 }
178
179 ACPI_STATUS
180 acpi_os_get_physical_address(void *virt, ACPI_PHYSICAL_ADDRESS *phys)
181 {
182 PHYSICAL_ADDRESS Address;
183
184 DPRINT("acpi_os_get_physical_address()\n");
185
186 if (!phys || !virt)
187 return AE_BAD_PARAMETER;
188
189 Address = MmGetPhysicalAddress(virt);
190
191 *phys = (ULONG)Address.QuadPart;
192
193 return AE_OK;
194 }
195
196 BOOLEAN STDCALL
197 OslIsrStub(
198 PKINTERRUPT Interrupt,
199 PVOID ServiceContext)
200 {
201 INT32 Status;
202
203 Status = (*AcpiIrqHandler)(AcpiIrqContext);
204
205 if (Status == INTERRUPT_HANDLED)
206 return TRUE;
207 else
208 return FALSE;
209 }
210
211 ACPI_STATUS
212 acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context)
213 {
214 ULONG Vector;
215 KIRQL DIrql;
216 KAFFINITY Affinity;
217 NTSTATUS Status;
218
219 DPRINT("acpi_os_install_interrupt_handler()\n");
220
221 Vector = HalGetInterruptVector(
222 Internal,
223 0,
224 0,
225 irq,
226 &DIrql,
227 &Affinity);
228
229 Status = IoConnectInterrupt(
230 &AcpiInterrupt,
231 OslIsrStub,
232 NULL,
233 NULL,
234 Vector,
235 DIrql,
236 DIrql,
237 LevelSensitive, /* FIXME: LevelSensitive or Latched? */
238 FALSE,
239 Affinity,
240 FALSE);
241 if (!NT_SUCCESS(Status)) {
242 DPRINT("Could not connect to interrupt %d\n", Vector);
243 return AE_ERROR;
244 }
245
246 AcpiIrqNumber = irq;
247 AcpiIrqHandler = handler;
248 AcpiIrqContext = context;
249 AcpiInterruptHandlerRegistered = TRUE;
250
251 return AE_OK;
252 }
253
254 ACPI_STATUS
255 acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler)
256 {
257 DPRINT("acpi_os_remove_interrupt_handler()\n");
258
259 if (AcpiInterruptHandlerRegistered) {
260 IoDisconnectInterrupt(AcpiInterrupt);
261 AcpiInterrupt = NULL;
262 AcpiInterruptHandlerRegistered = FALSE;
263 }
264
265 return AE_OK;
266 }
267
268 void
269 acpi_os_sleep(u32 sec, u32 ms)
270 {
271 /* FIXME: Wait */
272 }
273
274 void
275 acpi_os_sleep_usec(u32 us)
276 {
277 KeStallExecutionProcessor(us);
278 }
279
280 u8
281 acpi_os_in8(ACPI_IO_ADDRESS port)
282 {
283 return READ_PORT_UCHAR((PUCHAR)port);
284 }
285
286 u16
287 acpi_os_in16(ACPI_IO_ADDRESS port)
288 {
289 return READ_PORT_USHORT((PUSHORT)port);
290 }
291
292 u32
293 acpi_os_in32(ACPI_IO_ADDRESS port)
294 {
295 return READ_PORT_ULONG((PULONG)port);
296 }
297
298 void
299 acpi_os_out8(ACPI_IO_ADDRESS port, u8 val)
300 {
301 WRITE_PORT_UCHAR((PUCHAR)port, val);
302 }
303
304 void
305 acpi_os_out16(ACPI_IO_ADDRESS port, u16 val)
306 {
307 WRITE_PORT_USHORT((PUSHORT)port, val);
308 }
309
310 void
311 acpi_os_out32(ACPI_IO_ADDRESS port, u32 val)
312 {
313 WRITE_PORT_ULONG((PULONG)port, val);
314 }
315
316 UINT8
317 acpi_os_mem_in8 (ACPI_PHYSICAL_ADDRESS phys_addr)
318 {
319 return (*(PUCHAR)(ULONG)phys_addr);
320 }
321
322 UINT16
323 acpi_os_mem_in16 (ACPI_PHYSICAL_ADDRESS phys_addr)
324 {
325 return (*(PUSHORT)(ULONG)phys_addr);
326 }
327
328 UINT32
329 acpi_os_mem_in32 (ACPI_PHYSICAL_ADDRESS phys_addr)
330 {
331 return (*(PULONG)(ULONG)phys_addr);
332 }
333
334 void
335 acpi_os_mem_out8 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT8 value)
336 {
337 *(PUCHAR)(ULONG)phys_addr = value;
338 }
339
340 void
341 acpi_os_mem_out16 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT16 value)
342 {
343 *(PUSHORT)(ULONG)phys_addr = value;
344 }
345
346 void
347 acpi_os_mem_out32 (ACPI_PHYSICAL_ADDRESS phys_addr, UINT32 value)
348 {
349 *(PULONG)(ULONG)phys_addr = value;
350 }
351
352 ACPI_STATUS
353 acpi_os_read_pci_cfg_byte(
354 u32 bus,
355 u32 func,
356 u32 addr,
357 u8 * val)
358 {
359 /* FIXME: What do we do here? */
360
361 DPRINT("acpi_os_read_pci_cfg_byte is not implemented");
362
363 return AE_ERROR;
364 }
365
366 ACPI_STATUS
367 acpi_os_read_pci_cfg_word(
368 u32 bus,
369 u32 func,
370 u32 addr,
371 u16 * val)
372 {
373 /* FIXME: What do we do here? */
374
375 DPRINT("acpi_os_read_pci_cfg_word is not implemented");
376
377 return AE_ERROR;
378 }
379
380 ACPI_STATUS
381 acpi_os_read_pci_cfg_dword(
382 u32 bus,
383 u32 func,
384 u32 addr,
385 u32 * val)
386 {
387 /* FIXME: What do we do here? */
388
389 DPRINT("acpi_os_read_pci_cfg_dword is not implemented");
390
391 return AE_ERROR;
392 }
393
394 ACPI_STATUS
395 acpi_os_write_pci_cfg_byte(
396 u32 bus,
397 u32 func,
398 u32 addr,
399 u8 val)
400 {
401 /* FIXME: What do we do here? */
402
403 DPRINT("acpi_os_write_pci_cfg_byte is not implemented");
404
405 return AE_ERROR;
406 }
407
408 ACPI_STATUS
409 acpi_os_write_pci_cfg_word(
410 u32 bus,
411 u32 func,
412 u32 addr,
413 u16 val)
414 {
415 /* FIXME: What do we do here? */
416
417 DPRINT("acpi_os_write_pci_cfg_word is not implemented");
418
419 return AE_ERROR;
420 }
421
422 ACPI_STATUS
423 acpi_os_write_pci_cfg_dword(
424 u32 bus,
425 u32 func,
426 u32 addr,
427 u32 val)
428 {
429 /* FIXME: What do we do here? */
430
431 DPRINT("acpi_os_write_pci_cfg_dword is not implemented");
432
433 return AE_ERROR;
434 }
435
436 ACPI_STATUS
437 acpi_os_load_module (
438 char *module_name)
439 {
440 DPRINT("acpi_os_load_module()\n");
441
442 if (!module_name)
443 return AE_BAD_PARAMETER;
444
445 return AE_OK;
446 }
447
448 ACPI_STATUS
449 acpi_os_unload_module (
450 char *module_name)
451 {
452 DPRINT("acpi_os_unload_module()\n");
453
454 if (!module_name)
455 return AE_BAD_PARAMETER;
456
457 return AE_OK;
458 }
459
460 ACPI_STATUS
461 acpi_os_queue_for_execution(
462 u32 priority,
463 OSD_EXECUTION_CALLBACK function,
464 void *context)
465 {
466 ACPI_STATUS Status = AE_OK;
467
468 DPRINT("acpi_os_queue_for_execution()\n");
469
470 if (!function)
471 return AE_BAD_PARAMETER;
472
473 DPRINT("Scheduling task [%p](%p) for execution.\n", function, context);
474
475 #if 0
476 switch (priority) {
477 case OSD_PRIORITY_MED:
478 KeSetImportanceDpc(&AcpiDpc, MediumImportance);
479 case OSD_PRIORITY_LO:
480 KeSetImportanceDpc(&AcpiDpc, LowImportance);
481 case OSD_PRIORITY_HIGH:
482 default:
483 KeSetImportanceDpc(&AcpiDpc, HighImportance);
484 }
485 #endif
486
487 KeInsertQueueDpc(&AcpiDpc, (PVOID)function, (PVOID)context);
488
489 return Status;
490 }
491
492 ACPI_STATUS
493 acpi_os_create_semaphore(
494 u32 max_units,
495 u32 initial_units,
496 ACPI_HANDLE *handle)
497 {
498 PFAST_MUTEX Mutex;
499
500 Mutex = ExAllocatePool(NonPagedPool, sizeof(FAST_MUTEX));
501 if (!Mutex)
502 return AE_NO_MEMORY;
503
504 DPRINT("acpi_os_create_semaphore() at 0x%X\n", Mutex);
505
506 ExInitializeFastMutex(Mutex);
507
508 *handle = Mutex;
509 return AE_OK;
510 }
511
512 ACPI_STATUS
513 acpi_os_delete_semaphore(
514 ACPI_HANDLE handle)
515 {
516 PFAST_MUTEX Mutex = (PFAST_MUTEX)handle;
517
518 DPRINT("acpi_os_delete_semaphore(handle 0x%X)\n", handle);
519
520 if (!Mutex)
521 return AE_BAD_PARAMETER;
522
523 ExFreePool(Mutex);
524
525 return AE_OK;
526 }
527
528 ACPI_STATUS
529 acpi_os_wait_semaphore(
530 ACPI_HANDLE handle,
531 u32 units,
532 u32 timeout)
533 {
534 ACPI_STATUS Status = AE_OK;
535 PFAST_MUTEX Mutex = (PFAST_MUTEX)handle;
536
537 if (!Mutex || (units < 1)) {
538 DPRINT("acpi_os_wait_semaphore(handle 0x%X, units %d) Bad parameters\n",
539 handle, units);
540 return AE_BAD_PARAMETER;
541 }
542
543 DPRINT("Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout);
544
545 //ExAcquireFastMutex(Mutex);
546
547 return AE_OK;
548 }
549
550 ACPI_STATUS
551 acpi_os_signal_semaphore(
552 ACPI_HANDLE handle,
553 u32 units)
554 {
555 PFAST_MUTEX Mutex = (PFAST_MUTEX)handle;
556
557 if (!Mutex || (units < 1)) {
558 DPRINT("acpi_os_signal_semaphore(handle 0x%X) Bad parameter\n", handle);
559 return AE_BAD_PARAMETER;
560 }
561
562 DPRINT("Signaling semaphore[%p|%d]\n", handle, units);
563
564 //ExReleaseFastMutex(Mutex);
565
566 return AE_OK;
567 }
568
569 ACPI_STATUS
570 acpi_os_breakpoint(NATIVE_CHAR *msg)
571 {
572 DPRINT1("BREAKPOINT: %s", msg);
573 return AE_OK;
574 }
575
576 void
577 acpi_os_dbg_trap(char *msg)
578
579 {
580 DPRINT1("TRAP: %s", msg);
581 }
582
583 void
584 acpi_os_dbg_assert(void *failure, void *file, u32 line, NATIVE_CHAR *msg)
585 {
586 DPRINT1("ASSERT: %s\n", msg);
587 }
588
589 u32
590 acpi_os_get_line(NATIVE_CHAR *buffer)
591 {
592 return 0;
593 }
594
595 BOOLEAN
596 acpi_os_readable(void *ptr, u32 len)
597 {
598 /* Always readable */
599 return TRUE;
600 }
601
602 BOOLEAN
603 acpi_os_writable(void *ptr, u32 len)
604 {
605 /* Always writable */
606 return TRUE;
607 }
608
609 u32
610 acpi_os_get_thread_id (void)
611 {
612 return (ULONG)PsGetCurrentThreadId();
613 }