Author: ros-arm-bringup Date: Sat Jun 14 18:19:03 2008 New Revision: 33971
URL: http://svn.reactos.org/svn/reactos?rev=33971&view=rev Log: - Dude, we don't need to calibrate anything... we've got a 1MHz timer, which means 1us-precision. KeStallExecutionProcessor needs 1us-precision! - Since we have two timers (ha x86!!!), set the second one as the stall timer. It's a one-shot periodic timer, set to the exact number of microseconds being waited on. - To fully emulate stalling, we don't use a clock interrupt for it (it supports not sending one!) and just busy-loop until the value reaches 0. - Tried it with a 10 second (10000000 us) wait and it worked -perfectly-. - Re-implemented KeStallExecutionProcessor and got rid of the other code. Back in HalInitSystem(phase1) now... - Also killed some DPRINT1s getting on my nerves.
Modified: trunk/reactos/hal/halarm/generic/hal.c trunk/reactos/ntoskrnl/ke/arm/kiinit.c trunk/reactos/ntoskrnl/ke/arm/trapc.c
Modified: trunk/reactos/hal/halarm/generic/hal.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?re... ============================================================================== --- trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] (original) +++ trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] Sat Jun 14 18:19:03 2008 @@ -498,14 +498,19 @@ #define TIMER_INT_MASK (PVOID)0xE00E2014 #define TIMER_BACKGROUND_LOAD (PVOID)0xE00E2018
+#define TIMER2_LOAD (PVOID)0xE00E3000 +#define TIMER2_VALUE (PVOID)0xE00E3004 +#define TIMER2_CONTROL (PVOID)0xE00E3008 +#define TIMER2_INT_CLEAR (PVOID)0xE00E300C +#define TIMER2_INT_STATUS (PVOID)0xE00E3010 +#define TIMER2_INT_MASK (PVOID)0xE00E3014 +#define TIMER2_BACKGROUND_LOAD (PVOID)0xE00E3018
#define _clz(a) \ ({ ULONG __value, __arg = (a); \ asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \ __value; })
-ULONG HalpStallStart, HalpStallEnd, HalpStallScaleFactor; - ULONG HalGetInterruptSource(VOID) { @@ -535,37 +540,7 @@ // // Clear the interrupt // - DPRINT1("STALL INTERRUPT!!!: %lx %lx\n", HalpStallStart, HalpStallEnd); WRITE_REGISTER_ULONG(TIMER_INT_CLEAR, 1); - - // - // Check if this is our first time here - // - if (!(HalpStallStart + HalpStallEnd)) - { - // - // Remember that we've been hit once - // - HalpStallEnd = 1; - } - else if (!(HalpStallStart) && (HalpStallEnd)) - { - // - // Okay, this is our second time here! - // Load the stall execution count that was setup for us... - // And get ready to hit the case below - // - HalpStallStart = PCR->StallExecutionCount; - HalpStallEnd = 0; - } - else if ((HalpStallStart) && !(HalpStallEnd)) - { - // - // This our third time here! - // Now we can just save the stall execution count at end time - // - HalpStallEnd = PCR->StallExecutionCount; - } }
VOID @@ -693,6 +668,11 @@ } else if (BootPhase == 1) { + // + // Switch to real clock interrupt + // + PCR->InterruptRoutine[CLOCK2_LEVEL] = HalpClockInterrupt; + UNIMPLEMENTED; while (TRUE); } @@ -1084,23 +1064,33 @@
VOID NTAPI -KeStallExecutionProcessor( - ULONG Microseconds) -{ - ULONG Index; - - // - // Calculate how many times we should loop - // - Index = Microseconds * PCR->StallScaleFactor; - while (Index) - { - // - // Do one stall cycle - // - PCR->StallExecutionCount++; - Index--; - }; +KeStallExecutionProcessor(IN ULONG Microseconds) +{ + // + // Configure the interval to xxx Micrseconds + // (INTERVAL (xxx us) * TIMCLKfreq (1MHz)) + // --------------------------------------- + // (TIMCLKENXdiv (1) * PRESCALEdiv (1)) + // + // This works out great, since 1MHz * 1 us = 1! + // + + // + // Enable the timer + // + WRITE_REGISTER_ULONG(TIMER2_LOAD, Microseconds); + WRITE_REGISTER_ULONG(TIMER2_CONTROL, + 1 << 0 | // one-shot mode + 1 << 1 | // 32-bit mode + 0 << 2 | // 0 stages of prescale, divided by 1 + 0 << 5 | // no interrupt + 1 << 6 | // periodic mode + 1 << 7); // enable it + + // + // Now we will loop until the timer reached 0 + // + while (READ_REGISTER_ULONG(TIMER2_VALUE)); }
VOID @@ -1127,7 +1117,7 @@ // Setup the interrupt mask for this IRQL // InterruptMask = KeGetPcr()->IrqlTable[NewIrql]; - DPRINT1("[LOWER] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask); +// DPRINT1("[LOWER] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
// // Clear interrupts associated to the old IRQL @@ -1172,7 +1162,7 @@ // Setup the interrupt mask for this IRQL // InterruptMask = KeGetPcr()->IrqlTable[NewIrql]; - DPRINT1("[RAISE] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask); + // DPRINT1("[RAISE] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask); ASSERT(NewIrql >= OldIrql);
//
Modified: trunk/reactos/ntoskrnl/ke/arm/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/kiinit.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/kiinit.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/kiinit.c [iso-8859-1] Sat Jun 14 18:19:03 2008 @@ -52,7 +52,7 @@ LARGE_INTEGER PageDirectory; PKPCR Pcr; ULONG i; - DPRINT1("%s Process: %p Thread: %p Stack: %p PRCB: %p Number: %d LoaderBlock: %p\n", + DPRINT1("[INIT] Process: %p Thread: %p Stack: %p PRCB: %p Number: %d LoaderBlock: %p\n", __FUNCTION__, InitProcess, InitThread, IdleStack, Prcb, Number, LoaderBlock);
//
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Sat Jun 14 18:19:03 2008 @@ -333,7 +333,7 @@ // Get the interrupt source // InterruptCause = HalGetInterruptSource(); - DPRINT1("[INT] (%x) @ %p %p\n", InterruptCause, TrapFrame->SvcLr, TrapFrame->Pc); +// DPRINT1("[INT] (%x) @ %p %p\n", InterruptCause, TrapFrame->SvcLr, TrapFrame->Pc);
// // Get the new IRQL and Interrupt Mask @@ -354,14 +354,14 @@ // // FIXME: Switch to interrupt stack // - DPRINT1("[ISR]\n"); + //DPRINT1("[ISR]\n"); } else { // // We know this is APC or DPC. // - DPRINT1("[DPC/APC]\n"); + //DPRINT1("[DPC/APC]\n"); HalClearSoftwareInterrupt(Irql); }
@@ -369,7 +369,7 @@ // Call the registered interrupt routine // Pcr->InterruptRoutine[Irql](); - DPRINT1("[ISR RETURN]\n"); +// DPRINT1("[ISR RETURN]\n");
// // Re-enable interrupts and return IRQL