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 ) ;
}
Пример #2
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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;
}
Пример #6
0
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;
	}	
	
}