-sync rsaenh_winetest with wine 1.1.32
[reactos.git] / reactos / hal / halamd64 / generic / hal.c
1 /*
2 * PROJECT: ReactOS HAL
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: hal/halarm/generic/hal.c
5 * PURPOSE: Hardware Abstraction Layer
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <hal.h>
12 #define NDEBUG
13 #include <debug.h>
14 #include <ndk/inbvfuncs.h>
15
16 #undef ExAcquireFastMutex
17 #undef ExReleaseFastMutex
18 #undef ExTryToAcquireFastMutex
19 #undef KeAcquireSpinLock
20 #undef KeLowerIrql
21 #undef KeRaiseIrql
22 #undef KeReleaseSpinLock
23
24 #define READ_REGISTER_ULONG(r) (*(volatile ULONG * const)(r))
25 #define WRITE_REGISTER_ULONG(r, v) (*(volatile ULONG *)(r) = (v))
26
27 /* DATA **********************************************************************/
28
29 ULONG HalpCurrentTimeIncrement, HalpNextTimeIncrement, HalpNextIntervalCount;
30 ULONG _KdComPortInUse = 0;
31
32 ULONG HalpIrqlTable[HIGH_LEVEL + 1] =
33 {
34 0xFFFFFFFF, // IRQL 0 PASSIVE_LEVEL
35 0xFFFFFFFD, // IRQL 1 APC_LEVEL
36 0xFFFFFFF9, // IRQL 2 DISPATCH_LEVEL
37 0xFFFFFFD9, // IRQL 3
38 0xFFFFFF99, // IRQL 4
39 0xFFFFFF19, // IRQL 5
40 0xFFFFFE19, // IRQL 6
41 0xFFFFFC19, // IRQL 7
42 0xFFFFF819, // IRQL 8
43 0xFFFFF019, // IRQL 9
44 0xFFFFE019, // IRQL 10
45 0xFFFFC019, // IRQL 11
46 0xFFFF8019, // IRQL 12
47 0xFFFF0019, // IRQL 13
48 0xFFFE0019, // IRQL 14
49 0xFFFC0019, // IRQL 15
50 0xFFF80019, // IRQL 16
51 0xFFF00019, // IRQL 17
52 0xFFE00019, // IRQL 18
53 0xFFC00019, // IRQL 19
54 0xFF800019, // IRQL 20
55 0xFF000019, // IRQL 21
56 0xFE000019, // IRQL 22
57 0xFC000019, // IRQL 23
58 0xF0000019, // IRQL 24
59 0x80000019, // IRQL 25
60 0x19, // IRQL 26
61 0x18, // IRQL 27 PROFILE_LEVEL
62 0x10, // IRQL 28 CLOCK2_LEVEL
63 0x00, // IRQL 29 IPI_LEVEL
64 0x00, // IRQL 30 POWER_LEVEL
65 0x00, // IRQL 31 HIGH_LEVEL
66 };
67
68 UCHAR HalpMaskTable[HIGH_LEVEL + 1] =
69 {
70 PROFILE_LEVEL, // INT 0 WATCHDOG
71 APC_LEVEL, // INT 1 SOFTWARE INTERRUPT
72 DISPATCH_LEVEL,// INT 2 COMM RX
73 IPI_LEVEL, // INT 3 COMM TX
74 CLOCK2_LEVEL, // INT 4 TIMER 0
75 3,
76 4,
77 5,
78 6,
79 7,
80 8,
81 9,
82 10,
83 11,
84 12,
85 13,
86 14,
87 15,
88 16,
89 17,
90 18,
91 19,
92 20,
93 21,
94 22,
95 23,
96 24,
97 25,
98 26,
99 26,
100 26
101 };
102
103 /* FUNCTIONS *****************************************************************/
104
105 NTSTATUS
106 NTAPI
107 DriverEntry(
108 PDRIVER_OBJECT DriverObject,
109 PUNICODE_STRING RegistryPath)
110 {
111 UNIMPLEMENTED;
112
113 return STATUS_SUCCESS;
114 }
115
116 /*
117 * @unimplemented
118 */
119 VOID
120 NTAPI
121 HalStopProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
122 {
123 UNIMPLEMENTED;
124 return;
125 }
126
127 /*
128 * @unimplemented
129 */
130 VOID
131 NTAPI
132 HalStartProfileInterrupt(IN KPROFILE_SOURCE ProfileSource)
133 {
134 UNIMPLEMENTED;
135 return;
136 }
137
138 /*
139 * @unimplemented
140 */
141 ULONG_PTR
142 NTAPI
143 HalSetProfileInterval(IN ULONG_PTR Interval)
144 {
145 UNIMPLEMENTED;
146 return Interval;
147 }
148
149 VOID
150 FASTCALL
151 ExAcquireFastMutex(
152 PFAST_MUTEX FastMutex)
153 {
154 UNIMPLEMENTED;
155 }
156
157
158 VOID
159 FASTCALL
160 ExReleaseFastMutex(
161 PFAST_MUTEX FastMutex)
162 {
163 UNIMPLEMENTED;
164 }
165
166
167 BOOLEAN FASTCALL
168 ExTryToAcquireFastMutex(
169 PFAST_MUTEX FastMutex)
170 {
171 UNIMPLEMENTED;
172
173 return TRUE;
174 }
175
176
177 NTSTATUS
178 NTAPI
179 HalAdjustResourceList(
180 PCM_RESOURCE_LIST Resources)
181 {
182 UNIMPLEMENTED;
183
184 return STATUS_SUCCESS;
185 }
186
187
188 /*
189 * @implemented
190 */
191 BOOLEAN
192 NTAPI
193 HalAllProcessorsStarted(VOID)
194 {
195 /* Do nothing */
196 return TRUE;
197 }
198
199
200 NTSTATUS
201 NTAPI
202 HalAllocateAdapterChannel(
203 PADAPTER_OBJECT AdapterObject,
204 PWAIT_CONTEXT_BLOCK WaitContextBlock,
205 ULONG NumberOfMapRegisters,
206 PDRIVER_CONTROL ExecutionRoutine)
207 {
208 UNIMPLEMENTED;
209
210 return STATUS_SUCCESS;
211 }
212
213
214 PVOID
215 NTAPI
216 HalAllocateCommonBuffer(
217 PADAPTER_OBJECT AdapterObject,
218 ULONG Length,
219 PPHYSICAL_ADDRESS LogicalAddress,
220 BOOLEAN CacheEnabled)
221 {
222 UNIMPLEMENTED;
223
224 return NULL;
225 }
226
227
228 PVOID
229 NTAPI
230 HalAllocateCrashDumpRegisters(
231 PADAPTER_OBJECT AdapterObject,
232 PULONG NumberOfMapRegisters)
233 {
234 UNIMPLEMENTED;
235 return NULL;
236 }
237
238
239 NTSTATUS
240 NTAPI
241 HalAssignSlotResources(
242 PUNICODE_STRING RegistryPath,
243 PUNICODE_STRING DriverClassName,
244 PDRIVER_OBJECT DriverObject,
245 PDEVICE_OBJECT DeviceObject,
246 INTERFACE_TYPE BusType,
247 ULONG BusNumber,
248 ULONG SlotNumber,
249 PCM_RESOURCE_LIST *AllocatedResources)
250 {
251 UNIMPLEMENTED;
252
253 return TRUE;
254 }
255
256
257 BOOLEAN
258 NTAPI
259 HalBeginSystemInterrupt (KIRQL Irql,
260 ULONG Vector,
261 PKIRQL OldIrql)
262 {
263 UNIMPLEMENTED;
264
265 return TRUE;
266 }
267
268
269 VOID
270 NTAPI
271 HalCalibratePerformanceCounter(
272 volatile LONG *Count,
273 ULONGLONG NewCount)
274 {
275 UNIMPLEMENTED;
276 }
277
278
279 BOOLEAN
280 NTAPI
281 HalDisableSystemInterrupt(
282 ULONG Vector,
283 KIRQL Irql)
284 {
285 UNIMPLEMENTED;
286
287 return TRUE;
288 }
289
290 VOID
291 NTAPI
292 HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
293 {
294 //
295 // Stub since Windows XP implemented Inbv
296 //
297 return;
298 }
299
300 VOID
301 NTAPI
302 HalDisplayString(IN PCH String)
303 {
304 //
305 // Call the Inbv driver
306 //
307 InbvDisplayString(String);
308 }
309
310 VOID
311 NTAPI
312 HalQueryDisplayParameters(OUT PULONG DispSizeX,
313 OUT PULONG DispSizeY,
314 OUT PULONG CursorPosX,
315 OUT PULONG CursorPosY)
316 {
317 //
318 // Stub since Windows XP implemented Inbv
319 //
320 return;
321 }
322
323 VOID
324 NTAPI
325 HalSetDisplayParameters(IN ULONG CursorPosX,
326 IN ULONG CursorPosY)
327 {
328 //
329 // Stub since Windows XP implemented Inbv
330 //
331 return;
332 }
333
334 BOOLEAN
335 NTAPI
336 HalEnableSystemInterrupt(
337 ULONG Vector,
338 KIRQL Irql,
339 KINTERRUPT_MODE InterruptMode)
340 {
341 UNIMPLEMENTED;
342
343 return TRUE;
344 }
345
346
347 VOID
348 NTAPI
349 HalEndSystemInterrupt(
350 KIRQL Irql,
351 ULONG Unknown2)
352 {
353 UNIMPLEMENTED;
354 }
355
356
357 BOOLEAN
358 NTAPI
359 HalFlushCommonBuffer(
360 ULONG Unknown1,
361 ULONG Unknown2,
362 ULONG Unknown3,
363 ULONG Unknown4,
364 ULONG Unknown5)
365 {
366 UNIMPLEMENTED;
367
368 return TRUE;
369 }
370
371
372 VOID
373 NTAPI
374 HalFreeCommonBuffer(
375 PADAPTER_OBJECT AdapterObject,
376 ULONG Length,
377 PHYSICAL_ADDRESS LogicalAddress,
378 PVOID VirtualAddress,
379 BOOLEAN CacheEnabled)
380 {
381 UNIMPLEMENTED;
382 }
383
384
385 PADAPTER_OBJECT
386 NTAPI
387 HalGetAdapter(
388 PDEVICE_DESCRIPTION DeviceDescription,
389 PULONG NumberOfMapRegisters)
390 {
391 UNIMPLEMENTED;
392
393 return (PADAPTER_OBJECT)NULL;
394 }
395
396
397 ULONG
398 NTAPI
399 HalGetBusData(
400 BUS_DATA_TYPE BusDataType,
401 ULONG BusNumber,
402 ULONG SlotNumber,
403 PVOID Buffer,
404 ULONG Length)
405 {
406 UNIMPLEMENTED;
407
408 return 0;
409 }
410
411
412 ULONG
413 NTAPI
414 HalGetBusDataByOffset(
415 BUS_DATA_TYPE BusDataType,
416 ULONG BusNumber,
417 ULONG SlotNumber,
418 PVOID Buffer,
419 ULONG Offset,
420 ULONG Length)
421 {
422 UNIMPLEMENTED;
423
424 return 0;
425 }
426
427
428 ARC_STATUS
429 NTAPI
430 HalGetEnvironmentVariable(
431 PCH Name,
432 USHORT ValueLength,
433 PCH Value)
434 {
435 UNIMPLEMENTED;
436
437 return ENOENT;
438 }
439
440
441 ULONG
442 NTAPI
443 HalGetInterruptVector(
444 INTERFACE_TYPE InterfaceType,
445 ULONG BusNumber,
446 ULONG BusInterruptLevel,
447 ULONG BusInterruptVector,
448 PKIRQL Irql,
449 PKAFFINITY Affinity)
450 {
451 UNIMPLEMENTED;
452
453 return 0;
454 }
455
456
457 VOID
458 NTAPI
459 HalHandleNMI(
460 PVOID NmiData)
461 {
462 UNIMPLEMENTED;
463 }
464
465 VOID
466 NTAPI
467 HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
468 {
469 PCHAR CommandLine;
470
471 /* Make sure we have a loader block and command line */
472 if ((LoaderBlock) && (LoaderBlock->LoadOptions))
473 {
474 /* Read the command line */
475 CommandLine = LoaderBlock->LoadOptions;
476
477 /* Check for initial breakpoint */
478 if (strstr(CommandLine, "BREAK")) DbgBreakPoint();
479 }
480 }
481
482 ULONG
483 HalGetInterruptSource(VOID)
484 {
485 ULONG InterruptStatus;
486
487 //
488 // Get the interrupt status, and return the highest bit set
489 //
490 InterruptStatus = READ_REGISTER_ULONG(VIC_INT_STATUS);
491 return 31 - _clz(InterruptStatus);
492 }
493
494 VOID
495 HalpClockInterrupt(VOID)
496 {
497 //
498 // Clear the interrupt
499 //
500 ASSERT(KeGetCurrentIrql() == CLOCK2_LEVEL);
501 WRITE_REGISTER_ULONG(TIMER0_INT_CLEAR, 1);
502
503 //
504 // FIXME: Update HAL Perf counters
505 //
506
507 //
508 // FIXME: Check if someone changed the clockrate
509 //
510
511 //
512 // Call the kernel
513 //
514 KeUpdateSystemTime(KeGetCurrentThread()->TrapFrame,
515 CLOCK2_LEVEL,
516 HalpCurrentTimeIncrement);
517
518 //
519 // We're done
520 //
521 }
522
523 VOID
524 HalpStallInterrupt(VOID)
525 {
526 //
527 // Clear the interrupt
528 //
529 WRITE_REGISTER_ULONG(TIMER0_INT_CLEAR, 1);
530 }
531
532 VOID
533 HalpInitializeInterrupts(VOID)
534 {
535 PKPCR Pcr = (PKPCR)KeGetPcr();
536 ULONG ClockInterval;
537 SP804_CONTROL_REGISTER ControlRegister;
538
539 //
540 // Fill out the IRQL mappings
541 //
542 RtlCopyMemory(Pcr->IrqlTable, HalpIrqlTable, sizeof(Pcr->IrqlTable));
543 RtlCopyMemory(Pcr->IrqlMask, HalpMaskTable, sizeof(Pcr->IrqlMask));
544
545 //
546 // Setup the clock and profile interrupt
547 //
548 Pcr->InterruptRoutine[CLOCK2_LEVEL] = HalpStallInterrupt;
549
550 //
551 // Configure the interval to 10ms
552 // (INTERVAL (10ms) * TIMCLKfreq (1MHz))
553 // --------------------------------------- == 10^4
554 // (TIMCLKENXdiv (1) * PRESCALEdiv (1))
555 //
556 ClockInterval = 0x2710;
557
558 //
559 // Configure the timer
560 //
561 ControlRegister.AsUlong = 0;
562 ControlRegister.Wide = TRUE;
563 ControlRegister.Periodic = TRUE;
564 ControlRegister.Interrupt = TRUE;
565 ControlRegister.Enabled = TRUE;
566
567 //
568 // Enable the timer
569 //
570 WRITE_REGISTER_ULONG(TIMER0_LOAD, ClockInterval);
571 WRITE_REGISTER_ULONG(TIMER0_CONTROL, ControlRegister.AsUlong);
572 }
573
574 /*
575 * @implemented
576 */
577 BOOLEAN
578 NTAPI
579 HalInitSystem(IN ULONG BootPhase,
580 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
581 {
582 PKPRCB Prcb = KeGetCurrentPrcb();
583
584 //
585 // Check the boot phase
586 //
587 if (!BootPhase)
588 {
589 //
590 // Get command-line parameters
591 //
592 HalpGetParameters(LoaderBlock);
593
594 #if DBG
595 //
596 // Checked HAL requires checked kernel
597 //
598 if (!(Prcb->BuildType & PRCB_BUILD_DEBUG))
599 {
600 //
601 // No match, bugcheck
602 //
603 KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 1, 0);
604 }
605 #else
606 //
607 // Release build requires release HAL
608 //
609 if (Prcb->BuildType & PRCB_BUILD_DEBUG)
610 {
611 //
612 // No match, bugcheck
613 //
614 KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0);
615 }
616 #endif
617
618 #ifdef CONFIG_SMP
619 //
620 // SMP HAL requires SMP kernel
621 //
622 if (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR)
623 {
624 //
625 // No match, bugcheck
626 //
627 KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0);
628 }
629 #endif
630
631 //
632 // Validate the PRCB
633 //
634 if (Prcb->MajorVersion != PRCB_MAJOR_VERSION)
635 {
636 //
637 // Validation failed, bugcheck
638 //
639 KeBugCheckEx(MISMATCHED_HAL, 1, Prcb->MajorVersion, 1, 0);
640 }
641
642 //
643 // Setup time increments to 10ms and 1ms
644 //
645 HalpCurrentTimeIncrement = 100000;
646 HalpNextTimeIncrement = 100000;
647 HalpNextIntervalCount = 0;
648 KeSetTimeIncrement(100000, 10000);
649
650 //
651 // Initialize interrupts
652 //
653 HalpInitializeInterrupts();
654 }
655 else if (BootPhase == 1)
656 {
657 //
658 // Switch to real clock interrupt
659 //
660 PCR->InterruptRoutine[CLOCK2_LEVEL] = HalpClockInterrupt;
661 }
662
663 //
664 // All done, return
665 //
666 return TRUE;
667 }
668
669
670 VOID
671 NTAPI
672 HalInitializeProcessor(IN ULONG ProcessorNumber,
673 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
674 {
675 //
676 // Nothing to do
677 //
678 return;
679 }
680
681
682 BOOLEAN
683 NTAPI
684 HalMakeBeep(
685 ULONG Frequency)
686 {
687 UNIMPLEMENTED;
688
689 return TRUE;
690 }
691
692
693 VOID
694 NTAPI
695 HalProcessorIdle(VOID)
696 {
697 UNIMPLEMENTED;
698 }
699
700
701 #define RTC_DATA (PVOID)0xE00E8000
702
703 BOOLEAN
704 NTAPI
705 HalQueryRealTimeClock(IN PTIME_FIELDS Time)
706 {
707 LARGE_INTEGER LargeTime;
708 ULONG Seconds;
709
710 //
711 // Query the RTC value
712 //
713 Seconds = READ_REGISTER_ULONG(RTC_DATA);
714
715 //
716 // Convert to time
717 //
718 RtlSecondsSince1970ToTime(Seconds, &LargeTime);
719
720 //
721 // Convert to time-fields
722 //
723 RtlTimeToTimeFields(&LargeTime, Time);
724 return TRUE;
725 }
726
727 ULONG
728 NTAPI
729 HalReadDmaCounter(
730 PADAPTER_OBJECT AdapterObject)
731 {
732 UNIMPLEMENTED;
733
734 return 0;
735 }
736
737
738 VOID
739 NTAPI
740 HalReportResourceUsage(VOID)
741 {
742 UNIMPLEMENTED;
743 }
744
745
746 VOID
747 NTAPI
748 HalRequestIpi(
749 ULONG Unknown)
750 {
751 UNIMPLEMENTED;
752 }
753
754
755 VOID
756 FASTCALL
757 HalRequestSoftwareInterrupt(IN KIRQL Request)
758 {
759 //
760 // Force a software interrupt
761 //
762 WRITE_REGISTER_ULONG(VIC_SOFT_INT, 1 << Request);
763 }
764
765 VOID
766 FASTCALL
767 HalClearSoftwareInterrupt(IN KIRQL Request)
768 {
769 //
770 // Clear a software interrupt
771 //
772 WRITE_REGISTER_ULONG(VIC_SOFT_INT_CLEAR, 1 << Request);
773 }
774
775 VOID
776 NTAPI
777 HalReturnToFirmware(
778 FIRMWARE_REENTRY Action)
779 {
780 UNIMPLEMENTED;
781 }
782
783
784 ULONG
785 NTAPI
786 HalSetBusData(
787 BUS_DATA_TYPE BusDataType,
788 ULONG BusNumber,
789 ULONG SlotNumber,
790 PVOID Buffer,
791 ULONG Length)
792 {
793 UNIMPLEMENTED;
794
795 return 0;
796 }
797
798
799 ULONG
800 NTAPI
801 HalSetBusDataByOffset(
802 BUS_DATA_TYPE BusDataType,
803 ULONG BusNumber,
804 ULONG SlotNumber,
805 PVOID Buffer,
806 ULONG Offset,
807 ULONG Length)
808 {
809 UNIMPLEMENTED;
810
811 return 0;
812 }
813
814
815 ARC_STATUS
816 NTAPI
817 HalSetEnvironmentVariable(
818 PCH Name,
819 PCH Value)
820 {
821 UNIMPLEMENTED;
822
823 return ESUCCESS;
824 }
825
826
827 BOOLEAN
828 NTAPI
829 HalSetRealTimeClock(
830 PTIME_FIELDS Time)
831 {
832 UNIMPLEMENTED;
833
834 return TRUE;
835 }
836
837
838 ULONG
839 NTAPI
840 HalSetTimeIncrement(
841 ULONG Increment)
842 {
843 UNIMPLEMENTED;
844
845 return Increment;
846 }
847
848
849 BOOLEAN
850 NTAPI
851 HalStartNextProcessor(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
852 IN PKPROCESSOR_STATE ProcessorState)
853 {
854 UNIMPLEMENTED;
855
856 return TRUE;
857 }
858
859
860 ULONG
861 FASTCALL
862 HalSystemVectorDispatchEntry(
863 ULONG Unknown1,
864 ULONG Unknown2,
865 ULONG Unknown3)
866 {
867 UNIMPLEMENTED;
868
869 return 0;
870 }
871
872
873 BOOLEAN
874 NTAPI
875 HalTranslateBusAddress(
876 INTERFACE_TYPE InterfaceType,
877 ULONG BusNumber,
878 PHYSICAL_ADDRESS BusAddress,
879 PULONG AddressSpace,
880 PPHYSICAL_ADDRESS TranslatedAddress)
881 {
882 UNIMPLEMENTED;
883
884 return TRUE;
885 }
886
887
888 VOID
889 NTAPI
890 HalpAssignDriveLetters(IN struct _LOADER_PARAMETER_BLOCK *LoaderBlock,
891 IN PSTRING NtDeviceName,
892 OUT PUCHAR NtSystemPath,
893 OUT PSTRING NtSystemPathString)
894 {
895 /* Call the kernel */
896 IoAssignDriveLetters(LoaderBlock,
897 NtDeviceName,
898 NtSystemPath,
899 NtSystemPathString);
900 }
901
902 NTSTATUS
903 NTAPI
904 HalpReadPartitionTable(IN PDEVICE_OBJECT DeviceObject,
905 IN ULONG SectorSize,
906 IN BOOLEAN ReturnRecognizedPartitions,
907 IN OUT PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
908 {
909 /* Call the kernel */
910 return IoReadPartitionTable(DeviceObject,
911 SectorSize,
912 ReturnRecognizedPartitions,
913 PartitionBuffer);
914 }
915
916 NTSTATUS
917 NTAPI
918 HalpWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
919 IN ULONG SectorSize,
920 IN ULONG SectorsPerTrack,
921 IN ULONG NumberOfHeads,
922 IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
923 {
924 /* Call the kernel */
925 return IoWritePartitionTable(DeviceObject,
926 SectorSize,
927 SectorsPerTrack,
928 NumberOfHeads,
929 PartitionBuffer);
930 }
931
932 NTSTATUS
933 NTAPI
934 HalpSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
935 IN ULONG SectorSize,
936 IN ULONG PartitionNumber,
937 IN ULONG PartitionType)
938 {
939 /* Call the kernel */
940 return IoSetPartitionInformation(DeviceObject,
941 SectorSize,
942 PartitionNumber,
943 PartitionType);
944 }
945
946
947 BOOLEAN
948 NTAPI
949 IoFlushAdapterBuffers(
950 PADAPTER_OBJECT AdapterObject,
951 PMDL Mdl,
952 PVOID MapRegisterBase,
953 PVOID CurrentVa,
954 ULONG Length,
955 BOOLEAN WriteToDevice)
956 {
957 UNIMPLEMENTED;
958
959 return TRUE;
960 }
961
962
963 VOID
964 NTAPI
965 IoFreeAdapterChannel(
966 PADAPTER_OBJECT AdapterObject)
967 {
968 UNIMPLEMENTED;
969 }
970
971
972 VOID
973 NTAPI
974 IoFreeMapRegisters(
975 PADAPTER_OBJECT AdapterObject,
976 PVOID MapRegisterBase,
977 ULONG NumberOfMapRegisters)
978 {
979 UNIMPLEMENTED;
980 }
981
982
983 PHYSICAL_ADDRESS
984 NTAPI
985 IoMapTransfer(
986 PADAPTER_OBJECT AdapterObject,
987 PMDL Mdl,
988 PVOID MapRegisterBase,
989 PVOID CurrentVa,
990 PULONG Length,
991 BOOLEAN WriteToDevice)
992 {
993 PHYSICAL_ADDRESS Address;
994
995 UNIMPLEMENTED;
996
997 Address.QuadPart = 0;
998
999 return Address;
1000 }
1001
1002 VOID
1003 NTAPI
1004 KeFlushWriteBuffer(VOID)
1005 {
1006 UNIMPLEMENTED;
1007 }
1008
1009 LARGE_INTEGER
1010 NTAPI
1011 KeQueryPerformanceCounter(
1012 PLARGE_INTEGER PerformanceFreq)
1013 {
1014 LARGE_INTEGER Value;
1015
1016 UNIMPLEMENTED;
1017
1018 Value.QuadPart = 0;
1019
1020 return Value;
1021 }
1022
1023 VOID
1024 NTAPI
1025 KeStallExecutionProcessor(IN ULONG Microseconds)
1026 {
1027 SP804_CONTROL_REGISTER ControlRegister;
1028
1029 //
1030 // Enable the timer
1031 //
1032 WRITE_REGISTER_ULONG(TIMER1_LOAD, Microseconds);
1033
1034 //
1035 // Configure the timer
1036 //
1037 ControlRegister.AsUlong = 0;
1038 ControlRegister.OneShot = TRUE;
1039 ControlRegister.Wide = TRUE;
1040 ControlRegister.Periodic = TRUE;
1041 ControlRegister.Enabled = TRUE;
1042 WRITE_REGISTER_ULONG(TIMER1_CONTROL, ControlRegister.AsUlong);
1043
1044 //
1045 // Now we will loop until the timer reached 0
1046 //
1047 while (READ_REGISTER_ULONG(TIMER1_VALUE));
1048 }
1049
1050 VOID
1051 FASTCALL
1052 KfLowerIrql(IN KIRQL NewIrql)
1053 {
1054 ULONG InterruptMask;
1055 ARM_STATUS_REGISTER Flags;
1056 PKPCR Pcr = (PKPCR)KeGetPcr();
1057
1058 //
1059 // Validate the new IRQL
1060 //
1061 Flags = KeArmStatusRegisterGet();
1062 _disable();
1063 ASSERT(NewIrql <= Pcr->CurrentIrql);
1064
1065 //
1066 // IRQLs are internally 8 bits
1067 //
1068 NewIrql &= 0xFF;
1069
1070 //
1071 // Setup the interrupt mask for this IRQL
1072 //
1073 InterruptMask = KeGetPcr()->IrqlTable[NewIrql];
1074 // DPRINT1("[LOWER] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
1075
1076 //
1077 // Clear interrupts associated to the old IRQL
1078 //
1079 WRITE_REGISTER_ULONG(VIC_INT_CLEAR, 0xFFFFFFFF);
1080
1081 //
1082 // Set the new interrupt mask
1083 // PL190 VIC support only for now
1084 //
1085 WRITE_REGISTER_ULONG(VIC_INT_ENABLE, InterruptMask);
1086
1087 //
1088 // Save the new IRQL
1089 //
1090 Pcr->CurrentIrql = NewIrql;
1091 if (!Flags.IrqDisable) _enable();
1092 }
1093
1094 KIRQL
1095 FASTCALL
1096 KfRaiseIrql(IN KIRQL NewIrql)
1097 {
1098 KIRQL OldIrql;
1099 ULONG InterruptMask;
1100 ARM_STATUS_REGISTER Flags;
1101 PKPCR Pcr = (PKPCR)KeGetPcr();
1102
1103 //
1104 // Save the current IRQL
1105 //
1106 Flags = KeArmStatusRegisterGet();
1107 _disable();
1108 OldIrql = Pcr->CurrentIrql;
1109
1110 //
1111 // IRQLs are internally 8 bits
1112 //
1113 NewIrql &= 0xFF;
1114
1115 //
1116 // Setup the interrupt mask for this IRQL
1117 //
1118 InterruptMask = KeGetPcr()->IrqlTable[NewIrql];
1119 // DPRINT1("[RAISE] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
1120 ASSERT(NewIrql >= OldIrql);
1121
1122 //
1123 // Clear interrupts associated to the old IRQL
1124 //
1125 WRITE_REGISTER_ULONG(VIC_INT_CLEAR, 0xFFFFFFFF);
1126
1127 //
1128 // Set the new interrupt mask
1129 // PL190 VIC support only for now
1130 //
1131 WRITE_REGISTER_ULONG(VIC_INT_ENABLE, InterruptMask);
1132
1133 //
1134 // Save the new IRQL
1135 //
1136 Pcr->CurrentIrql = NewIrql;
1137 if (!Flags.IrqDisable) _enable();
1138 return OldIrql;
1139 }
1140
1141 VOID
1142 NTAPI
1143 READ_PORT_BUFFER_UCHAR(
1144 PUCHAR Port,
1145 PUCHAR Buffer,
1146 ULONG Count)
1147 {
1148 UNIMPLEMENTED;
1149 }
1150
1151
1152 VOID
1153 NTAPI
1154 READ_PORT_BUFFER_ULONG(
1155 PULONG Port,
1156 PULONG Buffer,
1157 ULONG Count)
1158 {
1159 UNIMPLEMENTED;
1160 }
1161
1162
1163 VOID
1164 NTAPI
1165 READ_PORT_BUFFER_USHORT(
1166 PUSHORT Port,
1167 PUSHORT Buffer,
1168 ULONG Count)
1169 {
1170 UNIMPLEMENTED;
1171 }
1172
1173
1174 UCHAR
1175 NTAPI
1176 READ_PORT_UCHAR(
1177 PUCHAR Port)
1178 {
1179 UNIMPLEMENTED;
1180
1181 return 0;
1182 }
1183
1184
1185 ULONG
1186 NTAPI
1187 READ_PORT_ULONG(
1188 PULONG Port)
1189 {
1190 UNIMPLEMENTED;
1191
1192 return 0;
1193 }
1194
1195
1196 USHORT
1197 NTAPI
1198 READ_PORT_USHORT(
1199 PUSHORT Port)
1200 {
1201 UNIMPLEMENTED;
1202
1203 return 0;
1204 }
1205
1206
1207 VOID
1208 NTAPI
1209 WRITE_PORT_BUFFER_UCHAR(
1210 PUCHAR Port,
1211 PUCHAR Buffer,
1212 ULONG Count)
1213 {
1214 UNIMPLEMENTED;
1215 }
1216
1217
1218 VOID
1219 NTAPI
1220 WRITE_PORT_BUFFER_USHORT(
1221 PUSHORT Port,
1222 PUSHORT Buffer,
1223 ULONG Count)
1224 {
1225 UNIMPLEMENTED;
1226 }
1227
1228
1229 VOID
1230 NTAPI
1231 WRITE_PORT_BUFFER_ULONG(
1232 PULONG Port,
1233 PULONG Buffer,
1234 ULONG Count)
1235 {
1236 UNIMPLEMENTED;
1237 }
1238
1239
1240 VOID
1241 NTAPI
1242 WRITE_PORT_UCHAR(
1243 PUCHAR Port,
1244 UCHAR Value)
1245 {
1246 UNIMPLEMENTED;
1247 }
1248
1249 VOID
1250 NTAPI
1251 WRITE_PORT_ULONG(
1252 PULONG Port,
1253 ULONG Value)
1254 {
1255 UNIMPLEMENTED;
1256 }
1257
1258 VOID
1259 NTAPI
1260 WRITE_PORT_USHORT(
1261 PUSHORT Port,
1262 USHORT Value)
1263 {
1264 UNIMPLEMENTED;
1265 }
1266
1267 KIRQL
1268 KeRaiseIrqlToDpcLevel(VOID)
1269 {
1270 //
1271 // Call the generic routine
1272 //
1273 return KfRaiseIrql(DISPATCH_LEVEL);
1274 }
1275
1276 KIRQL
1277 KeRaiseIrqlToSynchLevel(VOID)
1278 {
1279 //
1280 // Call the generic routine
1281 //
1282 return KfRaiseIrql(DISPATCH_LEVEL);
1283 }
1284
1285 BOOLEAN HalpProcessorIdentified;
1286 BOOLEAN HalpTestCleanSupported;
1287
1288 VOID
1289 HalpIdentifyProcessor(VOID)
1290 {
1291 ARM_ID_CODE_REGISTER IdRegister;
1292
1293 //
1294 // Don't do it again
1295 //
1296 HalpProcessorIdentified = TRUE;
1297
1298 //
1299 // Read the ID Code
1300 //
1301 IdRegister = KeArmIdCodeRegisterGet();
1302
1303 //
1304 // Architecture "6" CPUs support test-and-clean (926EJ-S and 1026EJ-S)
1305 //
1306 HalpTestCleanSupported = (IdRegister.Architecture == 6);
1307 }
1308
1309 VOID
1310 HalSweepDcache(VOID)
1311 {
1312 //
1313 // We get called very early on, before HalInitSystem or any of the Hal*
1314 // processor routines, so we need to figure out what CPU we're on.
1315 //
1316 if (!HalpProcessorIdentified) HalpIdentifyProcessor();
1317
1318 //
1319 // Check if we can do it the ARMv5TE-J way
1320 //
1321 if (HalpTestCleanSupported)
1322 {
1323 //
1324 // Test, clean, flush D-Cache
1325 //
1326 __asm__ __volatile__ ("1: mrc p15, 0, pc, c7, c14, 3; bne 1b");
1327 }
1328 else
1329 {
1330 //
1331 // We need to do it it by set/way
1332 //
1333 UNIMPLEMENTED;
1334 }
1335 }
1336
1337 VOID
1338 HalSweepIcache(VOID)
1339 {
1340 //
1341 // All ARM cores support the same Icache flush command, no need for HAL work
1342 //
1343 KeArmFlushIcache();
1344 }
1345
1346 /*
1347 * @implemented
1348 */
1349 #undef KeGetCurrentIrql
1350 KIRQL
1351 NTAPI
1352 KeGetCurrentIrql(VOID)
1353 {
1354 /* Return IRQL */
1355 return PCR->CurrentIrql;
1356 }
1357
1358 /*
1359 * @implemented
1360 */
1361 VOID
1362 NTAPI
1363 KeLowerIrql(KIRQL NewIrql)
1364 {
1365 /* Call the fastcall function */
1366 KfLowerIrql(NewIrql);
1367 }
1368
1369 /*
1370 * @implemented
1371 */
1372 VOID
1373 NTAPI
1374 KeRaiseIrql(KIRQL NewIrql,
1375 PKIRQL OldIrql)
1376 {
1377 /* Call the fastcall function */
1378 *OldIrql = KfRaiseIrql(NewIrql);
1379 }
1380
1381 /*
1382 * @implemented
1383 */
1384 VOID
1385 NTAPI
1386 KeAcquireSpinLock(PKSPIN_LOCK SpinLock,
1387 PKIRQL OldIrql)
1388 {
1389 /* Call the fastcall function */
1390 *OldIrql = KfAcquireSpinLock(SpinLock);
1391 }
1392
1393 /*
1394 * @implemented
1395 */
1396 KIRQL
1397 FASTCALL
1398 KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
1399 {
1400 /* Simply raise to dispatch */
1401 return KfRaiseIrql(DISPATCH_LEVEL);
1402 }
1403
1404 /*
1405 * @implemented
1406 */
1407 VOID
1408 NTAPI
1409 KeReleaseSpinLock(PKSPIN_LOCK SpinLock,
1410 KIRQL NewIrql)
1411 {
1412 /* Call the fastcall function */
1413 KfReleaseSpinLock(SpinLock, NewIrql);
1414 }
1415
1416 /*
1417 * @implemented
1418 */
1419 KIRQL
1420 FASTCALL
1421 KfAcquireSpinLock(PKSPIN_LOCK SpinLock)
1422 {
1423 /* Simply raise to dispatch */
1424 return KfRaiseIrql(DISPATCH_LEVEL);
1425 }
1426
1427 /*
1428 * @implemented
1429 */
1430 VOID
1431 FASTCALL
1432 KfReleaseSpinLock(PKSPIN_LOCK SpinLock,
1433 KIRQL OldIrql)
1434 {
1435 /* Simply lower IRQL back */
1436 KfLowerIrql(OldIrql);
1437 }
1438
1439 /*
1440 * @implemented
1441 */
1442 KIRQL
1443 FASTCALL
1444 KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
1445 {
1446 /* Simply raise to dispatch */
1447 return KfRaiseIrql(DISPATCH_LEVEL);
1448 }
1449
1450 /*
1451 * @implemented
1452 */
1453 KIRQL
1454 FASTCALL
1455 KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
1456 {
1457 /* Simply raise to dispatch */
1458 return KfRaiseIrql(DISPATCH_LEVEL);
1459 }
1460
1461 /*
1462 * @implemented
1463 */
1464 VOID
1465 FASTCALL
1466 KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock,
1467 IN PKLOCK_QUEUE_HANDLE LockHandle)
1468 {
1469 /* Simply raise to dispatch */
1470 LockHandle->OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
1471 }
1472
1473 /*
1474 * @implemented
1475 */
1476 VOID
1477 FASTCALL
1478 KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock,
1479 IN PKLOCK_QUEUE_HANDLE LockHandle)
1480 {
1481 /* Simply raise to synch */
1482 LockHandle->OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
1483 }
1484
1485 /*
1486 * @implemented
1487 */
1488 VOID
1489 FASTCALL
1490 KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
1491 IN KIRQL OldIrql)
1492 {
1493 /* Simply lower IRQL back */
1494 KfLowerIrql(OldIrql);
1495 }
1496
1497 /*
1498 * @implemented
1499 */
1500 VOID
1501 FASTCALL
1502 KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
1503 {
1504 /* Simply lower IRQL back */
1505 KfLowerIrql(LockHandle->OldIrql);
1506 }
1507
1508 /*
1509 * @implemented
1510 */
1511 BOOLEAN
1512 FASTCALL
1513 KeTryToAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
1514 IN PKIRQL OldIrql)
1515 {
1516 /* Simply raise to dispatch */
1517 *OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
1518
1519 /* Always return true on UP Machines */
1520 return TRUE;
1521 }
1522
1523 /*
1524 * @implemented
1525 */
1526 LOGICAL
1527 FASTCALL
1528 KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
1529 OUT PKIRQL OldIrql)
1530 {
1531 /* Simply raise to dispatch */
1532 *OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
1533
1534 /* Always return true on UP Machines */
1535 return TRUE;
1536 }
1537
1538 /* EOF */