Subject: Pages, Caching, DMA
To: None <tech-kern@netbsd.org>
From: Michael R. Zucca <mrz5149@acm.org>
List: tech-kern
Date: 02/02/2002 14:14:09
I'm trying to write a DMA SCSI disk driver for the mac68k port for
660AV/840AV Macs and I've got a nice prototype driver that does DMA into
some fixed buffers and then bcopy's the data into the final data area.
Needless to say on an old 68040, the bcopy is *not* something I want to be
doing. Luckily, the SCSI DMA channel can blast data starting at any
physical address for just about any physically contiguous length. So I'd
like to use the capability to blast data to/from the target addresses
rather than first into a bounce buffer.

This is all well and good but the catch is that the DMA is not aware of the
cache on the 040. :( This causes problems only if I have a situation where
the CPU is using a page simultaneously with the DMA controller. If the CPU
stays away from the page during the transfer I can just flush the page from
cache before writing to the device and invalidate the page after a read. If
the CPU insists on using the page at the same time, I'm screwed because I
could potentially trash CPU data if I invalidate and I could potentially
trash DMA data if I flush.

I've noticed that there seem to be three different types of transfers once
the system gets going:
1. SCSI transfers which happen to message buffers for the purposes of
controlling devices.
2. Data transfers that are some multiple of a page size (4k)
3. Data transfers that are less than a page but around 1k or 2k.

I can avoid coherency issues with #1 by telling the SCSI code to use
pre-allocated message buffers which reside on their own page. And #2 is
easy because the data lives on its own page. Unfortunately, I'm stuck for
#3.

So my question is this: When the system passes an address to the SCSI
subsystem for a transfer, is it expected that the rest of the data on the
page is pretty much "don't care" for the duration of the transfer or can
the CPU possibly be operating on the page during a transfer?

If the answer is that the CPU is active on the page, then for transfers
under 1 page I'll have to DMA to/from a bounce buffer and bcopy to/from to
the partial page. If the answer is that the CPU stays away from the page I
can DMA directly to/from the page and flush/invalidate as necessary. That
is, unless somebody has a better idea :-)

Please direct responses to my email address as well as tech-kern since I'm
not currently subscribed to tech-kern.

Many thanks!

----------------------------------------------
 Michael Zucca - mrz5149@acm.org
----------------------------------------------
 "I'm too old to use Emacs." -- Rod MacDonald
----------------------------------------------