Re: why we use multu to implement udelay

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi:
thanks for your kind help :)

2009/11/2 Ralf Baechle <ralf@xxxxxxxxxxxxxx>:
> On Sun, Nov 01, 2009 at 10:18:14PM +0800, loody wrote:
>
>> If I search the right place in mip kernel, I find the kernel implement
>> udelay by multu and bnez looping, in 32-bits mode.
>>       if (sizeof(long) == 4)
>>               __asm__("multu\t%2, %3"
>>               : "=h" (usecs), "=l" (lo)
>>               : "r" (usecs), "r" (lpj)
>>               : GCC_REG_ACCUM);
>>       else if (sizeof(long) == 8)
>>               __asm__("dmultu\t%2, %3"
>>               : "=h" (usecs), "=l" (lo)
>>               : "r" (usecs), "r" (lpj)
>>               : GCC_REG_ACCUM);
>>
>>       __delay(usecs);
>> why we doing so instead of using kernel timer function and the
>> precision will be incorrect if the cpu runs faster or slower, right?
>
> This is an old-fashioned implementation which will work even on systems
> where no CPU timer is available or its frequency is unknown or variable.
>
> A while ago patches were posted to use the cp0 counter instead but do
> to other necessary rewrites those patches went stale, so need to be
> reworked before they can be applied.  Either way, for above restrictions
> the delay by looping implementation will still be needed as the fallback
> implementation.
>
>  Ralf
I find in the __udelay we will first calculate out the value of
counter then sent to __delay for looping.

The formula of counter value is like below:
#if defined(CONFIG_64BIT) && (HZ == 128)
	usecs *= 0x0008637bd05af6c7UL;		/* 2**64 / (1000000 / HZ) */
#elif defined(CONFIG_64BIT)
	usecs *= (0x8000000000000000UL / (500000 / HZ));
#else /* 32-bit junk follows here */
	usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +
	                           0x80000000ULL) >> 32);
#endif

Is there any rule or principle that tells us how to get this value?
appreciate your help,
miloody


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux