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