allocating non-cacheable regions

Steve Rossi srossi at
Sat Jun 3 00:24:14 EST 2000

well it sort of works. I think I'm running into some strange compiler problems.
There are four scenarios that I'm working with. They are:

compiling driver as a module using x86 cross-compiler - doesn't work
compiling driver as a module using native compiler - works

compiling driver into the kernel using x86 cross-compiler - doesn't work
compiling driver into the kernel using native compiler - sorta works

when I say doesn't work, I mean that invalidate_dcache_range is having no effect -
the powerpc is always getting bad data when it reads memory that was written by the
device - in this case a SCSI controller
when I say sorta works, I mean that what I've observed is the first chunk of data
returned by the scsi controller for the first query command seems to be correct or
partially correct, but subsequent data is not
when I say works - that means it completely works, I can mount the filesystem on the
scsi disk and read and write files with no problem

when I compile on x86 it never works (monta vista cdk, gcc version 2.95.2 19991024
(release)) whether I compile it as a module or into the kernel. compiler
bug? something to do with the fact that invalidate_dcache_range is an assembly
routine? any thoughts on this?

when I compile on ppc (g4 running yellow dog linux cs 1.2, gcc version 2.95.2
19991024 (release/franzo)) I can only get it to work as a module. this is ok, but
not ideal. I would like to be able to compile the driver into the kernel. Does
anyone have any ideas as to why it would be different with respect to regions marked
as no-cache when compiled as a module versus when compiled into the kernel?

will somone verify that my assumptions are correct - the driver that I'm working
with allocates memory for its own data structures - both those used only by the
driver and those shared between the driver and the device - using get_free_pages().
I'm taking the simple approach - attempting to make all of that memory that the
driver allocates non-cacheable - that is I want it to always access external memory
on both write and reads to these addresses and never use the cache.  So for each
call to get_free_pages (which is always called with order = 0 so only returns a
pointer to one page) I track down the pte, mark it as _PAGE_NO_CACHE then flush the
tlb using flush_tlb_page, then invalidate the cache using invalidate_dcache_range
passing the address returned by get_free_pages as the start and that address +
PAGE_SIZE as the end. My assumption is that this is sufficient to ensure that all
further accesses to the addresses within this page will bypass the cache. This
assumption seems to hold for the case of writing to these addresses - as the
_PAGE_NO_CACHE flag appears to force it to writethrough. But I'm a little leary as
to whether I need to invalidate the cache each time before I read these addresses.
I would like to not have to do that. If what I'm doing isn't sufficient to ensure
that reads will never come from the cache, is there something else I can do to
ensure that?

regarding multiple mapping the same physical address - I don't believe that's
happening - or at least the driver isn't doing anything that would cause that to
happen as far as I can tell.


Steve Rossi wrote:

> Well I found the solution - I needed to added an  extern
> invalidate_dcache_range() declaration to include/asm/cache.h then the kernel will
> compile with invalidate_dcache_range exported in ppc_ksyms.c (contrary to what
> I reported, my problem with compiling the device driver as a module was that the
> kernel wouldn't compile with invalidate_dcache_range exported - not that it
> wouldn't boot. I just wasn't remembering correctly when I wrote that.) Now I can
> compile the driver as a module with invalidate_dcache_range and it works!

Steven K. Rossi                     srossi at
Staff Engineer
Multimedia Communications Research Laboratory
Motorola Labs

** Sent via the linuxppc-embedded mail list. See

More information about the Linuxppc-embedded mailing list