Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Nov 95 23:51 WET
From:      uhclem%nemesis@fw.ast.com (Frank Durda IV)
To:        current@FreeBSD.org
Subject:   Re: Opcode sequencing
Message-ID:  <m0tBbW4-000J4YC@nemesis.lonestar.org>

next in thread | raw e-mail | index | archive | help
[3]Bruce Evans <bde@zeta.org.au> writes:
[3]Perhaps the 8254 clock is being accessed too fast.  Try adding some delays
[3]before each inb() and outb() in clock.c:getit().  Count to 100 or so to
[3]get at least 1 usec delay.


[4]Uh, I don't think this will work as you expect on a Pentium or a P6. It is
[4]too easy for the parallel integer unit(s) to execute the inb/outbs in one
[4]unit and do the nice delay loop in the other, thus wrecking your timing
[4]delay.  On the Pentium and up you must force these types of "timed"
[4]instruction sequences to be done sequentially.
[4]
[4]Execution Time is no longer linear....   :-)


[5]Rod Grimes rgrimes@gndrsh.aac.dev.com writes:
[5]I suggest you go read the book again, IN and OUT instructions are
[5]``serailization'' instuctions.  All code between them will have _completed_
[5]execution before the external cycle runs.


Uh, I did.  18-8.5 of Volume 3 of the 1994 Pentium songbook says:

"The I/O instructions are *not* completely serializing; the processor does
*not* wait for these instructions to complete before it prefetches the next
instruction.  However, they do have some serializing properties that cause
them to function in a manner that is compatible with processor generations
prior to the Pentium processor."  

[Ed: even the 486 and to a lesser extend the 386 had a habit of having
 the I/O cycle from an OUT instruction occur AFTER the next instruction
 was well-underway.  More on this below.]


and Chapter 15.4 "Ordering of I/O" says:

"To optimize performance, the Pentium CPU allows memory reads to be 
reordered ahead of buffered writes in most situations.  Internally, the
CPU reads (cache hits) can be reordered around buffered writes.  Memory
reordering does not occur externally at the pins, read (cache miss) and
writes appear in-order.  The Intel486 CPU allows memory reads to be
reordered ahead of buffered writes in certain precisely-defined
circumstances. (See the Intel486TM Microprocessor Hardware Reference
Manual for further details about the operation of the write buffer.)

Using memory-mapped I/O, therefore, creates the possibility that an I/O
read might be performed before the memory write of a previous instruction.
To eliminate this possibility on the Intel486CPU, use an I/O instruction
for the read.  ****To eliminate this possibility on the Pentium processor,
insert one of the serializing instructions, such as CPUID, between
operations.****

[Ed: the reverse is also true on a 486 according to the HP 486 Logic Analyzer.
 An OUT followed by a memory read obtained data from the wrong location
 because the OUT I/O cycle had not occurred by the time the memory read
 was performed.  (The OUT cycle would have changed memory banks in an
 expanded memory system, so the wrong bank was accessed even though the
 OUT appeared in the code before the MOV.) The solution was to insert a
 JMP $+2 between OUT and MOV opcodes.  I don't know if similar or fancier
 action is required on the Pentium and this particular case isn't clearly
 covered in the Pentium manual.]

When I/O instructions are used instead of memory-mapped I/O, the situation
is different in two respects:

1.  Some I/O writes are never buffered.  The only I/O writes that the
    the Intel486 CPU buffers are those from the OUTS instruction.  The
    Pentium processor does not buffer any I/O writes.  Therefore,
    strict ordering of I/O operations is enforced by the processor.

[Ed: Symantics.  A plain OUT on a 486 may not be "buffered", but the
I/O WRITE cycle also does not occur during the actual execution clocks of
the OUT instruction.  It occurs during or after the next instruction is
performed.  So you might call that "deferred".  I think they are using
"buffered" to say the I/O cycle does not occur only forced out onto the
bus for some reason, and I agree that is not how it works.  The I/O
cycle occurs at a reasonably predictable point.  It just isn't in the
confines of the OUT instruction execution period.]

2.  The [Pentium] processor synchronizes I/O instruction execution with
    *external* bus activity.  Refer to Table 15-1.

			Table 15-1  [Pentium] I/O Serialization

		Processor Holds			Awaiting for Completion of...
		Execution of...

Current		Current		Next		Pending		Current
Instruction	Instruction?	Instruction	Stores?		Store?

IN		Yes		-		Yes		-

INS		Yes		-		Yes		-

REP INS		Yes		-		Yes		-

OUT		-		Yes		Yes		Yes

OUTS		-		Yes		Yes		Yes

REP OUTS	-		Yes		Yes		Yes

"

Sorry, I don't know what the difference is between "Current Instruction"
and "Current Instruction?".  Perhaps it means an instruction in the
other execution unit (if any) is held while this I/O instruction is
performed.

So much for this bit of trivia.

Frank Durda IV <uhclem@nemesis.lonestar.org>|You want something here 
or uhclem%nemesis@fw.ast.com (Fastest Route)|every time?
...letni!rwsys!nemesis!uhclem               |
...decvax!fw.ast.com!nemesis!uhclem         |




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?m0tBbW4-000J4YC>