Physical Memory, DMA, and I/O Mappings
Physical Memory, DMA, and I/O Mappings
- Subject: Physical Memory, DMA, and I/O Mappings
- From: Josh de Cesare <email@hidden>
- Date: Mon, 9 Sep 2002 09:42:40 -0700
We are in the process of making changes to the way the kernel handles
I/O mappings and physical memory addresses. The changes will be
released in a future update to Mac OS X 10.2. We have found that the
changes effect various drivers and will require those drivers to
change. Below is a description of each of the major changes and
suggestions about how drivers should be adapted. We do not expect
any performance issue or backward compatibility problems with drivers
once they have been adapted.
I/O Mappings:
Currently, the kernel maps PCI I/O & memory spaces such that the
kernel virtual address equals the physical address (V=R). Some
drivers access their registers by obtaining the physical address of
the registers then using the address as a normal virtual address.
This has never been correct, but has worked because of the V=R I/O
mappings. These extra mappings will no longer be available.
Drivers should create an explicit mapping for their memory and I/O
spaces. This can be done easily with methods like
provider->mapDeviceMemoryWithIndex. This will look up the range in
the provider and map it for the driver. The driver can then get the
virtual address. Some families have similar methods: IOPCIFamily
provides mapDeviceMemoryWithRegister so that the order of the spaces
need not be known, just which base address register the hardware uses.
pmap_extract and kvtophys:
These functions currently find the physical address for a page given
a virtual address and a page. Drivers often use this physical
address to setup DMA programs. Normally a driver uses physical page
addresses for two purposes: a small number of pages to hold the DMA
programs, and then a large number of pages that contain the data for
the I/O.
pmap_extract and kvtophys will no longer be available for use in drivers.
Drivers should use IOMemoryDescriptors to get physical page
addresses. For pages used to hold DMA programs,
IOBufferMemoryDescriptor will allocate and map memory for the driver.
getPhysicalSegment, or getPhysicalAddress will then return the
physical address to be given to DMA hardware. The driver must call
->prepare() on the IOBufferMemoryDescriptor before it is used. Call
->complete() and then ->release() when the memory is no longer
needed. Assuming the IOBufferMemoryDescriptor has been allocated
into the kernel task, the memory can be accessed normally by getting
its address with ->getBytesNoCopy(). If the driver does not map the
memory, it can still be accessed with ->readBytes(...) and
->writeBytes(...).
The I/O memory for most drivers will already be in a
IOMemoryDescriptor. If the data is not provided in an
IOMemoryDescriptor, the driver should wrap it with one;
IOMemoryDescriptor::withAddress(...). Use a loop across
getPhysicalSegment to determine the physical address of each page. Be
aware the getPhysicalSegment will also return a length, which can be
of any size and can be larger or smaller than one page. Drivers may
also use IOMemoryCursor to simplify the iteration process.
--
Josh de Cesare
Mac OS X - Core OS
Apple Computer, Inc.
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.