Physical Memory, DMA, and I/O Mappings
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 | darwin-kernel@lists.apple.com Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-kernel Do not post admin requests to the list. They will be ignored.
participants (1)
-
Josh de Cesare