AppleSamplePCI.cpp [plain text]
#include "AppleSamplePCI.h"
#include <IOKit/IOLib.h>
#include <IOKit/assert.h>
#define super IOService
OSDefineMetaClassAndStructors( AppleSamplePCI, IOService );
bool AppleSamplePCI::start( IOService * provider )
{
IOMemoryDescriptor * mem;
IOMemoryMap * map;
IOLog("AppleSamplePCI::start\n");
if( !super::start( provider ))
return( false );
assert( OSDynamicCast( IOPCIDevice, provider ));
fPCIDevice = (IOPCIDevice *) provider;
fPCIDevice->setMemoryEnable( true );
for( UInt32 index = 0;
index < fPCIDevice->getDeviceMemoryCount();
index++ ) {
mem = fPCIDevice->getDeviceMemoryWithIndex( index );
assert( mem );
IOLog("Range[%ld] %08lx:%08lx\n", index,
mem->getPhysicalAddress(), mem->getLength());
}
mem = fPCIDevice->getDeviceMemoryWithRegister(
kIOPCIConfigBaseAddress0 );
if( mem )
IOLog("Range@0x%x %08lx:%08lx\n", kIOPCIConfigBaseAddress0,
mem->getPhysicalAddress(), mem->getLength());
map = fPCIDevice->mapDeviceMemoryWithRegister(
kIOPCIConfigBaseAddress0 );
if( map ) {
IOLog("Range@0x%x (%08lx) mapped to kernel virtual address %08x\n",
kIOPCIConfigBaseAddress0,
map->getPhysicalAddress(),
map->getVirtualAddress());
map->release();
}
IOLog("Config register@0x%x = %08lx\n", kIOPCIConfigCommand,
fPCIDevice->configRead32(kIOPCIConfigCommand) );
IOBufferMemoryDescriptor * bmd =
IOBufferMemoryDescriptor::inTaskWithPhysicalMask(
kernel_task,
kIOMemoryPhysicallyContiguous,
64*1024,
0x00000000FFFFF000ULL);
if (bmd) {
generateDMAAddresses(bmd);
} else {
IOLog("IOBufferMemoryDescriptor::inTaskWithPhysicalMask failed\n");
}
fLowMemory = bmd;
registerService();
return( true );
}
void AppleSamplePCI::stop( IOService * provider )
{
IOLog("AppleSamplePCI::stop\n");
super::stop( provider );
}
IOMemoryDescriptor * AppleSamplePCI::copyGlobalMemory( void )
{
IOMemoryDescriptor * memory;
memory = fPCIDevice->getDeviceMemoryWithRegister( kIOPCIConfigBaseAddress0 );
if( memory)
memory->retain();
return( memory );
}
IOReturn AppleSamplePCI::generateDMAAddresses( IOMemoryDescriptor * memDesc )
{
IODMACommand * cmd;
IOReturn err = kIOReturnSuccess;
IOByteCount offset = 0;
IOPhysicalAddress physicalAddr;
IOPhysicalLength segmentLength;
UInt32 index = 0;
while( (physicalAddr = memDesc->getPhysicalSegment( offset, &segmentLength ))) {
IOLog("Physical segment(%ld) %08lx:%08lx\n", index, physicalAddr, segmentLength);
offset += segmentLength;
index++;
}
do
{
cmd = IODMACommand::withSpecification(
kIODMACommandOutputHost64,
64,
0,
IODMACommand::kMapped,
0,
1 );
if (!cmd)
{
IOLog("IODMACommand::withSpecification failed\n");
break;
}
err = cmd->setMemoryDescriptor(memDesc);
if (kIOReturnSuccess != err)
{
IOLog("setMemoryDescriptor failed (0x%x)\n", err);
break;
}
UInt64 offset = 0;
while ((kIOReturnSuccess == err) && (offset < memDesc->getLength()))
{
IODMACommand::Segment64 segments[1];
UInt32 numSeg = 1;
err = cmd->gen64IOVMSegments(&offset, &segments[0], &numSeg);
IOLog("gen64IOVMSegments(%x) addr 0x%qx, len 0x%qx, nsegs %ld\n",
err, segments[0].fIOVMAddr, segments[0].fLength, numSeg);
}
err = cmd->clearMemoryDescriptor();
if (kIOReturnSuccess != err)
{
IOLog("clearMemoryDescriptor failed (0x%x)\n", err);
}
}
while (false);
if (cmd)
cmd->release();
do
{
cmd = IODMACommand::withSpecification(
kIODMACommandOutputHost32,
32,
0,
IODMACommand::kMapped,
0,
1 );
if (!cmd)
{
IOLog("IODMACommand::withSpecification failed\n");
break;
}
err = cmd->setMemoryDescriptor(memDesc);
if (kIOReturnSuccess != err)
{
IOLog("setMemoryDescriptor failed (0x%x)\n", err);
break;
}
UInt64 offset = 0;
while ((kIOReturnSuccess == err) && (offset < memDesc->getLength()))
{
IODMACommand::Segment32 segments[1];
UInt32 numSeg = 1;
err = cmd->gen32IOVMSegments(&offset, &segments[0], &numSeg);
IOLog("gen32IOVMSegments(%x) addr 0x%lx, len 0x%lx, nsegs %ld\n",
err, segments[0].fIOVMAddr, segments[0].fLength, numSeg);
}
err = cmd->clearMemoryDescriptor();
if (kIOReturnSuccess != err)
{
IOLog("clearMemoryDescriptor failed (0x%x)\n", err);
}
}
while (false);
if (cmd)
cmd->release();
return (err);
}