bool IOFWUserLocalIsochPort::initWithUserDCLProgram ( AllocateParams * params, IOFireWireUserClient & userclient, IOFireWireController & controller ) { // sanity checking if ( params->programExportBytes == 0 ) { ErrorLog ( "No program!" ) ; return false ; } fLock = IORecursiveLockAlloc () ; if ( ! fLock ) { ErrorLog ( "Couldn't allocate recursive lock\n" ) ; return false ; } // init easy params fUserObj = params->userObj ; fUserClient = & userclient ; fDCLPool = NULL ; fProgramCount = 0; fStarted = false ; IOReturn error = kIOReturnSuccess ; // get user program ranges: IOAddressRange * bufferRanges = new IOAddressRange[ params->bufferRangeCount ] ; if ( !bufferRanges ) { error = kIOReturnNoMemory ; } if ( !error ) { error = fUserClient->copyUserData(params->bufferRanges,(mach_vm_address_t)bufferRanges, sizeof ( IOAddressRange ) * params->bufferRangeCount ) ; } // create descriptor for program buffers IOMemoryDescriptor * bufferDesc = NULL ; if ( ! error ) { IOByteCount length = 0 ; for ( unsigned index = 0; index < params->bufferRangeCount; ++index ) { length += bufferRanges[ index ].length ; } bufferDesc = IOMemoryDescriptor::withAddressRanges ( bufferRanges, params->bufferRangeCount, kIODirectionOutIn, fUserClient->getOwningTask() ) ; if ( ! bufferDesc ) { error = kIOReturnNoMemory ; } else { // IOLog( "IOFWUserLocalIsochPort::initWithUserDCLProgram - checkMemoryInRange status 0x%08lx\n", checkMemoryInRange( bufferDesc, 0x000000001FFFFFFF ) ); error = bufferDesc->prepare( kIODirectionPrepareToPhys32 ) ; FWTrace( kFWTIsoch, kTPIsochPortUserInitWithUserDCLProgram, (uintptr_t)(fUserClient->getOwner()->getController()->getLink()), error, length, 0 ); // IOLog( "IOFWUserLocalIsochPort::initWithUserDCLProgram - prep 32 checkMemoryInRange status 0x%08lx\n", checkMemoryInRange( bufferDesc, 0x000000001FFFFFFF ) ); } } // create map for buffers; we will need to get a virtual address for them IOMemoryMap * bufferMap = NULL ; if ( !error ) { bufferMap = bufferDesc->map() ; if ( !bufferMap ) { DebugLog( "Couldn't map program buffers\n" ) ; error = kIOReturnVMError ; } bufferDesc->release() ; } IOMemoryDescriptor * userProgramExportDesc = NULL ; if ( !error ) { userProgramExportDesc = IOMemoryDescriptor::withAddressRange( params->programData, params->programExportBytes, kIODirectionOut, fUserClient->getOwningTask() ) ; } // get map of program export data if ( userProgramExportDesc ) { error = userProgramExportDesc->prepare() ; } if ( !error ) { DCLCommand * opcodes = NULL ; switch ( params->version ) { case kDCLExportDataLegacyVersion : error = importUserProgram( userProgramExportDesc, params->bufferRangeCount, bufferRanges, bufferMap ) ; ErrorLogCond( error, "importUserProgram returned %x\n", error ) ; if ( ! error ) { opcodes = (DCLCommand*)fProgramBuffer ; } break ; case kDCLExportDataNuDCLRosettaVersion : fDCLPool = fUserClient->getOwner()->getBus()->createDCLPool() ; if ( ! fDCLPool ) { error = kIOReturnNoMemory ; } if ( !error ) { error = fDCLPool->importUserProgram( userProgramExportDesc, params->bufferRangeCount, bufferRanges, bufferMap ) ; } fProgramBuffer = new UInt8[ sizeof( DCLNuDCLLeader ) ] ; { DCLNuDCLLeader * leader = (DCLNuDCLLeader*)fProgramBuffer ; { leader->pNextDCLCommand = NULL ; // unused - always NULL leader->opcode = kDCLNuDCLLeaderOp ; leader->program = fDCLPool ; } opcodes = (DCLCommand*)leader ; } break ; default : ErrorLog ( "unsupported DCL program type\n" ) ; error = kIOReturnBadArgument ; break ; } ErrorLogCond( !opcodes, "Couldn't get opcodes\n" ) ; IODCLProgram * program = NULL ; if ( opcodes ) { // IOFWLocalIsochPort::printDCLProgram( opcodes ) ; IOFireWireBus::DCLTaskInfoAux infoAux ; { infoAux.version = 2 ; infoAux.u.v2.bufferMemoryMap = bufferMap ; infoAux.u.v2.workloop = params->options & kFWIsochPortUseSeparateKernelThread ? createRealtimeThread() : NULL ; infoAux.u.v2.options = (IOFWIsochPortOptions)params->options ; } IOFireWireBus::DCLTaskInfo info = { 0, 0, 0, 0, 0, 0, & infoAux } ; program = fUserClient->getOwner()->getController()->getLink()->createDCLProgram( params->talking, opcodes, & info, params->startEvent, params->startState, params->startMask ) ; bufferMap->release() ; // retained by DCL program bufferMap = NULL ; if ( infoAux.u.v2.workloop ) { // If we created a custom workloop, it will be retained by the program... // We can release our reference... infoAux.u.v2.workloop->release() ; } DebugLogCond( !program, "createDCLProgram returned nil\n" ) ; } if ( program ) { if ( ! super::init( program, & controller ) ) { ErrorLog ( "IOFWUserIsochPort::init failed\n" ) ; error = kIOReturnError ; } } else { DebugLog ( "Couldn't create DCL program\n" ) ; error = kIOReturnNoMemory ; } userProgramExportDesc->complete() ; userProgramExportDesc->release() ; userProgramExportDesc = NULL ; } delete [] bufferRanges ; InfoLog( "-IOFWUserLocalIsochPort::initWithUserDCLProgram error=%x (build date "__TIME__" "__DATE__")\n", error ) ; return ( ! error ) ; }
bool X3100monitor::start(IOService * provider) { if (!provider || !super::start(provider)) return false; if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) { WarningLog("Can't locate fake SMC device, kext will not load"); return false; } IOMemoryDescriptor * theDescriptor; IOPhysicalAddress bar = (IOPhysicalAddress)((VCard->configRead32(kMCHBAR)) & ~0xf); DebugLog("Fx3100: register space=%08lx\n", (long unsigned int)bar); theDescriptor = IOMemoryDescriptor::withPhysicalAddress (bar, 0x2000, kIODirectionOutIn); // | kIOMapInhibitCache); if(theDescriptor != NULL) { mmio = theDescriptor->map(); if(mmio != NULL) { mmio_base = (volatile UInt8 *)mmio->getVirtualAddress(); #if DEBUG DebugLog(" MCHBAR mapped\n"); for (int i=0; i<0x2f; i +=16) { DebugLog("%04lx: ", (long unsigned int)i+0x1000); for (int j=0; j<16; j += 1) { DebugLog("%02lx ", (long unsigned int)INVID8(i+j+0x1000)); } DebugLog("\n"); } #endif } else { InfoLog(" MCHBAR failed to map\n"); return -1; } } char name[5]; //try to find empty key for (int i = 0; i < 0x10; i++) { snprintf(name, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, i); UInt8 length = 0; void * data = 0; IOReturn result = fakeSMC->callPlatformFunction(kFakeSMCGetKeyValue, true, (void *)name, (void *)&length, (void *)&data, 0); if (kIOReturnSuccess == result) { continue; } if (addSensor(name, TYPE_SP78, 2, i)) { numCard = i; break; } } if (kIOReturnSuccess != fakeSMC->callPlatformFunction(kFakeSMCAddKeyHandler, false, (void *)name, (void *)TYPE_SP78, (void *)2, this)) { WarningLog("Can't add key to fake SMC device, kext will not load"); return false; } return true; }
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; }
IOReturn org_pqrs_driver_KeyRemap4MacBook_UserClient_kext::callback_synchronized_communication(const BridgeUserClientStruct* inputdata, uint64_t* outputdata) { IOReturn result = kIOReturnSuccess; IOMemoryDescriptor* memorydescriptor = NULL; if (! inputdata || ! outputdata) { result = kIOReturnBadArgument; IOLOG_ERROR("UserClient_kext::callback_synchronized_communication kIOReturnBadArgument\n"); goto finish; } if (provider_ == NULL || isInactive()) { // Return an error if we don't have a provider. This could happen if the user process // called callback_synchronized_communication without calling IOServiceOpen first. // Or, the user client could be in the process of being terminated and is thus inactive. result = kIOReturnNotAttached; IOLOG_ERROR("UserClient_kext::callback_synchronized_communication kIOReturnNotAttached\n"); goto finish; } if (! provider_->isOpen(this)) { // Return an error if we do not have the driver open. This could happen if the user process // did not call callback_open before calling this function. result = kIOReturnNotOpen; IOLOG_ERROR("UserClient_kext::callback_synchronized_communication kIOReturnNotOpen\n"); goto finish; } memorydescriptor = IOMemoryDescriptor::withAddressRange(inputdata->data, inputdata->size, kIODirectionNone, task_); if (! memorydescriptor) { result = kIOReturnVMError; IOLOG_ERROR("UserClient_kext::callback_synchronized_communication kIOReturnVMError\n"); goto finish; } // wire it and make sure we can write it result = memorydescriptor->prepare(kIODirectionOutIn); if (kIOReturnSuccess != result) { IOLOG_ERROR("UserClient_kext::callback_synchronized_communication IOMemoryDescriptor::prepare failed(0x%x)\n", result); goto finish; } { // this map() will create a mapping in the users (the client of this IOUserClient) address space. IOMemoryMap* memorymap = memorydescriptor->map(); if (! memorymap) { result = kIOReturnVMError; IOLOG_ERROR("UserClient_kext::callback_synchronized_communication IOMemoryDescriptor::map failed\n"); } else { mach_vm_address_t address = memorymap->getAddress(); handle_synchronized_communication(inputdata->type, inputdata->option, address, inputdata->size, outputdata); memorymap->release(); } } // Done with the I/O now. memorydescriptor->complete(kIODirectionOutIn); finish: if (memorydescriptor) { memorydescriptor->release(); } return result; }
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; }
void NSC::Start() { IOMemoryDescriptor * theDescriptor; UInt32 adr = (ListenPortByte(NSC_MEM)&0xff)+((ListenPortByte(NSC_MEM+1)<<8)&0xff00)+ ((ListenPortByte(NSC_MEM+2)&0xff)<<16)+((ListenPortByte(NSC_MEM+3)&0xff)<<24); IOPhysicalAddress bar = (IOPhysicalAddress)(adr & ~0xf); // IOLog("Fx3100: register space=%08lx\n", (long unsigned int)bar); theDescriptor = IOMemoryDescriptor::withPhysicalAddress (bar, 0x200, kIODirectionOutIn); // | kIOMapInhibitCache); if(theDescriptor != NULL) { mmio = theDescriptor->map (); if(mmio != NULL) { // UInt32 addr = map->getPhysicalAddress(); mmio_base = (volatile UInt8 *)mmio->getVirtualAddress(); #if 0 UInt32 base_phys = (UInt32)mmio->getPhysicalAddress(); InfoLog(" Memory mapped at address %08lx\n", (long unsigned int)base_phys); for (int i=0; i<0x2f; i +=16) { IOLog("%04lx: ", (long unsigned int)i); for (int j=0; j<16; j += 1) { IOLog("%02lx ", (long unsigned int)mmio_base[i+j]); } IOLog("\n"); } //mmio->release(); #endif } else { InfoLog(" MCHBAR failed to map\n"); return; } } // Heatsink AddSensor(new NSCTemperatureSensor(this, 2, KEY_CPU_HEATSINK_TEMPERATURE, TYPE_SP78, 2)); // Northbridge AddSensor(new NSCTemperatureSensor(this, 0, KEY_NORTHBRIDGE_TEMPERATURE, TYPE_SP78, 2)); // Heatsink AddSensor(new NSCTemperatureSensor(this, 1, KEY_DIMM_TEMPERATURE, TYPE_SP78, 2)); // Northbridge AddSensor(new NSCTemperatureSensor(this, 3, KEY_AUX_TEMPERATURE, TYPE_SP78, 2)); char key[5]; int id=GetNextUnusedKey(KEY_FORMAT_FAN_ID, key); int ac=GetNextUnusedKey(KEY_FORMAT_FAN_SPEED, key); if (id!=-1 || ac!=-1) { int no=id>ac ? id : ac; char name[] = "System Fan"; int lname = sizeof(name); // snprintf (name, 10, "System Fan"); snprintf(key, 5, KEY_FORMAT_FAN_ID, no); FakeSMCAddKey(key, TYPE_CH8, lname, name); snprintf(key, 5, KEY_FORMAT_FAN_SPEED, no); AddSensor(new NSCTachometerSensor(this, 4, key, TYPE_FP2E, 2)); UpdateFNum(); FanCount = 1; } }