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