[ros-diffs] [ros-arm-bringup] 32674: - Implement IRQL functions for the PL190 VIC. - Start coding HalInitSystem. - Implement HalRequestSoftwareInterrupt for the PL190 VIC. The interrupt fires! (This interrupt is responsible for forcing DPC delivery, which should also force thread scheduling, which should force the switch to the phase 1 thread)

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Thu Mar 13 17:29:45 CET 2008


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;




More information about the Ros-diffs mailing list