Author: ros-arm-bringup
Date: Thu Mar 13 11:29:45 2008
New Revision: 32674
URL:
http://svn.reactos.org/svn/reactos?rev=3D32674&view=3Drev
Log:
- Implement IRQL functions for the PL190 VIC.
- Start coding HalInitSystem.
- Implement HalRequestSoftwareInterrupt for the PL190 VIC. The interrupt fi=
res! (This interrupt is responsible for forcing DPC delivery, which should =
also force thread scheduling, which should force the switch to the phase 1 =
thread)
Modified:
trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c
trunk/reactos/hal/halarm/generic/hal.c
trunk/reactos/include/reactos/armddk.h
Modified: trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/=
arch/arm/loader.c?rev=3D32674&r1=3D32673&r2=3D32674&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/arm/loader.c Thu Mar 13 11:29:4=
5 2008
@@ -742,7 +742,7 @@
ArmTable->Pte[0] =3D Pte;
=
//
- // Map the page in MMIO space that contains the serial port into virtu=
al memory
+ // Map the page in MMIO space that contains the serial port and timers
//
Pte.L1.Section.BaseAddress =3D ArmBoardBlock->UartRegisterBase >> PDE_=
SHIFT;
ArmTable->Pte[UART_VIRTUAL >> PDE_SHIFT] =3D Pte;
Modified: trunk/reactos/hal/halarm/generic/hal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/ha=
l.c?rev=3D32674&r1=3D32673&r2=3D32674&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/hal/halarm/generic/hal.c (original)
+++ trunk/reactos/hal/halarm/generic/hal.c Thu Mar 13 11:29:45 2008
@@ -17,8 +17,10 @@
#include <ndk/halfuncs.h>
#include <ndk/iofuncs.h>
#include <ndk/kdfuncs.h>
+#include <ndk/kefuncs.h>
#include <internal/arm/ke.h>
#include <internal/arm/intrin_i.h>
+#include <bugcodes.h>
=
#define NDEBUG
#include <debug.h>
@@ -31,6 +33,9 @@
#undef KeLowerIrql
#undef KeRaiseIrql
#undef KeReleaseSpinLock
+
+#define READ_REGISTER_ULONG(r) (*(volatile ULONG * const)(r))
+#define WRITE_REGISTER_ULONG(r, v) (*(volatile ULONG *)(r) =3D (v))
=
/* DATA ******************************************************************=
****/
=
@@ -371,16 +376,210 @@
UNIMPLEMENTED;
}
=
-
+VOID
+NTAPI
+HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PCHAR CommandLine;
+ =
+ /* Make sure we have a loader block and command line */
+ if ((LoaderBlock) && (LoaderBlock->LoadOptions))
+ {
+ /* Read the command line */
+ CommandLine =3D LoaderBlock->LoadOptions;
+ =
+ /* Check for initial breakpoint */
+ if (strstr(CommandLine, "BREAK")) DbgBreakPoint();
+ }
+}
+
+
+//
+// INTs on the Versatile:
+//
+// 0 WATCHDOG -> We use it for profiling
+// 1 SOFTWARE INTERRUPT -> We use it for APC delivery
+// 2 COMM RX -> We use it for DPC delivery
+// 3 COMM TX -> We use it for IPI delivery
+// 4 TIMER0/1 -> Use for Clock Interrupt.
+// 5+ XXX -> Mapped to to actual device
+//
+// So we have the following IRQL masks:
+// PASSIVE_LEVEL - 0xFFFFFFFF (enable all interrupts)
+// APC_LEVEL - 0xFFFFFFFD (disable interrupt 1)
+// DISPATCH_LEVEL - 0xFFFFFFF9 (disable interrupts 1, 2)
+// DEVICE_LEVEL_0 - 0xFFFFFFD9 (disable interrupts 1, 2, 5)
+// DEVICE_LEVEL_N - 0x19 (everything disabled except 0, 3, 4)
+// PROFILE_LEVEL - 0x18 (everything disabled except, 3, 4)
+// CLOCK_LEVEL - 0x10 (everything disabled except 4)
+// POWER_LEVEL, IPI_LEVEL, HIGH_LEVEL - 0x00 (everything disabled)
+
+ULONG HalpIrqlTable[] =3D
+{
+ 0xFFFFFFFF, // IRQL 0 PASSIVE_LEVEL
+ 0xFFFFFFFD, // IRQL 1 APC_LEVEL
+ 0xFFFFFFF9, // IRQL 2 DISPATCH_LEVEL
+ 0xFFFFFFD9, // IRQL 3
+ 0xFFFFFF99, // IRQL 4
+ 0xFFFFFF19, // IRQL 5
+ 0xFFFFFE19, // IRQL 6
+ 0xFFFFFC19, // IRQL 7
+ 0xFFFFF819, // IRQL 8
+ 0xFFFFF019, // IRQL 9
+ 0xFFFFE019, // IRQL 10
+ 0xFFFFC019, // IRQL 11
+ 0xFFFF8019, // IRQL 12
+ 0xFFFF0019, // IRQL 13
+ 0xFFFE0019, // IRQL 14
+ 0xFFFC0019, // IRQL 15
+ 0xFFF80019, // IRQL 16
+ 0xFFF00019, // IRQL 17
+ 0xFFE00019, // IRQL 18
+ 0xFFC00019, // IRQL 19
+ 0xFF800019, // IRQL 20
+ 0xFF000019, // IRQL 21
+ 0xFE000019, // IRQL 22
+ 0xFC000019, // IRQL 23
+ 0xF0000019, // IRQL 24
+ 0x80000019, // IRQL 25
+ 0x19, // IRQL 26
+ 0x18, // IRQL 27 PROFILE_LEVEL
+ 0x10, // IRQL 28 CLOCK2_LEVEL
+ 0x00, // IRQL 29 IPI_LEVEL
+ 0x00, // IRQL 30 POWER_LEVEL
+ 0x00, // IRQL 31 HIGH_LEVEL
+};
+
+
+VOID
+HalpStallInterrupt(VOID)
+{
+ DPRINT1("STALL INTERRUPT!!!\n");
+ while (TRUE);
+}
+
+VOID
+HalpInitializeInterrupts(VOID)
+{
+ ULONG i;
+ PKPCR Pcr =3D (PKPCR)KeGetPcr();
+ =
+ //
+ // Fill out the IRQL mappings
+ //
+ for (i =3D 0; i < (HIGH_LEVEL + 1); i++)
+ {
+ //
+ // Save the valeue in the PCR
+ //
+ Pcr->IrqlTable[i] =3D HalpIrqlTable[i];
+ }
+ =
+ //
+ // Setup the clock and profile interrupt
+ //
+ Pcr->InterruptRoutine[CLOCK2_LEVEL] =3D HalpStallInterrupt;
+ // Pcr->InterruptRoutine[PROFILE_LEVEL] =3D HalpCountInterrupt;
+}
+
+ULONG HalpCurrentTimeIncrement, HalpNextTimeIncrement, HalpNextIntervalCou=
nt;
+
+#define VICINTENABLE (PVOID)0xE0040010
+#define VICINTENCLEAR (PVOID)0xE0040014
+#define VICSOFTINT (PVOID)0xE0040018
+#define VICSOFTINTCLEAR (PVOID)0xE004001C
+
+/*
+ * @implemented
+ */
BOOLEAN
NTAPI
-HalInitSystem(
- ULONG BootPhase,
- PLOADER_PARAMETER_BLOCK LoaderBlock)
-{
- UNIMPLEMENTED;
-
- return TRUE;
+HalInitSystem(IN ULONG BootPhase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PKPRCB Prcb =3D KeGetCurrentPrcb();
+ =
+ //
+ // Check the boot phase
+ //
+ if (!BootPhase)
+ {
+ //
+ // Get command-line parameters
+ //
+ HalpGetParameters(LoaderBlock);
+ =
+#if DBG
+ //
+ // Checked HAL requires checked kernel
+ //
+ if (!(Prcb->BuildType & PRCB_BUILD_DEBUG))
+ {
+ //
+ // No match, bugcheck
+ //
+ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 1, 0);
+ }
+#else
+ //
+ // Release build requires release HAL
+ //
+ if (Prcb->BuildType & PRCB_BUILD_DEBUG)
+ {
+ //
+ // No match, bugcheck
+ //
+ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0);
+ }
+#endif
+ =
+#ifdef CONFIG_SMP
+ //
+ // SMP HAL requires SMP kernel
+ //
+ if (Prcb->BuildType & PRCB_BUILD_UNIPROCESSOR)
+ {
+ //
+ // No match, bugcheck
+ //
+ KeBugCheckEx(MISMATCHED_HAL, 2, Prcb->BuildType, 0, 0);
+ }
+#endif
+ =
+ //
+ // Validate the PRCB
+ //
+ if (Prcb->MajorVersion !=3D PRCB_MAJOR_VERSION)
+ {
+ //
+ // Validation failed, bugcheck
+ //
+ KeBugCheckEx(MISMATCHED_HAL, 1, Prcb->MajorVersion, 1, 0);
+ }
+ =
+ //
+ // Setup time increments to 10ms and 1ms
+ //
+ HalpCurrentTimeIncrement =3D 100000;
+ HalpNextTimeIncrement =3D 100000;
+ HalpNextIntervalCount =3D 0;
+ KeSetTimeIncrement(100000, 10000);
+ =
+ //
+ // Initialize interrupts
+ //
+ HalpInitializeInterrupts();
+ }
+ else if (BootPhase =3D=3D 1)
+ {
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+ =
+ //
+ // All done, return
+ //
+ return TRUE;
}
=
=
@@ -484,10 +683,35 @@
=
VOID
FASTCALL
-HalRequestSoftwareInterrupt(
- KIRQL Request)
-{
- UNIMPLEMENTED;
+HalRequestSoftwareInterrupt(IN KIRQL Request)
+{
+ ULONG Interrupt =3D 0;
+
+ //
+ // Get the interrupt that maches this IRQL level
+ //
+ switch (Request)
+ {
+ case APC_LEVEL:
+ =
+ Interrupt =3D 1 << 1;
+ break;
+ =
+ case DISPATCH_LEVEL:
+ =
+ Interrupt =3D 1 << 2;
+ break;
+ =
+ default:
+ =
+ ASSERT(FALSE);
+ }
+ =
+ //
+ // Force a software interrupt
+ //
+ DPRINT1("About to force interrupt mask: %d\n", Interrupt);
+ WRITE_REGISTER_ULONG(VICSOFTINT, Interrupt);
}
=
VOID FASTCALL
@@ -766,23 +990,79 @@
=
VOID
FASTCALL
-KfLowerIrql(
- KIRQL NewIrql)
-{
- KeGetPcr()->CurrentIrql =3D NewIrql;
- UNIMPLEMENTED;
-}
-
+KfLowerIrql(IN KIRQL NewIrql)
+{
+ ULONG InterruptMask;
+ PKPCR Pcr =3D (PKPCR)KeGetPcr();
+ =
+ //
+ // Validate the new IRQL
+ //
+ ASSERT(NewIrql <=3D Pcr->CurrentIrql);
+ =
+ //
+ // IRQLs are internally 8 bits
+ //
+ NewIrql &=3D 0xFF;
+ =
+ //
+ // Setup the interrupt mask for this IRQL
+ //
+ InterruptMask =3D KeGetPcr()->IrqlTable[NewIrql];
+ DPRINT1("New IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
+ =
+ //
+ // Clear interrupts associated to the old IRQL
+ //
+ WRITE_REGISTER_ULONG(VICINTENCLEAR, 0xFFFFFFFF);
+ =
+ //
+ // Set the new interrupt mask
+ // PL190 VIC support only for now
+ //
+ WRITE_REGISTER_ULONG(VICINTENABLE, InterruptMask);
+ =
+ //
+ // Save the new IRQL
+ //
+ Pcr->CurrentIrql =3D NewIrql;
+}
=
KIRQL
FASTCALL
-KfRaiseIrql(
- KIRQL NewIrql)
-{
- KIRQL OldIrql =3D KeGetPcr()->CurrentIrql;
- KeGetPcr()->CurrentIrql =3D NewIrql;
- UNIMPLEMENTED;
-
+KfRaiseIrql(IN KIRQL NewIrql)
+{
+ KIRQL OldIrql;
+ ULONG InterruptMask;
+ PKPCR Pcr =3D (PKPCR)KeGetPcr();
+ =
+ //
+ // Save the current IRQL
+ //
+ OldIrql =3D Pcr->CurrentIrql;
+ =
+ //
+ // IRQLs are internally 8 bits
+ //
+ NewIrql &=3D 0xFF;
+ =
+ //
+ // Setup the interrupt mask for this IRQL
+ //
+ InterruptMask =3D KeGetPcr()->IrqlTable[NewIrql];
+ DPRINT1("New IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
+ //ASSERT(NewIrql >=3D OldIrql);
+ =
+ //
+ // Set the new interrupt mask
+ // PL190 VIC support only for now
+ //
+ WRITE_REGISTER_ULONG(VICINTENABLE, InterruptMask);
+ =
+ //
+ // Save the new IRQL
+ //
+ Pcr->CurrentIrql =3D NewIrql;
return OldIrql;
}
=
@@ -915,28 +1195,28 @@
KIRQL
KeSwapIrql(IN KIRQL Irql)
{
- KIRQL OldIrql =3D KeGetPcr()->CurrentIrql;
- KeGetPcr()->CurrentIrql =3D Irql;
- UNIMPLEMENTED;
- return OldIrql;
+ //
+ // Call the generic routine
+ //
+ return KfRaiseIrql(Irql);
}
=
KIRQL
KeRaiseIrqlToDpcLevel(VOID)
{
- KIRQL OldIrql =3D KeGetPcr()->CurrentIrql;
- KeGetPcr()->CurrentIrql =3D SYNCH_LEVEL;
- UNIMPLEMENTED;
- return OldIrql;
+ //
+ // Call the generic routine
+ //
+ return KfRaiseIrql(DISPATCH_LEVEL);
}
=
KIRQL
KeRaiseIrqlToSynchLevel(VOID)
{
- KIRQL OldIrql =3D KeGetPcr()->CurrentIrql;
- KeGetPcr()->CurrentIrql =3D SYNCH_LEVEL;
- UNIMPLEMENTED;
- return OldIrql;
+ //
+ // Call the generic routine
+ //
+ return KfRaiseIrql(DISPATCH_LEVEL);
}
=
BOOLEAN HalpProcessorIdentified;
@@ -1136,7 +1416,7 @@
IN PKLOCK_QUEUE_HANDLE LockHand=
le)
{
/* Simply raise to synch */
- LockHandle->OldIrql =3D KfRaiseIrql(SYNCH_LEVEL);
+ LockHandle->OldIrql =3D KfRaiseIrql(DISPATCH_LEVEL);
}
=
/*
Modified: trunk/reactos/include/reactos/armddk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/armdd=
k.h?rev=3D32674&r1=3D32673&r2=3D32674&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/include/reactos/armddk.h (original)
+++ trunk/reactos/include/reactos/armddk.h Thu Mar 13 11:29:45 2008
@@ -4,15 +4,17 @@
//
// IRQLs
//
-#define PASSIVE_LEVEL 0
-#define LOW_LEVEL 0
-#define APC_LEVEL 1
-#define DISPATCH_LEVEL 2
-#define IPI_LEVEL 7
-#define POWER_LEVEL 7
-#define PROFILE_LEVEL 8
-#define HIGH_LEVEL 8
-#define SYNCH_LEVEL (IPI_LEVEL - 1)
+#define PASSIVE_LEVEL 0
+#define LOW_LEVEL 0
+#define APC_LEVEL 1
+#define DISPATCH_LEVEL 2
+#define SYNCH_LEVEL DISPATCH_LEVEL
+#define PROFILE_LEVEL 27
+#define CLOCK1_LEVEL 28
+#define CLOCK2_LEVEL 28
+#define IPI_LEVEL 29
+#define POWER_LEVEL 30
+#define HIGH_LEVEL 31
=
//
// FIXME: mmtypes.h?
@@ -83,8 +85,8 @@
PVOID InstructionBusError;
ULONG CachePolicy;
ULONG AlignedCachePolicy;
- UCHAR IrqlMask[64];
- UCHAR IrqlTable[64];
+// UCHAR IrqlMask[64];
+ ULONG IrqlTable[HIGH_LEVEL + 1];
UCHAR CurrentIrql;
KAFFINITY SetMember;
struct _KTHREAD *CurrentThread;