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

Reply via email to