bool Core99NVRAM::start(IOService *provider) { IOMemoryMap *nvramMemoryMap; unsigned long gen1, gen2; // Get the base address for the nvram. nvramMemoryMap = provider->mapDeviceMemoryWithIndex(0); if (nvramMemoryMap == 0) return false; nvramBaseAddress = (unsigned char *)nvramMemoryMap->getVirtualAddress(); // Allocte the nvram shadow. nvramShadow = (unsigned char *)IOMalloc(kCore99NVRAMSize); if (nvramShadow == 0) return false; // Find the current nvram partition and set the next. gen1 = validateGeneration(nvramBaseAddress + kCore99NVRAMAreaAOffset); gen2 = validateGeneration(nvramBaseAddress + kCore99NVRAMAreaBOffset); if (gen1 > gen2) { generation = gen1; nvramCurrent = nvramBaseAddress + kCore99NVRAMAreaAOffset; nvramNext = nvramBaseAddress + kCore99NVRAMAreaBOffset; } else { generation = gen2; nvramCurrent = nvramBaseAddress + kCore99NVRAMAreaBOffset; nvramNext = nvramBaseAddress + kCore99NVRAMAreaAOffset; } // Copy the nvram into the shadow. bcopy(nvramCurrent, nvramShadow, kCore99NVRAMSize); return super::start(provider); }
IOBufferMemoryDescriptor* MemoryDmaAlloc(UInt32 buf_size, dma_addr_t *phys_add, void *virt_add) { IOBufferMemoryDescriptor *memBuffer; void *virt_address; dma_addr_t phys_address; IOMemoryMap *memMap; memBuffer = IOBufferMemoryDescriptor::inTaskWithOptions(kernel_task, kIODirectionOutIn | kIOMemoryPhysicallyContiguous | \ kIOMemoryAutoPrepare | kIOMapInhibitCache, buf_size, \ PAGE_SIZE); if (memBuffer == NULL) { //IOLog("Memory Allocation failed - RLC"); return NULL; } memMap = memBuffer->map(); if (memMap == NULL) { //IOLog("mapping failed\n"); memBuffer->release(); memBuffer = NULL; return NULL; } phys_address = memMap->getPhysicalAddress(); virt_address = (void *)memMap->getVirtualAddress(); if (virt_address == NULL || phys_address == NULL) { memMap->release(); memBuffer->release(); memBuffer = NULL; return NULL; } *phys_add = phys_address; *(IOVirtualAddress*)virt_add = (IOVirtualAddress)virt_address; memMap->release(); return memBuffer; }
// ---------------------------------------------------------------------------------------------------- IODBDMAChannelRegisters * PlatformInterfaceDBDMA_Mapped::GetOutputChannelRegistersVirtualAddress ( IOService * dbdmaProvider ) { IOMemoryMap * map; IOService * parentOfParent; debugIOLog (3, "+ PlatformInterfaceDBDMA_Mapped::GetOutputChannelRegistersVirtualAddress ( %p )", dbdmaProvider ); FailIf ( NULL == dbdmaProvider, Exit ); debugIOLog (3, " i2s-x name is %s", dbdmaProvider->getName() ); parentOfParent = (IOService*)dbdmaProvider->getParentEntry ( gIODTPlane ); FailIf ( NULL == parentOfParent, Exit ); debugIOLog (3, " parent of %s is %s", dbdmaProvider->getName(), parentOfParent->getName() ); map = parentOfParent->mapDeviceMemoryWithIndex ( AppleDBDMAAudio::kDBDMAOutputIndex ); FailIf ( NULL == map, Exit ); mIOBaseDMAOutput = (IODBDMAChannelRegisters *) map->getVirtualAddress(); debugIOLog (3, " mIOBaseDMAOutput virtual address %p is at physical address %p", mIOBaseDMAOutput, (void*)map->getPhysicalAddress() ); if ( NULL == mIOBaseDMAOutput ) { debugIOLog (1, " PlatformInterfaceDBDMA_Mapped::GetOutputChannelRegistersVirtualAddress IODBDMAChannelRegisters NOT IN VIRTUAL SPACE" ); } Exit: debugIOLog (3, "- PlatformInterfaceDBDMA_Mapped::GetOutputChannelRegistersVirtualAddress ( %p ) returns %p", dbdmaProvider, mIOBaseDMAOutput ); return mIOBaseDMAOutput; }
/** * Start this service. */ bool org_virtualbox_VBoxGuest::start(IOService *pProvider) { if (!IOService::start(pProvider)) return false; /* Low level initialization should be performed only once */ if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false)) { IOService::stop(pProvider); return false; } m_pIOPCIDevice = OSDynamicCast(IOPCIDevice, pProvider); if (m_pIOPCIDevice) { if (isVmmDev(m_pIOPCIDevice)) { /* Enable memory response from VMM device */ m_pIOPCIDevice->setMemoryEnable(true); m_pIOPCIDevice->setIOEnable(true); IOMemoryDescriptor *pMem = m_pIOPCIDevice->getDeviceMemoryWithIndex(0); if (pMem) { IOPhysicalAddress IOPortBasePhys = pMem->getPhysicalAddress(); /* Check that returned value is from I/O port range (at least it is 16-bit lenght) */ if((IOPortBasePhys >> 16) == 0) { RTIOPORT IOPortBase = (RTIOPORT)IOPortBasePhys; void *pvMMIOBase = NULL; uint32_t cbMMIO = 0; m_pMap = m_pIOPCIDevice->mapDeviceMemoryWithIndex(1); if (m_pMap) { pvMMIOBase = (void *)m_pMap->getVirtualAddress(); cbMMIO = m_pMap->getLength(); } int rc = VBoxGuestInitDevExt(&g_DevExt, IOPortBase, pvMMIOBase, cbMMIO, #if ARCH_BITS == 64 VBOXOSTYPE_MacOS_x64, #else VBOXOSTYPE_MacOS, #endif 0); if (RT_SUCCESS(rc)) { rc = VbgdDarwinCharDevInit(); if (rc == KMOD_RETURN_SUCCESS) { if (setupVmmDevInterrupts(pProvider)) { /* register the service. */ registerService(); LogRel(("VBoxGuest: IOService started\n")); return true; } LogRel(("VBoxGuest: Failed to set up interrupts\n")); VbgdDarwinCharDevRemove(); } else LogRel(("VBoxGuest: Failed to initialize character device (rc=%d).\n", rc)); VBoxGuestDeleteDevExt(&g_DevExt); } else LogRel(("VBoxGuest: Failed to initialize common code (rc=%d).\n", rc)); if (m_pMap) { m_pMap->release(); m_pMap = NULL; } } } else LogRel(("VBoxGuest: The device missing is the I/O port range (#0).\n")); } else
IOReturn SamplePCIUserClientClassName::method2( SampleStructForMethod2 * structIn, SampleResultsForMethod2 * structOut, IOByteCount inputSize, IOByteCount * outputSize ) { IOReturn err; IOMemoryDescriptor * memDesc = 0; UInt32 param1 = structIn->parameter1; uint64_t clientAddr = structIn->data_pointer; uint64_t size = structIn->data_length; // Rosetta if (fCrossEndian) { param1 = OSSwapInt32(param1); } IOLog("SamplePCIUserClient::method2(" UInt32_x_FORMAT ")\n", param1); IOLog( "fClientShared->string == \"%s\"\n", fClientShared->string ); structOut->results1 = 0x87654321; // Rosetta if (fCrossEndian) { structOut->results1 = OSSwapInt64(structOut->results1); clientAddr = OSSwapInt64(clientAddr); size = OSSwapInt64(size); } do { #if defined(__ppc__) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4) // construct a memory descriptor for the out of line client memory // old 32 bit API - this will fail and log a backtrace if the task is 64 bit IOLog("The Pre-Leopard way to construct a memory descriptor\n"); memDesc = IOMemoryDescriptor::withAddress( (vm_address_t) clientAddr, (IOByteCount) size, kIODirectionNone, fTask ); if (memDesc == NULL) { IOLog("IOMemoryDescriptor::withAddress failed\n"); err = kIOReturnVMError; continue; } #else // 64 bit API - works on all tasks, whether 64 bit or 32 bit IOLog("The Leopard and later way to construct a memory descriptor\n"); memDesc = IOMemoryDescriptor::withAddressRange( clientAddr, size, kIODirectionNone, fTask ); if (memDesc == NULL) { IOLog("IOMemoryDescriptor::withAddresswithAddressRange failed\n"); err = kIOReturnVMError; continue; } #endif // Wire it and make sure we can write it err = memDesc->prepare( kIODirectionOutIn ); if (kIOReturnSuccess != err) { IOLog("IOMemoryDescriptor::prepare failed(0x%08x)\n", err); continue; } // Generate a DMA list for the client memory err = fDriver->generateDMAAddresses(memDesc); // Other methods to access client memory: // readBytes/writeBytes allow programmed I/O to/from an offset in the buffer char pioBuffer[ 200 ]; memDesc->readBytes(32, &pioBuffer, sizeof(pioBuffer)); IOLog("readBytes: \"%s\"\n", pioBuffer); // map() will create a mapping in the kernel address space. IOMemoryMap* memMap = memDesc->map(); if (memMap) { char* address = (char *) memMap->getVirtualAddress(); IOLog("kernel mapped: \"%s\"\n", address + 32); memMap->release(); } else { IOLog("memDesc map(kernel) failed\n"); } // this map() will create a mapping in the users (the client of this IOUserClient) address space. #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 memMap = memDesc->map(fTask, 0, kIOMapAnywhere); #else memMap = memDesc->createMappingInTask(fTask, 0, kIOMapAnywhere); #endif if (memMap) { #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 IOLog("The pre-Leopard way to construct a memory descriptor\n"); // old 32 bit API - this will truncate and log a backtrace if the task is 64 bit IOVirtualAddress address32 = memMap->getVirtualAddress(); IOLog("user32 mapped: " VirtAddr_FORMAT "\n", address32); #else IOLog("The Leopard and later way to construct a memory descriptor\n"); // new 64 bit API - same for 32 bit and 64 bit client tasks mach_vm_address_t address64 = memMap->getAddress(); IOLog("user64 mapped: 0x%016llx\n", address64); memMap->release(); #endif } else { IOLog("memDesc map(user) failed\n"); } // Done with the I/O now. memDesc->complete( kIODirectionOutIn ); } while ( false ); if (memDesc) memDesc->release(); return err; }
bool AppleSamplePCI::start( IOService * provider ) { IOMemoryDescriptor * mem; IOMemoryMap * map; IOLog("AppleSamplePCI::start\n"); if( !super::start( provider )) return( false ); /* * Our provider class is specified in the driver property table * as IOPCIDevice, so the provider must be of that class. * The assert is just to make absolutely sure for debugging. */ assert( OSDynamicCast( IOPCIDevice, provider )); fPCIDevice = (IOPCIDevice *) provider; /* * Enable memory response from the card */ fPCIDevice->setMemoryEnable( true ); /* * Log some info about the device */ /* print all the device's memory ranges */ 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()); } /* look up a range based on its config space base address register */ mem = fPCIDevice->getDeviceMemoryWithRegister( kIOPCIConfigBaseAddress0 ); if( mem ) IOLog("Range@0x%x %08lx:%08lx\n", kIOPCIConfigBaseAddress0, mem->getPhysicalAddress(), mem->getLength()); /* map a range based on its config space base address register, * this is how the driver gets access to its memory mapped registers * the getVirtualAddress() method returns a kernel virtual address * for the register mapping */ map = fPCIDevice->mapDeviceMemoryWithRegister( kIOPCIConfigBaseAddress0 ); if( map ) { IOLog("Range@0x%x (%08lx) mapped to kernel virtual address %08x\n", kIOPCIConfigBaseAddress0, map->getPhysicalAddress(), map->getVirtualAddress()); /* release the map object, and the mapping itself */ map->release(); } /* read a config space register */ IOLog("Config register@0x%x = %08lx\n", kIOPCIConfigCommand, fPCIDevice->configRead32(kIOPCIConfigCommand) ); // construct a memory descriptor for a buffer below the 4Gb line & // so addressable by 32 bit DMA. This could be used for a // DMA program buffer for example IOBufferMemoryDescriptor * bmd = IOBufferMemoryDescriptor::inTaskWithPhysicalMask( // task to hold the memory kernel_task, // options kIOMemoryPhysicallyContiguous, // size 64*1024, // physicalMask - 32 bit addressable and page aligned 0x00000000FFFFF000ULL); if (bmd) { generateDMAAddresses(bmd); } else { IOLog("IOBufferMemoryDescriptor::inTaskWithPhysicalMask failed\n"); } fLowMemory = bmd; /* publish ourselves so clients can find us */ registerService(); return( true ); }
bool setOemProperties(IOService *provider) { SMBEntryPoint* eps = 0; IOMemoryDescriptor* dmiMemory = 0; IOItemCount dmiStructureCount = 0; UInt8* biosAddress = NULL; IOMemoryDescriptor * biosMemory = 0; IOMemoryMap * biosMap = 0; biosMemory = IOMemoryDescriptor::withPhysicalAddress( 0xf0000,0xfffff-0xf0000+1,kIODirectionOutIn); if(biosMemory) { biosMap = biosMemory->map(); if(biosMap) { biosAddress = (UInt8 *) biosMap->getVirtualAddress(); } } // Search 0x0f0000 - 0x0fffff for SMBIOS Ptr if(biosAddress) for (UInt32 Address = 0; Address < biosMap->getLength(); Address += 0x10) { if (*(UInt32 *)(biosAddress + Address) == SMBIOS_PTR) { eps = (SMBEntryPoint *)(biosAddress + Address); continue; } } if(eps) if (memcmp(eps->anchor, "_SM_", 4) == 0) { UInt8 csum; csum = checksum8(eps, sizeof(SMBEntryPoint)); /*HWSensorsDebugLog("DMI checksum = 0x%x", csum); HWSensorsDebugLog("DMI tableLength = %d", eps->dmi.tableLength); HWSensorsDebugLog("DMI tableAddress = 0x%x", (uint32_t) eps->dmi.tableAddress); HWSensorsDebugLog("DMI structureCount = %d", eps->dmi.structureCount); HWSensorsDebugLog("DMI bcdRevision = %x", eps->dmi.bcdRevision);*/ if (csum == 0 && eps->dmi.tableLength && eps->dmi.structureCount) { dmiStructureCount = eps->dmi.structureCount; dmiMemory = IOMemoryDescriptor::withPhysicalAddress( eps->dmi.tableAddress, eps->dmi.tableLength, kIODirectionOutIn ); } /*else { HWSensorsDebugLog("no DMI structure found"); }*/ } if (biosMap) OSSafeReleaseNULL(biosMap); if(biosMemory) OSSafeReleaseNULL(biosMemory); if ( dmiMemory ) { if (IOMemoryMap *fDMIMemoryMap = dmiMemory->map()) { decodeSMBIOSTable(provider, (void *) fDMIMemoryMap->getVirtualAddress(), fDMIMemoryMap->getLength(), dmiStructureCount ); OSSafeReleaseNULL(fDMIMemoryMap); } OSSafeReleaseNULL(dmiMemory); } return true; }