Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/*
 * free:
 *
 * Free resources
 */
void IOBufferMemoryDescriptor::free()
{
    // Cache all of the relevant information on the stack for use
    // after we call super::free()!
    IOOptionBits     flags         = _flags;
    IOOptionBits     internalFlags = _internalFlags;
    IOOptionBits     options   = _options;
    vm_size_t        size      = _capacity;
    void *           buffer    = _buffer;
    IOMemoryMap *    map       = 0;
    IOAddressRange * range     = _ranges.v64;
    vm_offset_t      alignment = _alignment;

    if (alignment >= page_size)
	size = round_page(size);

    if (reserved)
    {
	map = reserved->map;
        IODelete( reserved, ExpansionData, 1 );
	if (map)
	    map->release();
    }

    /* super::free may unwire - deallocate buffer afterwards */
    super::free();

    if (options & kIOMemoryPageable)
    {
#if IOALLOCDEBUG
	debug_iomallocpageable_size -= round_page(size);
#endif
    }
    else if (buffer)
    {
	if (kInternalFlagPageSized & internalFlags) size = round_page(size);

        if (kInternalFlagPhysical & internalFlags)
        {
            IOKernelFreePhysical((mach_vm_address_t) buffer, size);
	}
	else if (kInternalFlagPageAllocated & internalFlags)
	{
            iopa_free((uintptr_t) buffer, size);
	}
        else if (alignment > 1)
	{
            IOFreeAligned(buffer, size);
	}
        else
	{
            IOFree(buffer, size);
	}
    }
    if (range && (kIOMemoryAsReference & flags))
	IODelete(range, IOAddressRange, 1);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
void SoftU2FUserClient::frameReceivedGated(IOMemoryDescriptor *report) {
  IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, report);

  IOMemoryMap *reportMap = nullptr;

  if (isInactive())
    return;

  if (report->prepare() != kIOReturnSuccess)
    return;

  reportMap = report->map();

  // Notify userland that we got a report.
  if (_notifyRef && reportMap->getLength() == sizeof(U2FHID_FRAME)) {
    io_user_reference_t *args = (io_user_reference_t *)reportMap->getAddress();
    sendAsyncResult64(*_notifyRef, kIOReturnSuccess, args, sizeof(U2FHID_FRAME) / sizeof(io_user_reference_t));
  }

  reportMap->release();
  report->complete();
}
Exemplo n.º 5
0
//	----------------------------------------------------------------------------------------------------
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;
}
bool AppleSamsungSerialDeviceSync::start(IOService *provider) {
    IOMemoryMap* memoryMap;
    uint32_t uartBase;
    
    if(!provider) {
        panic("provider should not be null");
    }
    
    memoryMap = provider->mapDeviceMemoryWithIndex(0);
    if(!memoryMap) {
        panic("failed to get physical device memory map");
    }
    
    uartBase = memoryMap->getPhysicalAddress();
    
    SERIAL_LOG("Detected uart at PA:0x%08x\n",  uartBase);
    
    memoryMap->release();
    
    registerService();

    return true;
}
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 ) ;
}
Exemplo n.º 8
0
//	----------------------------------------------------------------------------------------------------
bool	PlatformInterfaceDBDMA_Mapped::init ( IOService* device, AppleOnboardAudio* provider, UInt32 inDBDMADeviceIndex )
{
	bool					result = FALSE;
	IOService* 				theService;
	IORegistryEntry			*macio;
	IORegistryEntry			*gpio;
	IORegistryEntry			*i2s;
	IORegistryEntry			*i2sParent;
	IOMemoryMap				*map;

	debugIOLog ( 3, "+ PlatformInterfaceDBDMA_Mapped::init ( %p, %p, %d )", device, provider, inDBDMADeviceIndex );
	
	FailIf ( NULL == provider, Exit );
	FailIf ( NULL == device, Exit );

	result = super::init ( device, provider, inDBDMADeviceIndex );
	if ( result ) 
	{
		mKeyLargoService = IOService::waitForService ( IOService::serviceMatching ( "KeyLargo" ) );
		debugIOLog ( 3, "  sound's name is %s",  ( (IORegistryEntry*)device)->getName () );
		
		i2s =  ( ( IORegistryEntry*)device)->getParentEntry ( gIODTPlane );
		FailWithAction ( 0 == i2s, result = false, Exit );
		debugIOLog ( 3, "  parent name is '%s'", i2s->getName () );

		if ( 0 == strcmp ( "i2s-a", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell0;
		}
		else if ( 0 == strcmp ( "i2s-b", i2s->getName () ) ) 
		{
			mI2SInterfaceNumber = kUseI2SCell1;
		}
		else if ( 0 == strcmp ( "i2s-c", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell2;
		}
		else if ( 0 == strcmp ( "i2s-d", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell3;
		}
		else if ( 0 == strcmp ( "i2s-e", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell4;
		}
		else if ( 0 == strcmp ( "i2s-f", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell5;
		}
		else if ( 0 == strcmp ( "i2s-g", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell6;
		}
		else if ( 0 == strcmp ( "i2s-h", i2s->getName () ) )
		{
			mI2SInterfaceNumber = kUseI2SCell7;
		}
		debugIOLog ( 5, "  mI2SInterfaceNumber = %d", mI2SInterfaceNumber );
		
		i2sParent = i2s->getParentEntry ( gIODTPlane );
		FailWithAction ( 0 == i2sParent, result = false, Exit );
		debugIOLog ( 3, "  parent name of '%s' is %s", i2s->getName (), i2sParent->getName () );

		macio = i2sParent->getParentEntry ( gIODTPlane );
		FailWithAction ( 0 == macio, result = false, Exit );
		debugIOLog ( 3, "  macio name is %s", macio->getName () );
		
		gpio = macio->childFromPath ( kGPIODTEntry, gIODTPlane);
		FailWithAction ( !gpio, result = false, Exit);
		debugIOLog ( 3, "  gpio name is %s", gpio->getName () );

		theService = ( OSDynamicCast ( IOService, i2s ) );
		FailWithAction ( !theService, result = false, Exit );

		map = theService->mapDeviceMemoryWithIndex ( inDBDMADeviceIndex );
		FailWithAction ( 0 == map, result = false, Exit );

		// cache the config space
		mSoundConfigSpace = (UInt8 *)map->getPhysicalAddress();

		// sets the clock base address figuring out which I2S cell we're on
		if ((((UInt32)mSoundConfigSpace ^ kI2S0BaseOffset) & 0x0001FFFF) == 0) 
		{
			//	[3060321]	ioBaseAddress is required by this object in order to enable the target
			//				I2S I/O Module for which this object is to service.  The I2S I/O Module
			//				enable occurs through the configuration registers which reside in the
			//				first block of ioBase.		rbm		2 Oct 2002
			mIOBaseAddress = (void *)((UInt32)mSoundConfigSpace - kI2S0BaseOffset);
			mIOBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace - kI2S0BaseOffset), 256);
			mI2SInterfaceNumber = kUseI2SCell0;
		}
		else if ((((UInt32)mSoundConfigSpace ^ kI2S1BaseOffset) & 0x0001FFFF) == 0) 
		{
			//	[3060321]	ioBaseAddress is required by this object in order to enable the target
			//				I2S I/O Module for which this object is to service.  The I2S I/O Module
			//				enable occurs through the configuration registers which reside in the
			//				first block of ioBase.		rbm		2 Oct 2002
			mIOBaseAddress = (void *)((UInt32)mSoundConfigSpace - kI2S1BaseOffset);
			mIOBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace - kI2S1BaseOffset), 256);
			mI2SInterfaceNumber = kUseI2SCell1;
		}
		else 
		{
			debugIOLog (3, "  AudioI2SControl::init ERROR: unable to setup ioBaseAddress and i2SInterfaceNumber");
		}
		FailIf (NULL == mIOBaseAddressMemory, Exit);

		//	[3060321]	ioConfigurationBaseAddress is required by this object in order to enable the target
		//				I2S I/O Module for which this object is to service.  The I2S I/O Module
		//				enable occurs through the configuration registers which reside in the
		//				first block of ioBase.		rbm		2 Oct 2002
		
		mIOConfigurationBaseAddress = (void *)mIOBaseAddressMemory->map()->getVirtualAddress();
		FailIf ( NULL == mIOConfigurationBaseAddress, Exit );

		//
		//	There are three sections of memory mapped I/O that are directly accessed by the Apple02Audio.  These
		//	include the GPIOs, I2S DMA Channel Registers and I2S control registers.  They fall within the memory map 
		//	as follows:
		//	~                              ~
		//	|______________________________|
		//	|                              |
		//	|         I2S Control          |
		//	|______________________________|	<-	soundConfigSpace = ioBase + i2s0BaseOffset ...OR... ioBase + i2s1BaseOffset
		//	|                              |
		//	~                              ~
		//	~                              ~
		//	|______________________________|
		//	|                              |
		//	|       I2S DMA Channel        |
		//	|______________________________|	<-	i2sDMA = ioBase + i2s0_DMA ...OR... ioBase + i2s1_DMA
		//	|                              |
		//	~                              ~
		//	~                              ~
		//	|______________________________|
		//	|            FCRs              |
		//	|            GPIO              |	<-	gpio = ioBase + gpioOffsetAddress
		//	|         ExtIntGPIO           |	<-	fcr = ioBase + fcrOffsetAddress
		//	|______________________________|	<-	ioConfigurationBaseAddress
		//	|                              |
		//	~                              ~
		//
		//	The I2S DMA Channel is mapped in by the Apple02DBDMAAudioDMAEngine.  Only the I2S control registers are 
		//	mapped in by the AudioI2SControl.  The Apple I/O Configuration Space (i.e. FCRs, GPIOs and ExtIntGPIOs)
		//	are mapped in by the subclass of Apple02Audio.  The FCRs must also be mapped in by the AudioI2SControl
		//	object as the init method must enable the I2S I/O Module for which the AudioI2SControl object is
		//	being instantiated for.
		//
		//	The physical addresses for memory mapped I/O within the KeyLargo system I/O controller are as follows:
		//	
		//
		//
		//                                       ______________________________
		//                                     /|                              |
		//                                    / |                              |
		//	                                 /  |______________________________|
		//	 ______________________________ /   |                              |
		//	|                              |    |       I2S 1 ('i2s-b')        |
		//	|                              |    |______________________________|....0xnnn11000	[0x80011000]
		//	|                              |    |                              |
		//	|                              |    |       I2S 0 ('i2s-a')        |
		//	|                              |    |______________________________|....0xnnn10000	[0x80001000]
		//	|       Device Registers       |   / 
		//	|                              |  /
		//	|                              | /   ______________________________ 
		//	|                              |/  /|                              |
		//	|______________________________|__/ |                              |
		//	|                              |    |______________________________|
		//	|                              |    |                              |
		//	|                              |    |    I2S 1 Rx DMA ('i2s-b')    |
		//	|                              |    |______________________________|....0xnnn08300	[0x80008300]
		//	|    DMA Channel Registers     |    |                              |
		//	|                              |    |    I2S 1 Tx DMA ('i2s-b')    |
		//	|                              |    |______________________________|....0xnnn08200	[0x80008200]
		//	|                              |    |                              |
		//	|______________________________|    |    I2S 0 Rx DMA ('i2s-a')    |
		//	|                              |\   |______________________________|....0xnnn08100	[0x80008100]
		//	|                              | \  |                              |
		//	|      Reserved: read "0"      |  \ |    I2S 0 Tx DMA ('i2s-a')    |
		//	|                              |   \|______________________________|....0xnnn08000	[0x80008000]
		//	|______________________________|
		//	|                              |
		//	|                              |
		//	|   Apple I/O Configuration    |
		//	|                              |
		//	|______________________________|....0xnnn00000	[0x80011000]
		//	
		//	Map the I2S configuration registers
		mIOI2SBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)mSoundConfigSpace), kI2S_IO_CONFIGURATION_SIZE);
		FailIf ( NULL == mIOI2SBaseAddressMemory, Exit );
		mI2SBaseAddress = (void *)mIOI2SBaseAddressMemory->map()->getVirtualAddress();
		FailIf (NULL == mI2SBaseAddress, Exit);
		
		debugIOLog (3, "  mI2SInterfaceNumber         = %d", mI2SInterfaceNumber);
		debugIOLog (3, "  mIOI2SBaseAddressMemory     = %p", mIOI2SBaseAddressMemory);
		debugIOLog (3, "  mI2SBaseAddress             = %p", mI2SBaseAddress);
		debugIOLog (3, "  mIOBaseAddressMemory        = %p", mIOBaseAddressMemory);
		debugIOLog (3, "  mIOConfigurationBaseAddress = %p", mIOConfigurationBaseAddress);
	}
Exit:
	debugIOLog ( 3, "- PlatformInterfaceDBDMA_Mapped::init ( %p, %p, %d ) returns %lX", device, provider, inDBDMADeviceIndex, result );
	return result;
}
Exemplo n.º 9
0
/**
 * 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;
}
Exemplo n.º 11
0
// --------------------------------------------------------------------------
bool AudioI2SControl::init(AudioI2SInfo *theInfo) 
{    
	UInt32				tempFcr1;
	
    debugIOLog (3, "+ AudioI2SControl::init");
	
    if(!super::init())
        return(false);
		
	if ( NULL == theInfo ) { return ( false ); }		//	[3060321]	rbm	1 Oct 2002
	
    IOMemoryMap 		*map = theInfo->map ;

	switch ( theInfo->i2sSerialFormat ) {				//	[3060321]	rbm	2 Oct 2002	begin {
		case kSerialFormatSony:							//	fall through to kSerialFormatSiliLabs
		case kSerialFormat64x:							//	fall through to kSerialFormatSiliLabs
		case kSerialFormat32x:							//	fall through to kSerialFormatSiliLabs
		case kSerialFormatDAV:							//	fall through to kSerialFormatSiliLabs
		case kSerialFormatSiliLabs:
			serialFormat = theInfo->i2sSerialFormat;	//	set the format as requested
			break;
		default:
			debugIOLog (3,  "### WRONG I2S Serial Format" );
			serialFormat = kSerialFormatSony;			//	force a legal value here...
			break;
	}													//	[3060321]	rbm	1 Oct 2002	} end
	
    // cache the config space
	soundConfigSpace = (UInt8 *)map->getPhysicalAddress();

    // sets the clock base address figuring out which I2S cell we're on
    if ((((UInt32)soundConfigSpace ^ kI2S0BaseOffset) & 0x0001FFFF) == 0) 
    {
		//	[3060321]	ioBaseAddress is required by this object in order to enable the target
		//				I2S I/O Module for which this object is to service.  The I2S I/O Module
		//				enable occurs through the configuration registers which reside in the
		//				first block of ioBase.		rbm		2 Oct 2002
		ioBaseAddress = (void *)((UInt32)soundConfigSpace - kI2S0BaseOffset);
		ioBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)soundConfigSpace - kI2S0BaseOffset), 256);
        i2SInterfaceNumber = kUseI2SCell0;
    }
    else if ((((UInt32)soundConfigSpace ^ kI2S1BaseOffset) & 0x0001FFFF) == 0) 
    {
		//	[3060321]	ioBaseAddress is required by this object in order to enable the target
		//				I2S I/O Module for which this object is to service.  The I2S I/O Module
		//				enable occurs through the configuration registers which reside in the
		//				first block of ioBase.		rbm		2 Oct 2002
		ioBaseAddress = (void *)((UInt32)soundConfigSpace - kI2S1BaseOffset);
		ioBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)soundConfigSpace - kI2S1BaseOffset), 256);
        i2SInterfaceNumber = kUseI2SCell1;
    }
    else 
    {
        debugIOLog (3, "AudioI2SControl::init ERROR: unable to setup ioBaseAddress and i2SInterfaceNumber");
    }

	//
	//	There are three sections of memory mapped I/O that are directly accessed by the Apple02Audio.  These
	//	include the GPIOs, I2S DMA Channel Registers and I2S control registers.  They fall within the memory map 
	//	as follows:
	//	~                              ~
	//	|______________________________|
	//	|                              |
	//	|         I2S Control          |
	//	|______________________________|	<-	soundConfigSpace = ioBase + i2s0BaseOffset ...OR... ioBase + i2s1BaseOffset
	//	|                              |
	//	~                              ~
	//	~                              ~
	//	|______________________________|
	//	|                              |
	//	|       I2S DMA Channel        |
	//	|______________________________|	<-	i2sDMA = ioBase + i2s0_DMA ...OR... ioBase + i2s1_DMA
	//	|                              |
	//	~                              ~
	//	~                              ~
	//	|______________________________|
	//	|            FCRs              |
	//	|            GPIO              |	<-	gpio = ioBase + gpioOffsetAddress
	//	|         ExtIntGPIO           |	<-	fcr = ioBase + fcrOffsetAddress
	//	|______________________________|	<-	ioConfigurationBaseAddress
	//	|                              |
	//	~                              ~
	//
	//	The I2S DMA Channel is mapped in by the Apple02DBDMAAudioDMAEngine.  Only the I2S control registers are 
	//	mapped in by the AudioI2SControl.  The Apple I/O Configuration Space (i.e. FCRs, GPIOs and ExtIntGPIOs)
	//	are mapped in by the subclass of Apple02Audio.  The FCRs must also be mapped in by the AudioI2SControl
	//	object as the init method must enable the I2S I/O Module for which the AudioI2SControl object is
	//	being instantiated for.
	//
	
	//	Map the I2S configuration registers
	if (kUseI2SCell0 == i2SInterfaceNumber) {
		ioI2SBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)soundConfigSpace), kI2S_IO_CONFIGURATION_SIZE);
	} else {
		ioI2SBaseAddressMemory = IODeviceMemory::withRange ((IOPhysicalAddress)((UInt8 *)soundConfigSpace), kI2S_IO_CONFIGURATION_SIZE);
	}
	if (NULL != ioI2SBaseAddressMemory) {
		i2sBaseAddress = (void *)ioI2SBaseAddressMemory->map()->getVirtualAddress();
	} else {
		return false;
	}

	//	Enable the I2S interface by setting the enable bit in the feature 
	//	control register.  This one action requires knowledge of the address 
	//	of I/O configuration address space.		[3060321]	rbm		2 Oct 2002
	tempFcr1 = KLGetRegister ( kFCR1Offset );
	if ( kUseI2SCell0 == i2SInterfaceNumber ) {
		tempFcr1 &= ~( 1 << kI2S0SwReset );
		KLSetRegister ( kFCR1Offset, tempFcr1 );
		KLSetRegister ( kFCR1Offset, tempFcr1 | kI2S0InterfaceEnable );
	} else {
		tempFcr1 &= ~( 1 << kI2S1SwReset );
		KLSetRegister ( kFCR1Offset, tempFcr1 );
		KLSetRegister ( kFCR1Offset, tempFcr1 | kI2S1InterfaceEnable );
	}

    debugIOLog (3, "- AudioI2SControl::init");
    return(true);
}
Exemplo n.º 12
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;
}
Exemplo n.º 13
0
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 );
}
Exemplo n.º 14
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;
}