Subject: Re: hardware caches and DMA
To: John F. Woods <jfw@jfwhome.funhouse.com>
From: Tobias Weingartner <weingart@austin.BrandonU.CA>
List: port-i386
Date: 04/17/1995 13:17:13
"John F. Woods" writes:
> > > I haven't looked at NetBSD DMA code but one simple thing to
> > > do is to use, for example, CACHE_FLUSH(addr,len) and
> > > CACHE_INVALIDATE(addr,len) macros at appropriate points
> > > around where DMA is set up or done.
[Deleted]

This should already be in the kernel, to handle write-back caches
in different architectures.  I have 'Programmer's Technical Reference:
The Processor & Coprocessor' from PC Magazine, by Robert L. Hummel.
The dude seems to know what he is doing, and the book even has a
section on known bugs in the CPU's, some of them with workarounds.

Here is the section on invd and wbinvd, the MOV BL, Label is there to
work around a bug in the A-C0 stop of the 80486, which might corrupt
the cache when a MOV CR0, reg32 instruction is executed.  I have no
idea why the OUT port, data is there for.  The more I look at this
book, the worse it gets... YUK! ;-(

=====================================================================

INVD - (00001111 00001000)
--------------------------
Description:

INVD instructs the processor to consider data in both internal and
external caches to be invalid.

When this instruction is executed, the internal cache is flushed. In
addition, a special bus cycle is issued which indicates that any external
caches should also be flushed.  Data that is being held in write-back
external caches will be discarded.


Algorithm:

None.


Notes:

1. On some versions of the 80486, if a cache line fill is in progress
when the INVD instruction is executed, the cache line fill buffer is
not invalidated.  The buffer contents will be moved into the cache,
which will contain a valid line when it should have been flushed.

To work around this problem in software, use the following code to
disable the internal cache prior to flushing the cache.  Note that
the NMI and faults/traps should not occur during this code sequence.

	MOV EAX, CR0
	OR  EAX, 60000000H  ; Set to disable cache
	PUSHFD
	CLI
	MOV BL, CS:Label
	OUT port, data      ; Write data to dummy port
	MOV CR0, EAX        ; Disable cache
Label:
	INVD                ; Invalidate cache
	AND EAX, 9FFFFFFFH  ; Enable cache (value may be different for
	MOV CR0, EAX        ; no write-thru)
	POPFD


Flags:

No flags are affected.


Timing:

CPU    | 88 86 286 386 486
Cycles | -  -   -   -   4

=====================================================================

WBINVD -- (00001111 00001001)
-----------------------------
Description:

WBINVD flushes both internal and external caches, directing any
external caches to write-back data to main memory before flushing.


Algorithm:

None.


Notes:

1. On some versions of the 80486, if a cache line is in progress when
the WBINVD instruction is executed, the cache line fill buffer is not
invalidated.  The buffer contents will be moved into the cache, which
will contain a valid line when it should have been flushed.

To work around this problem in software, use the following code to
disable the internal cache prior to flushing the cache. Not that the
NMI and faults/traps should not occur during this code sequence.

	MOV EAX, CR0
	OR  EAX, 60000000H  ; Set to disable cache
	PUSHFD
	CLI
	MOV BL, CS:Label
	OUT port, data      ; Write data to dummy port
	MOV CR0, EAX        ; Disable cache
Label:
	WBINVD              ; Invalidate cache
	AND EAX, 9FFFFFFFH  ; Enable cache (value may be different
	MOV CR0, EAX        ; for no write-thru)
	POPFD


Flags:

No flags are affected.


Timing:

CPU    | 88 86 286 386 486
Cycles | -  -   -   -   5

=====================================================================


> 	#ifdef GODDAMNED_CUTRATE_CACHE_IMPLEMENTATIONS
> 			wbinvd();
> 	#endif
[Deleted]

Why?  I realize that handling bus snooping should be done in hardware,
but there has to be a way to make these things work in software, without
kludging everything up beyond belief?!?  The dudes working on the i386
port, what do ya say?

--Toby.
*----------------------------------------------------------------------------*
| Tobias Weingartner | Email: weingart@BrandonU.Ca | Need a Unix sys-admin?  |
| Box 27, Beulah, MB |-----------------------------| Send E-Mail for resume, |
| R0M 0B0, Canada    | Unix Guru, Admin, Sys-Prgmr | and other details...    |
|----------------------------------------------------------------------------|
|      %SYSTEM-F-ANARCHISM, The operating system has been overthrown         |
*----------------------------------------------------------------------------*