lkml.org 
[lkml]   [2007]   [Dec]   [11]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateTue, 11 Dec 2007 14:16:01 +0100
FromRene Herman <>
SubjectRe: RFC: outb 0x80 in inb_p, outb_p harmful on some modern AMD64 with MCP51 laptops
On 11-12-07 13:08, David Newall wrote:

> Rene Herman wrote:
>> On 11-12-07 08:40, Paul Rolland wrote:
>>
>>> Well, if the delay is so much unspecified, what about _reading_ port 
>>> 0x80 ?
>>> Will the delay be shorter ?
>>
>> The delay is completely and fully specified in terms of the ISA/LPC clock
> 
> That would be the delay on the i386 (sic) architecture.  In general, 
> though, the delay is:

This particular discussion isn't about anything in general but solely about 
the delay an outb_p gives you on x86 since what is under discussion is not 
using an output to port 0x80 on that platform to generate it.

> Thinking that _p gives a pause is perhaps too PC-centric. Why, if a delay
> is needed, wouldn't you use a real delay; one that says how long it
> should be?

Because any possible outb_p delay should be synced to the bus-clock, not to 
any wall-clock. Drivers that want to sync to wall-clock need to use an outb, 
delay pair as you'd expect.

In the real world, driver authors aren't perfect and will have used outb_p 
as a wall-clock delay which they have gotten away with since it's a nicely 
specified delay in terms of the ISA/LPC clock and the ISA/LPC clock being 
fairly (old) to very (new) constant.

The delay it gives is very close to 1 us on a spec ISA/LPC bus (*) and as 
such, even though it may not be the right thing to do from an theoretical 
standpoint, generally a udelay(1) is going to be a fine replacement from a 
practical one -- as soon as we _can_ use udelay(), as I also wrote.

Rene.

(*) some local testing shows it to be almost exactly that for both out and 
in on my own PC -- a little over. If anyone cares, see attached little test 
program. The "little over" I don't worry about. 0 us delay is also fine for 
me and if any code was _that_ fragile it would have broken long ago.
#include <stdlib.h>
#include <stdio.h>

#include <sys/io.h>

int main(void)
{
	unsigned long cycles;
	if (iopl(3) < 0) {
		perror("iopl");
		return EXIT_FAILURE;
	}
	asm (	"cli			\n\t"	
		"rdtsc			\n\t"
		"movl	%%eax, %%ecx	\n\t"	
		"outb	%%al, $0x80	\n\t"
		"rdtsc			\n\t"
		"subl	%%ecx, %%eax	\n\t"
		"sti			"			
		: "=a" (cycles) : : "ecx", "edx");

	printf("out = %lu\n", cycles);

	asm (	"cli			\n\t"	
		"rdtsc			\n\t"
		"movl	%%eax, %%ecx	\n\t"	
		"inb	$0x80, %%al	\n\t"
		"rdtsc			\n\t"
		"subl	%%ecx, %%eax	\n\t"
		"sti			"			
		: "=a" (cycles) : : "ecx", "edx");

	printf("in  = %lu\n", cycles);

	return EXIT_FAILURE;
}
\
 
 \ /
  Last update: 2007-12-11 14:21    [from the cache]
©2003-2008