linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* why we use multu to implement udelay
@ 2009-11-01 14:18 loody
  2009-11-02  7:17 ` Ralf Baechle
  0 siblings, 1 reply; 3+ messages in thread
From: loody @ 2009-11-01 14:18 UTC (permalink / raw)
  To: Linux MIPS Mailing List

Dear all:
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?
appreciate your help,
miloody

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: why we use multu to implement udelay
  2009-11-01 14:18 why we use multu to implement udelay loody
@ 2009-11-02  7:17 ` Ralf Baechle
  2009-11-04  2:33   ` loody
  0 siblings, 1 reply; 3+ messages in thread
From: Ralf Baechle @ 2009-11-02  7:17 UTC (permalink / raw)
  To: loody; +Cc: Linux MIPS Mailing List

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: why we use multu to implement udelay
  2009-11-02  7:17 ` Ralf Baechle
@ 2009-11-04  2:33   ` loody
  0 siblings, 0 replies; 3+ messages in thread
From: loody @ 2009-11-04  2:33 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Linux MIPS Mailing List

Hi:
thanks for your kind help :)

2009/11/2 Ralf Baechle <ralf@linux-mips.org>:
> 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

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-11-04  2:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-01 14:18 why we use multu to implement udelay loody
2009-11-02  7:17 ` Ralf Baechle
2009-11-04  2:33   ` loody

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).