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;