Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Zero-copy PXI-X driver for G5 Mac, process access to 7 GB memory



The attachments got removed by there list. Here are the two files.


// BigDMA.h

#include <IOKit/IOService.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/IOUserClient.h>

class BigDMA : public IOService
{
OSDeclareDefaultStructors(BigDMA);


public:
ppnum_t mapperAddresses[4];
ppnum_t *realAddresses;
UInt32 taskBaseAddress;
UInt32 taskNumPages;

IOMemoryDescriptor *channelMD;

bool start(IOService *provider);
void stop(IOService *provider);

IOReturn registerMemory(task_t task, UInt32 offset, UInt32 length);
IOReturn unregisterMemory(task_t task, UInt32 offset, UInt32 length);
IOReturn sendMemory(task_t task, UInt32 offset, UInt32 length);
};


// BigDMA.cpp

#include <IOKit/IOLib.h>
#include <IOKit/IOService.h>
#include <IOKit/IOMapper.h>
#include <IOKit/IOBufferMemoryDescriptor.h>


#include "BigDMA.h"

#define super IOService
OSDefineMetaClassAndStructors(BigDMA, IOService);

bool BigDMA::start(IOService *provider)
{
if (!super::start(provider)) return false;

// Allocate a number of DMA windows, each 256 MB - 4 KB in size
mapperAddresses[0] = IOMapperIOVMAlloc(256 * 256 - 1);
mapperAddresses[1] = IOMapperIOVMAlloc(256 * 256 - 1);
mapperAddresses[2] = IOMapperIOVMAlloc(256 * 256 - 1);
mapperAddresses[3] = IOMapperIOVMAlloc(256 * 256 - 1);

// ...

return true;
}


void BigDMA::stop(IOService *provider)
{
super::stop(provider);

// Release memory descritors and free IOMapper addresses.

IOMapperIOVMFree(mapperAddresses[0], 256 * 256 - 1);
IOMapperIOVMFree(mapperAddresses[1], 256 * 256 - 1);
IOMapperIOVMFree(mapperAddresses[2], 256 * 256 - 1);
IOMapperIOVMFree(mapperAddresses[3], 256 * 256 - 1);
}


IOReturn BigDMA::registerMemory(task_t task, UInt32 offset, UInt32 length)
{
UInt32 count, cnt, curLength, tmpLength;
IOMemoryDescriptor *md;

// Register a user memory buffer from a client. The memory must
have been wired by the client (vm_wire or mlock)
// offset is assume to be page aligned
// The length can be any number of whole pages.

length = (length + 0xFFF) & 0xFFFFF000;

taskNumPages = length >> 12;

// Save this off in a control structure with the task and client
vm address.
realAddresses = (ppnum_t *)IOMalloc(taskNumPages * sizeof(ppnum_t));

taskBaseAddress = offset;

// Save the page numbers for each page.
// Create a memory descriptor on each 1 MB of user memory and get
the real physical addresses.

count = 0;
while (count < taskNumPages) {

curLength = 0x100;
if (taskNumPages < (count + curLength)) curLength =
taskNumPages - count;

md = IOMemoryDescriptor::withAddress(offset + count << 12,
curLength << 12, kIODirectionOutIn, task);
md->prepare();

// Get the 64 bit physical addresses of each page in the
memory descriptor
for (cnt = 0; cnt < curLength; cnt++) {
realAddresses[count + cnt] =
(UInt32)(md->getPhysicalSegment64(cnt << 12, &tmpLength) >> 12);
}

count += curLength;

md->complete();
md->release();
}

return kIOReturnSuccess;
}

IOReturn BigDMA::unregisterMemory(task_t task, UInt32 offset, UInt32 length)
{
// Clean up as needed.

// Find the memory in the control structures and tear it down.

return kIOReturnSuccess;
}

IOReturn BigDMA::sendMemory(task_t task, UInt32 offset, UInt32 length)
{
UInt32 cnt, curPage, numPages, startPage, pageCount;

// offset is assumed to be page aligned and length is assumed to
be whole pages

// Find the client memory in the control structures to get the page list.

startPage = (offset - taskBaseAddress) >> 12;
pageCount = length >> 12;

// Map the memory into the DART using 1 to 4 of the segments.
// Large than 1 GB - 16 KB is needed, loop based on 256MB - 4KB chunks.
cnt = 0;
curPage = 0;
while (curPage < pageCount) {
numPages = pageCount - curPage;
if (numPages > (256 * 256 - 1)) numPages = 256 * 256 - 1;
IOMapperInsertPPNPages(mapperAddresses[cnt], 0, realAddresses
+ startPage + curPage, numPages);

pageCount -= numPages;
cnt++;
}

// Start the DMA and wait for completion.
// Use the mapperAddresses[0 .. 3] as the physical page numbers
for the DMA.
// This could be broken into two function, a request and a completion.

return kIOReturnSuccess;
}
_______________________________________________
darwin-drivers mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/darwin-drivers
Do not post admin requests to the list. They will be ignored.

References: 
 >Re: Zero-copy PXI-X driver for G5 Mac, process access to 7 GB memory (From: Andrew Gallatin <email@hidden>)
 >Re: Zero-copy PXI-X driver for G5 Mac, process access to 7 GB memory (From: Josh de Cesare <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.