[comp.sys.mips] Wiring down physical pages

ajc@bbn.com (Anthony J. Courtemanche) (11/21/89)

I am trying to write a device driver for a MIPS M2000 and am having
trouble understanding the virtual memory system.  I have 3 simple
questions that unfortunately I couldn't get answered from the MIPS
software support phoneline.  They suggested I try here (which sounded
to me like a big cop-out by the software support people, but maybe
I'll get lucky) so here goes.  I also tried looking at some device
drivers supplied by MIPS, but they all were super complicated and I
couldn't seem to find the answers to my 3 simple questions there
either.

I have a device to plug into the M2000 (running RISC/os 4.20) that
wants to do DMA.  I have three problems that I must solve:

	1) The device needs some contiguous memory to write into.
	   This memory is larger than a physical page (4K). How
	   do I allocate this memory in the device driver?  My current
	   solution is to declare a large global static array in the
	   device driver code.  Either by chance or by design, upon
	   checking, this array IS physically contigous, which is
	   good.  Should I be allocating this memory by another means?

	2) In order to not have any surprises, the virtual memory
	   system better not use these physical pages to map random
	   virtual addresses later on.  These physical pages need to
	   be "wired down" and reserved for this kernel resource.
	   How do I do this?  Upon checking, the static array is in
	   the "kseg0" segment of the kernel, but I do not know
	   whether or not this has any bearing on whether this memory
	   can be swapped or not.  Also, for ease of use, I would like
	   these physical pages to bypass the cache, so that when the
	   device writes into this memory, the cpu won't see stale
	   data still in the cache.  I know there exists the cachectl
	   call to modify the cacheability of specific pages.  Is this
	   the proper call to make in the device driver?

	3) User applications programs will need to access this kernel
	   reserved memory that the device is writing into.  These
	   applications programs just want to map in these physical
	   pages into their own address space and access them as if
	   they were normal addresses in their address space.  How do
	   I do this?

If anyone out there in net-land knows any answers to these, please let
me know.
--Anthony Courtemanche
  ajc@bbn.com

mash@mips.COM (John Mashey) (11/22/89)

In article <48553@bbn.COM> ajc@bbn.com (Anthony J. Courtemanche) writes:

>I am trying to write a device driver for a MIPS M2000 and am having
>trouble understanding the virtual memory system.  I have 3 simple
>questions that unfortunately I couldn't get answered from the MIPS
>software support phoneline.  They suggested I try here (which sounded
>to me like a big cop-out by the software support people, but maybe
>I'll get lucky) so here goes.  I also tried looking at some device
>drivers supplied by MIPS, but they all were super complicated and I
>couldn't seem to find the answers to my 3 simple questions there
>either.

>I have a device to plug into the M2000 (running RISC/os 4.20) that
>wants to do DMA.  I have three problems that I must solve:
>
>	1) The device needs some contiguous memory to write into.
>	   This memory is larger than a physical page (4K). How
>	   do I allocate this memory in the device driver?  My current
>	   solution is to declare a large global static array in the
>	   device driver code.  Either by chance or by design, upon
>	   checking, this array IS physically contigous, which is
>	   good.  Should I be allocating this memory by another means?
This is fine, although you could dynamically allocate it in your ....init
entry also, and eitehr would be fine.  Lots of drivers have static space
allocations, and nothing in the kernel runs around and grabs that space.
If you allocate space, it will be:
	contiguous in kseg0 (the normal place)
	contiguous in kseg1 (when referenced with the appropriate bits
		OR'd with the address to get into K1.  I.e., look at
		/usr/include/sys/sbd.h for the address conversion macros.
		specifically, while x = &y; gets you the K0 version,
		x = K0_TO_K1(&y) gets you uncached address of same word.
	wherever it would be, if you also mapped kseg2 or kuseg entries
	on top of it as well.
>
>	2) In order to not have any surprises, the virtual memory
>	   system better not use these physical pages to map random
>	   virtual addresses later on.  These physical pages need to
It won't; just allocate the space.
>	   be "wired down" and reserved for this kernel resource.
>	   How do I do this?  Upon checking, the static array is in
>	   the "kseg0" segment of the kernel, but I do not know
>	   whether or not this has any bearing on whether this memory
>	   can be swapped or not.  Also, for ease of use, I would like
Unswappable.
>	   these physical pages to bypass the cache, so that when the
>	   device writes into this memory, the cpu won't see stale
>	   data still in the cache.  I know there exists the cachectl
>	   call to modify the cacheability of specific pages.  Is this
>	   the proper call to make in the device driver?
You can do this two ways: flush the cache before doing input, or reference
the space through the kseg1 space (uncached access).
Since K0/K1 pages don't use TLB entries, you don't use cachectl(2)
at the kernel level, you use at at the user level, since anything there
needs TLB entries.
>
>	3) User applications programs will need to access this kernel
>	   reserved memory that the device is writing into.  These
>	   applications programs just want to map in these physical
>	   pages into their own address space and access them as if
>	   they were normal addresses in their address space.  How do
>	   I do this?
use mmap(2).

---------
To summarize:
	1) Allocate N pages of space in your driver, starting on a page
	boundary.  It will be contiguous in both K0 & K1.  You may want to
	look at the .align directive in the assembler manual.
	2) In the user process
		mmap the space in
		use cachectl to make it uncached, if that's what you want.
	3) In the kernel, just reference it thru the K1 version of the address.

maybe somebody from OS group will post something better, but this should
work.
-- 
-john mashey	DISCLAIMER: <generic disclaimer, I speak for me only, etc>
UUCP: 	{ames,decwrl,prls,pyramid}!mips!mash  OR  mash@mips.com
DDD:  	408-991-0253 or 408-720-1700, x253
USPS: 	MIPS Computer Systems, 930 E. Arques, Sunnyvale, CA 94086