This commit introduces a noticeable delay in VirtualBox:
1) When booting from the CD to install ROS, after FreeLDR has initially loaded
and the screen becomes black, here I notice a delay of 6~7 seconds until I see
the blue screen to choose the language in usetup. Before the commit it was
about 1 sec.
2) In second stage when loading UniATA, it stays there for about 4-5 seconds,
there was no delay before.
Best regards,
Gabriel.
> Date: Tue, 27 Oct 2009 01:03:41 +0000
> To: [email protected]
> From: [email protected]
> Subject: [ros-diffs] [sginsberg] 43789: - Replace broken implementation of
> HalpCalibrateStallExecution with a new implementation by a mysterious HAL
> ninja and myself. The old implementation calculated the stall count factor
> incorrectly and produced bogus results that were off by several thousand, and
> varied by as much for each boot, and can best be described as "rand() made
> complicated". The new implementation installs its own RTC interrupt handler
> to accurately calculate the stall scale factor, all done in assembler instead
> of broken C. Fixes the hang at boot when initializing Uniata as stalls no
> longer takes 10 times or more as long to execute then they should.
>
> Author: sginsberg
> Date: Tue Oct 27 02:03:41 2009
> New Revision: 43789
>
> URL: http://svn.reactos.org/svn/reactos?rev=43789&view=rev
> Log:
> - Replace broken implementation of HalpCalibrateStallExecution with a new
> implementation by a mysterious HAL ninja and myself. The old implementation
> calculated the stall count factor incorrectly and produced bogus results that
> were off by several thousand, and varied by as much for each boot, and can
> best be described as "rand() made complicated". The new implementation
> installs its own RTC interrupt handler to accurately calculate the stall
> scale factor, all done in assembler instead of broken C. Fixes the hang at
> boot when initializing Uniata as stalls no longer takes 10 times or more as
> long to execute then they should.
>
> Modified:
> trunk/reactos/hal/halx86/generic/halinit.c
> trunk/reactos/hal/halx86/generic/systimer.S
> trunk/reactos/hal/halx86/generic/timer.c
>
> Modified: trunk/reactos/hal/halx86/generic/halinit.c
> URL:
> http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/halinit.c?rev=43789&r1=43788&r2=43789&view=diff
> ==============================================================================
> --- trunk/reactos/hal/halx86/generic/halinit.c [iso-8859-1] (original)
> +++ trunk/reactos/hal/halx86/generic/halinit.c [iso-8859-1] Tue Oct 27
> 02:03:41 2009
> @@ -97,11 +97,11 @@
> /* Force initial PIC state */
> KfRaiseIrql(KeGetCurrentIrql());
>
> + /* Setup busy waiting */
> + HalpCalibrateStallExecution();
> +
> /* Initialize the clock */
> HalpInitializeClock();
> -
> - /* Setup busy waiting */
> - HalpCalibrateStallExecution();
>
> /* Fill out the dispatch tables */
> HalQuerySystemInformation = HaliQuerySystemInformation;
>
> Modified: trunk/reactos/hal/halx86/generic/systimer.S
> URL:
> http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/systimer.S?rev=43789&r1=43788&r2=43789&view=diff
> ==============================================================================
> --- trunk/reactos/hal/halx86/generic/systimer.S [iso-8859-1] (original)
> +++ trunk/reactos/hal/halx86/generic/systimer.S [iso-8859-1] Tue Oct 27
> 02:03:41 2009
> @@ -17,11 +17,386 @@
> _HalpLastPerfCounterHigh: .long 0
> _HalpPerfCounterLow: .long 0
> _HalpPerfCounterHigh: .long 0
> +_HalpSystemHardwareLock: .long 0
> +_HalpSystemHardwareFlags: .long 0
>
> _UnhandledMsg:
> .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
>
> /* FUNCTIONS
> *****************************************************************/
> +
> +.global _halpreleasecmosspinl...@0
> +.func halpreleasecmosspinl...@0
> +_halpreleasecmosspinl...@0:
> +
> +#ifdef CONFIG_SMP
> + /* Save clobbered register */
> + push eax
> +
> + /* Push saved EFLAGS */
> + push _HalpSystemHardwareFlags
> +
> + /* Release the lock */
> + lea eax, _HalpSystemHardwareLock
> + RELEASE_SPINLOCK(eax)
> +
> + /* Restore EFLAGS */
> + popf
> +
> + /* Return */
> + pop eax
> + ret
> +#else
> + /* Restore EFLAGS and return */
> + push _HalpSystemHardwareFlags
> + popf
> + ret
> +#endif
> +.endfunc
> +
> +.global _halpacquiresystemhardwarespinl...@0
> +.func halpacquiresystemhardwarespinl...@0
> +_halpacquiresystemhardwarespinl...@0:
> +
> +#ifdef CONFIG_SMP
> + /* Save clobbered register */
> + push eax
> +
> +HardwareLock:
> + /* Save EFLAGS and disable interrupts */
> + pushf
> + cli
> +
> + /* This is the CMOS lock, acquire it */
> + lea eax, _HalpSystemHardwareLock
> + ACQUIRE_SPINLOCK(eax, CmosSpin)
> +
> + /* We have it, return the flags */
> + pop _HalpSystemHardwareFlags
> + pop eax
> + ret
> +
> +CmosSpin:
> +
> + /* Restore EFLAGS */
> + pushf _HalpSystemHardwareLock
> + popf
> +
> + /* Spin */
> + SPIN_ON_LOCK(eax, HardwareLock)
> +
> +#else
> + /* Save EFLAGS, disable interrupts and return */
> + pushf
> + cli
> + pop _HalpSystemHardwareFlags
> + ret
> +#endif
> +.endfunc
> +
> +.global _halpcalibratestallexecut...@0
> +.func halpcalibratestallexecut...@0
> +_halpcalibratestallexecut...@0:
> +
> + /* Setup the stack frame */
> + push ebp
> + mov ebp, esp
> + sub esp, 12
> +
> + /* Save EFLAGS and kill interrupts */
> + pushf
> + cli
> +
> + /* Get the current interrupt mask on the PICs */
> + xor eax, eax
> + in al, 0xA1
> + shl eax, 8
> + in al, 0x21
> +
> + /* Save it */
> + push eax
> +
> + /* Now mask everything except the RTC and PIC 2 chain-interrupt */
> + mov eax, ~((1 << 2) | (1 << 8))
> +
> + /* Program the PICs */
> + out 0x21, al
> + shr eax, 8
> + out 0xA1, al
> +
> + /* Now get the IDT */
> + sidt [ebp-8]
> + mov ecx, [ebp-6]
> +
> + /* Get the IDT entry for the RTC */
> + mov eax, 0x38
> + shl eax, 3
> + add ecx, eax
> +
> + /* Save the original RTC ISR */
> + push [ecx]
> + push [ecx+4]
> + push ecx
> +
> + /* Now load our new handler */
> + mov eax, offset OnlyOnePersonCanWriteHalCode
> + mov [ecx], ax
> + mov word ptr [ecx+2], KGDT_R0_CODE
> + mov word ptr [ecx+4], 0x8E00
> + shr eax, 16
> + mov [ecx+6], ax
> +
> + /* Reset our counter */
> + mov dword ptr [ebp-12], 0
> +
> + /* Acquire CMOS lock */
> + call _halpacquiresystemhardwarespinl...@0
> +
> + /* Now initialize register A on the CMOS */
> + mov ax, (0x2D << 8) | 0xA
> + out 0x70, al
> + jmp $+2
> + mov al, ah
> + out 0x71, al
> + jmp $+2
> +
> + /* Read register B */
> + mov ax, 0xB
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Don't touch the LastKnownGoodConfig hack */
> + and al, 1
> + mov ah, al
> +
> + /* Enable the interrupt */
> + or ah, 0x42
> +
> + /* Now write the register B */
> + mov al, 0xB
> + out 0x70, al
> + jmp $+2
> + mov al, ah
> + out 0x71, al
> + jmp $+2
> +
> + /* Read register C */
> + mov al, 0xC
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Read register D */
> + mov al, 0xD
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Release CMOS lock */
> + mov dword ptr [ebp-12], 0
> + call _halpreleasecmosspinl...@0
> +
> + /* Initialize looper */
> + xor eax, eax
> +
> + /* Align to 16 bytes */
> + .align 16
> +
> + /* Enable interrupts! */
> + sti
> + jmp Looper
> +
> + /* Align to 16 bytes */
> + .align 16
> +
> + /* Subtract one count */
> +Looper:
> + sub eax, 1
> + jnz Looper
> +
> + /* ASSERT: If we got here, then the RTC never fired */
> + call _dbgbreakpo...@0
> + jmp Looper
> +
> +OnlyOnePersonCanWriteHalCode:
> + /*********************** THIS IS THE RTC HANDLER
> **************************/
> +
> + /* Increment the interrupt count and check if this is the first one */
> + inc dword ptr [ebp-12]
> + cmp dword ptr [ebp-12], 1
> + jnz ComputeStall
> +
> + /*
> + * It is the first one -- we'll ignore it, since it fires randomly!
> + * Get rid of the old return address and push the new one in (our looper)
> + */
> + pop eax
> + push offset Looper
> +
> + /* Acquire CMOS lock */
> + call _halpacquiresystemhardwarespinl...@0
> +
> + /* Now initialize register A on the CMOS */
> + mov ax, (0x2D << 8) | 0xA
> + out 0x70, al
> + jmp $+2
> + mov al, ah
> + out 0x71, al
> + jmp $+2
> +
> + /* Read register B */
> + mov ax, 0xB
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Don't touch the LastKnownGoodConfig hack */
> + and al, 1
> + mov ah, al
> +
> + /* Enable the interrupt */
> + or ah, 0x42
> +
> + /* Now write the register B */
> + mov al, 0xB
> + out 0x70, al
> + jmp $+2
> + mov al, ah
> + out 0x71, al
> + jmp $+2
> +
> + /* Read register C */
> + mov al, 0xC
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Read register D */
> + mov al, 0xD
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Release CMOS lock */
> + call _halpreleasecmosspinl...@0
> +
> + /* Dismiss the interrupt */
> + mov al, 0x20
> + out 0xA0, al
> + mov al, 0x62
> + out 0x20, al
> +
> + /* Reset the counter and return back to the looper */
> + xor eax, eax
> + iretd
> +
> + /******************* THIS IS THE 2ND RTC HANDLER
> **************************/
> +ComputeStall:
> +
> + /* Do the calculation */
> + neg eax
> + xor edx, edx
> + mov ecx, 125000 /* RTC fires every 125 ms */
> + div ecx
> +
> + /* Is the remainder 0? */
> + cmp edx, 0
> + jz FoundFactor
> +
> + /* Otherwise fix-up the loop count */
> + inc eax
> +
> +FoundFactor:
> + /* Save the stall scale factor */
> + mov fs:[KPCR_STALL_SCALE_FACTOR], eax
> +
> + /* Prepare for interrupt return */
> + pop eax
> + push offset AndItsNotYou
> + mov eax, 0x13
> +
> + /* Acquire CMOS lock */
> + call _halpacquiresystemhardwarespinl...@0
> +
> + /* Now initialize register A on the CMOS */
> + mov ax, (0x2D << 8) | 0xA
> + out 0x70, al
> + jmp $+2
> + mov al, ah
> + out 0x71, al
> + jmp $+2
> +
> + /* Read register B */
> + mov ax, 0xB
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Don't touch the LastKnownGoodConfig hack */
> + and al, 1
> + mov ah, al
> +
> + /* Disable the interrupt */
> + or ah, 0x2
> +
> + /* Now write the register B */
> + mov al, 0xB
> + out 0x70, al
> + jmp $+2
> + mov al, ah
> + out 0x71, al
> + jmp $+2
> +
> + /* Read register C */
> + mov al, 0xC
> + out 0x70, al
> + jmp $+2
> + in al, 0x71
> + jmp $+2
> +
> + /* Release CMOS lock */
> + call _halpreleasecmosspinl...@0
> +
> + /* Dismiss the interrupt */
> + mov al, 0x20
> + out 0xA0, al
> + mov al, 0x62
> + out 0x20, al
> +
> + /* Disable interrupts on return */
> + and word ptr [esp+8], ~EFLAGS_INTERRUPT_MASK
> + iretd
> +
> + /************************* WE ARE BACK FROM RTC
> ***************************/
> +AndItsNotYou:
> +
> + /* Restore the IDT */
> + pop ecx
> + pop [ecx+4]
> + pop [ecx]
> +
> + /* Restore the mask */
> + pop eax
> + out 0x21, al
> + shr eax, 8
> + out 0xA1, al
> +
> + /* Restore EFLAGS */
> + popf
> +
> + /* Restore stack and return */
> + mov esp, ebp
> + pop ebp
> + ret
> +.endfunc
>
> .globl _kestallexecutionproces...@4
> .func kestallexecutionproces...@4
> @@ -53,34 +428,6 @@
> /* Return */
> ret 4
> .endfunc
> -
> -
> -.globl _halpquery8254coun...@0
> -.func halpquery8254coun...@0
> -_halpquery8254coun...@0:
> -
> - /* Save EFLAGS and disable interrupts */
> - pushfd
> - cli
> -
> - /* Set timer data */
> - mov al, 0
> - out 0x43, al
> - jmp $+2
> -
> - /* Read current timer */
> - in al, 0x40
> - jmp $+2
> - movzx ecx, al
> - in al, 0x40
> - mov ch, al
> -
> - /* Return it and restore interrupt state */
> - mov eax, ecx
> - popfd
> - ret
> -.endfunc
> -
>
> .global _kequeryperformancecoun...@4
> .func kequeryperformancecoun...@4
>
> Modified: trunk/reactos/hal/halx86/generic/timer.c
> URL:
> http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/timer.c?rev=43789&r1=43788&r2=43789&view=diff
> ==============================================================================
> --- trunk/reactos/hal/halx86/generic/timer.c [iso-8859-1] (original)
> +++ trunk/reactos/hal/halx86/generic/timer.c [iso-8859-1] Tue Oct 27 02:03:41
> 2009
> @@ -13,11 +13,6 @@
> #include <debug.h>
>
> /* GLOBALS
> *******************************************************************/
> -
> -/* time to wait */
> -#define MICROSECOND_TO_WAIT 1000
> -/* the tick count for 1 ms is 1193.182 (1193182 Hz) round it up */
> -#define TICKCOUNT_TO_WAIT 1194
>
> BOOLEAN HalpClockSetMSRate;
> ULONG HalpCurrentTimeIncrement;
> @@ -135,161 +130,4 @@
> return HalpRolloverTable[Increment - 1].HighPart;
> }
>
> -ULONG
> -WaitFor8254Wraparound(VOID)
> -{
> - ULONG StartTicks;
> - ULONG PrevTicks;
> - LONG Delta;
> -
> - StartTicks = HalpQuery8254Counter();
> -
> - do
> - {
> - PrevTicks = StartTicks;
> - StartTicks = HalpQuery8254Counter();
> - Delta = StartTicks - PrevTicks;
> -
> - /*
> - * This limit for delta seems arbitrary, but it isn't, it's
> - * slightly above the level of error a buggy Mercury/Neptune
> - * chipset timer can cause.
> - */
> -
> - }
> - while (Delta < 300);
> -
> - return StartTicks;
> -}
> -
> -VOID
> -NTAPI
> -HalpCalibrateStallExecution(VOID)
> -{
> - ULONG CalibrationBit;
> - ULONG EndTicks;
> - ULONG StartTicks;
> - ULONG OverheadTicks;
> - PKIPCR Pcr;
> -
> - Pcr = (PKIPCR)KeGetPcr();
> -
> - /* Measure the delay for the minimum call overhead in ticks */
> - Pcr->StallScaleFactor = 1;
> - StartTicks = WaitFor8254Wraparound();
> - KeStallExecutionProcessor(1);
> - EndTicks = HalpQuery8254Counter();
> - OverheadTicks = (StartTicks - EndTicks);
> -
> - do
> - {
> - /* Increase the StallScaleFactor */
> - Pcr->StallScaleFactor = Pcr->StallScaleFactor * 2;
> -
> - if (Pcr->StallScaleFactor == 0)
> - {
> - /* Nothing found */
> - break;
> - }
> -
> - /* Get the start ticks */
> - StartTicks = WaitFor8254Wraparound();
> -
> - /* Wait for a defined time */
> - KeStallExecutionProcessor(MICROSECOND_TO_WAIT);
> -
> - /* Get the end ticks */
> - EndTicks = HalpQuery8254Counter();
> -
> - DPRINT("Pcr->StallScaleFactor: %d\n", Pcr->StallScaleFactor);
> - DPRINT("Time1 : StartTicks %i - EndTicks %i = %i\n",
> - StartTicks, EndTicks, StartTicks - EndTicks);
> - } while ((StartTicks - EndTicks) <= (TICKCOUNT_TO_WAIT + OverheadTicks));
> -
> - /* A StallScaleFactor lesser than INITIAL_STALL_COUNT makes no sense */
> - if (Pcr->StallScaleFactor >= (INITIAL_STALL_COUNT * 2))
> - {
> - /* Adjust the StallScaleFactor */
> - Pcr->StallScaleFactor = Pcr->StallScaleFactor / 2;
> -
> - /* Setup the CalibrationBit */
> - CalibrationBit = Pcr->StallScaleFactor;
> -
> - for (;;)
> - {
> - /* Lower the CalibrationBit */
> - CalibrationBit = CalibrationBit / 2;
> - if (CalibrationBit == 0)
> - {
> - break;
> - }
> -
> - /* Add the CalibrationBit */
> - Pcr->StallScaleFactor = Pcr->StallScaleFactor + CalibrationBit;
> -
> - /* Get the start ticks */
> - StartTicks = WaitFor8254Wraparound();
> -
> - /* Wait for a defined time */
> - KeStallExecutionProcessor(MICROSECOND_TO_WAIT);
> -
> - /* Get the end ticks */
> - EndTicks = HalpQuery8254Counter();
> -
> - DPRINT("Pcr->StallScaleFactor: %d\n", Pcr->StallScaleFactor);
> - DPRINT("Time2 : StartTicks %i - EndTicks %i = %i\n",
> - StartTicks, EndTicks, StartTicks - EndTicks);
> -
> - if ((StartTicks-EndTicks) > (TICKCOUNT_TO_WAIT+OverheadTicks))
> - {
> - /* Too big so subtract the CalibrationBit */
> - Pcr->StallScaleFactor = Pcr->StallScaleFactor -
> CalibrationBit;
> - }
> - }
> - DPRINT("New StallScaleFactor: %d\n", Pcr->StallScaleFactor);
> - }
> - else
> - {
> - /* Set StallScaleFactor to the default */
> - Pcr->StallScaleFactor = INITIAL_STALL_COUNT;
> - }
> -
> -#if 0
> - /* For debugging */
> - ULONG i;
> -
> - DPRINT1("About to start delay loop test\n");
> - DPRINT1("Waiting for a minute...");
> - for (i = 0; i < (60*1000*20); i++)
> - {
> - KeStallExecutionProcessor(50);
> - }
> - DPRINT1("finished\n");
> -
> -
> - DPRINT1("About to start delay loop test\n");
> - DPRINT1("Waiting for a minute...");
> - for (i = 0; i < (60*1000); i++)
> - {
> - KeStallExecutionProcessor(1000);
> - }
> - DPRINT1("finished\n");
> -
> -
> - DPRINT1("About to start delay loop test\n");
> - DPRINT1("Waiting for a minute...");
> - for (i = 0; i < (60*1000*1000); i++)
> - {
> - KeStallExecutionProcessor(1);
> - }
> - DPRINT1("finished\n");
> -
> - DPRINT1("About to start delay loop test\n");
> - DPRINT1("Waiting for a minute...");
> - KeStallExecutionProcessor(60*1000000);
> - DPRINT1("finished\n");
> -#endif
> -}
> -
> -
> /* EOF */
>
>
_________________________________________________________________
Nuovo Windows 7: trova il PC più adatto alle tue esigenze. Scopri di più.
http://windows.microsoft.com/shop_______________________________________________
Ros-dev mailing list
[email protected]
http://www.reactos.org/mailman/listinfo/ros-dev