Beispiel #1
0
void FAT_SectorCache::Uninitialize()
{
    FAT_CacheLine* cacheLine;
    for(int i = 0; i < SECTORCACHE_MAXSIZE; i++)
    {
        cacheLine = &m_cacheLines[i];
        
        if(cacheLine->m_buffer)
        {
            FlushSector( cacheLine );

            private_free( cacheLine->m_buffer );

            cacheLine->m_buffer = NULL;
        }
    }
}
BYTE* FAT_SectorCache::GetSector( UINT32 sectorIndex, BOOL forWrite )
{
    if(sectorIndex > m_sectorCount)  //sectorIndex out of range of this device
        return NULL;

    FAT_CacheLine* cacheLine = GetCacheLine( sectorIndex );

    if(!cacheLine)
    {
        cacheLine = GetUnusedCacheLine();

        if(!cacheLine->m_buffer)
        {
            cacheLine->m_buffer = (BYTE*)private_malloc( SECTORCACHE_LINESIZE );

            if(!cacheLine->m_buffer) return NULL;
        }

        cacheLine->m_begin         = sectorIndex - (sectorIndex % m_sectorsPerLine);
        cacheLine->m_bsByteAddress = m_baseByteAddress + cacheLine->m_begin * m_bytesPerSector;
        cacheLine->m_flags         = 0;

        if(!m_blockStorageDevice->Read( cacheLine->m_bsByteAddress, SECTORCACHE_LINESIZE, cacheLine->m_buffer ))
        {
            private_free( cacheLine->m_buffer );
            
            cacheLine->m_buffer = NULL;
            
            return NULL;
        }
    }

    if(forWrite) cacheLine->SetDirty( TRUE );

    if((cacheLine->GetLRUCounter()) != m_LRUCounter)
    {
        m_LRUCounter++;

        cacheLine->SetLRUCOunter( m_LRUCounter );
    }

    return cacheLine->m_buffer + (sectorIndex - cacheLine->m_begin) * m_bytesPerSector;
}
void PolyphonicPiezo_Driver::ToneRelease( void* Param )
{
    ASSERT_IRQ_MUST_BE_ON();

    GLOBAL_LOCK(irq);

    while(true)
    {
        PIEZO_POLY_TONE* Tone = g_PolyphonicPiezo_Driver.m_ToneToRelease.ExtractFirstNode(); if(!Tone) break;

        //
        // Re-enable interrupts when releasing memory.
        //
        irq.Release();

        private_free( Tone );

        irq.Acquire();
    }

    g_PolyphonicPiezo_Driver.m_ToneRelease.Abort();
}
Beispiel #4
0
static void snd_ali_free_voice(struct snd_ali * codec,
			       struct snd_ali_voice *pvoice)
{
	void (*private_free)(void *);
	void *private_data;

	dev_dbg(codec->card->dev, "free_voice: channel=%d\n", pvoice->number);
	if (!pvoice->use)
		return;
	snd_ali_clear_voices(codec, pvoice->number, pvoice->number);
	spin_lock_irq(&codec->voice_alloc);
	private_free = pvoice->private_free;
	private_data = pvoice->private_data;
	pvoice->private_free = NULL;
	pvoice->private_data = NULL;
	if (pvoice->pcm)
		snd_ali_free_channel_pcm(codec, pvoice->number);
	pvoice->use = pvoice->pcm = pvoice->synth = 0;
	pvoice->substream = NULL;
	spin_unlock_irq(&codec->voice_alloc);
	if (private_free)
		private_free(private_data);
}
bool CryptoState::VerifySignature( UINT32 keyIndex )
{   
    RSAKey* key = NULL;

    // global config pointer not in bootloader image

    //---------------------------------------------
    // IF THERE IS NO CONFIG SECTOR IN THE FLASH SECTOR TABLE, THEN WE DON'T HAVE KEYS, 
    // THEREFORE WE WILL NOT PERFORM SIGNATURE CHECKING.
    // 
    if(g_PrimaryConfigManager.m_device == NULL) return true;


    switch(m_sectorType)
    {
    case BlockRange::BLOCKTYPE_DEPLOYMENT:
        // backwards compatibility
        if(g_PrimaryConfigManager.GetTinyBooterVersion() != ConfigurationSector::c_CurrentVersionTinyBooter) return true;

        // if there is no key then we do not need to check the signature for the deployment sectors ONLY
        if(g_PrimaryConfigManager.CheckSignatureKeyEmpty( ConfigurationSector::c_DeployKeyDeployment ))
        {
            return true;
        }

        key = (RSAKey*)g_PrimaryConfigManager.GetDeploymentKeys( ConfigurationSector::c_DeployKeyDeployment );
        
        break;

        // We have to be carefull of how we update the config sector as it contains the signature keys for firmware updates.
        // Unlike all other updates, the config data is written into RAM in the buffer g_ConfigBuffer.  THis is necessary because
        // we don't want to blow away the keys unless we know that the signature is OK.
        //
        // Also, if the keys are unchanged then we don't require signature verification.  Besides the keys there is not really anything
        // we need to protect in this sector.
    case BlockRange::BLOCKTYPE_CONFIG:
        {
            ASSERT(g_ConfigBufferLength > 0);
            ASSERT(g_ConfigBuffer != NULL);

            if(g_ConfigBuffer == NULL || g_ConfigBufferLength <= 0) return false;

            // the g_ConfigBuffer contains the new configuration data
            const ConfigurationSector* pNewCfg    = (const ConfigurationSector*)g_ConfigBuffer;

            bool fCanWrite = false;
            bool fRet      = false;

            if(pNewCfg->Version.TinyBooter == ConfigurationSector::c_CurrentVersionTinyBooter)
            {
                // allow updates of old config - for backwards compatibility
                if(g_PrimaryConfigManager.GetTinyBooterVersion() != ConfigurationSector::c_CurrentVersionTinyBooter)
                {
                    fCanWrite = true;
                }
                else
                {
                    bool key1Change = (!g_PrimaryConfigManager.VerifiySignatureKey(0, (BYTE *)&pNewCfg->DeploymentKeys[0]));
                    bool key2Change = (!g_PrimaryConfigManager.VerifiySignatureKey(1, (BYTE *)&pNewCfg->DeploymentKeys[1]));
                    bool key1Empty  =   g_PrimaryConfigManager.CheckSignatureKeyEmpty(0);
                    bool key2Empty  =   g_PrimaryConfigManager.CheckSignatureKeyEmpty(1);
                    

                    // make sure there are no key changes (unelss the key was uninitialized)    
                    if((key1Empty || !key1Change) &&
                       (key2Empty || !key2Change))
                    {
                        fCanWrite = true;
                    }
                }   

                if(fCanWrite)
                {                
                    // write the configuration
                    g_PrimaryConfigManager.EraseWriteConfigBlock( (BYTE *) g_ConfigBuffer, g_ConfigBufferLength );
                    fRet = true;
                }
            }

            // free RAM buffer
            private_free(g_ConfigBuffer);
            g_ConfigBuffer = NULL;

            return fRet;
            
        }
        break;

    default:
        // backwards compatibility


        if(g_PrimaryConfigManager.GetTinyBooterVersion() != ConfigurationSector::c_CurrentVersionTinyBooter) return true;

        // if there is no key then we do not need to check the signature for the deployment sectors ONLY
        if (g_PrimaryConfigManager.CheckSignatureKeyEmpty( keyIndex ))
        {
            return true;
        }

        key = (RSAKey*)g_PrimaryConfigManager.GetDeploymentKeys( keyIndex );

        break;
            
    };

    if(key == NULL)
    {
        return false; 
    }

    m_res = ::Crypto_StartRSAOperationWithKey( RSA_VERIFYSIGNATURE, key, (BYTE*)m_dataAddress, m_dataLength, (BYTE*)m_sig, m_sigLength, &m_handle );

    
    while(CRYPTO_CONTINUE == m_res)
    {
        m_res = ::Crypto_StepRSAOperation( &m_handle );
    }
    
    return m_res == CRYPTO_SUCCESS;
}
BOOL SF_BS_Driver::Write(void *context, ByteAddress Address, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite )
{
    NATIVE_PROFILE_PAL_FLASH();

    BYTE * pData;
    BYTE * pBuf = NULL;
    MEMORY_MAPPED_SERIAL_BLOCK_CONFIG* config = (MEMORY_MAPPED_SERIAL_BLOCK_CONFIG*)context;
    const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation;
    
    UINT32 region, range;

    if(ReadModifyWrite) 
    {
        BOOL fRet = TRUE;
        
        if(!deviceInfo->FindRegionFromAddress(Address, region, range)) return FALSE;

        UINT32      bytesPerBlock   = deviceInfo->Regions[region].BytesPerBlock;
        UINT32      regionEnd       = deviceInfo->Regions[region].Start + deviceInfo->Regions[region].Size();
        UINT32      offset          = Address % bytesPerBlock;
        ByteAddress addr            = Address;
        ByteAddress addrEnd         = Address + NumBytes;
        UINT32      index           = 0;

        pBuf = (BYTE*)private_malloc(bytesPerBlock);

        if(pBuf == NULL)
        {
 
            return FALSE;
        }

        while(fRet && addr < addrEnd)
        {
            ByteAddress sectAddr = (addr - offset);
             
            if(offset == 0 && NumBytes >= bytesPerBlock)
            {
                pData = &pSectorBuff[index];
            }
            else
            {
                int bytes = __min(bytesPerBlock - offset, NumBytes); 
                
                //memcpy( &pBuf[0]     , (void*)sectAddr    , bytesPerBlock );
                Read(context, sectAddr, bytesPerBlock, (BYTE *)&pBuf[0]);
                memcpy( &pBuf[offset], &pSectorBuff[index], bytes         );

                pData = pBuf;
            }

            if(!EraseBlock( context, sectAddr ))
{
                fRet = FALSE;
                break;
            }

            fRet = WriteX(context, sectAddr, bytesPerBlock, pData, ReadModifyWrite, TRUE);

            NumBytes -= bytesPerBlock - offset;
            addr     += bytesPerBlock - offset;
            index    += bytesPerBlock - offset;
            offset    = 0;

            if(NumBytes > 0 && addr >= regionEnd)
            {
                region++;

                if(region >= deviceInfo->NumRegions)
                {
                    fRet = FALSE;
                }
                else
                {
                    regionEnd       = deviceInfo->Regions[region].Start + deviceInfo->Regions[region].Size();
                    bytesPerBlock   = deviceInfo->Regions[region].BytesPerBlock;

                    private_free(pBuf);

                    pBuf = (BYTE*)private_malloc(bytesPerBlock);

                    if(pBuf == NULL)
                    {
                        fRet = FALSE;
                    }
                }
            }
                
        }

        if(pBuf != NULL)
        {
            private_free(pBuf);
        }

        return fRet;            
    }
    else
    {
        return WriteX(context, Address, NumBytes, pSectorBuff, ReadModifyWrite, TRUE);
    }
}
BOOL HAL_CONFIG_BLOCK::ApplyConfig( const char* Name, void* Address, size_t Length, void** newAlloc )
{
#if defined(HAL_REDUCESIZE)
    // No config update.
    return FALSE;
#else
    BYTE* pXipConfigBuf = NULL;
    HAL_CONFIG_BLOCK_STORAGE_DATA blData;
    const HAL_CONFIG_BLOCK *header = NULL;

    if(!GetConfigSectorAddress(blData)) return FALSE;

    if(g_ConfigurationSector.ConfigurationLength == 0xFFFFFFFF) return FALSE;

    if(blData.isXIP)
    {
        header = (const HAL_CONFIG_BLOCK*)(blData.ConfigAddress + g_ConfigurationSector.ConfigurationLength);
    }
    else
    {
        pXipConfigBuf = (BYTE*)private_malloc(blData.BlockLength);

        if(pXipConfigBuf != NULL)

        {
            blData.Device->Read( blData.ConfigAddress, blData.BlockLength, pXipConfigBuf );

            header = (const HAL_CONFIG_BLOCK*)&pXipConfigBuf[g_ConfigurationSector.ConfigurationLength];
        }
    }

    if(header != NULL)
    {
        header = header->Find(Name, FALSE, FALSE);
    }

    if(header)
    {
        if(newAlloc != NULL)
        {
            *newAlloc = private_malloc(header->Size);

            if(*newAlloc)
            {
                memcpy( *newAlloc, header->Data(), header->Size );

                return TRUE;
            }
        }
        else if(header->Size == Length)
        {
            if(Address)
            {
                memcpy( Address, header->Data(), Length );
            }

            return TRUE;
        }
    }

    if(pXipConfigBuf != NULL)
    {
        private_free(pXipConfigBuf);
    }

    return FALSE;
#endif
}
BOOL HAL_CONFIG_BLOCK::UpdateBlockWithName( const char* Name, void* Data, size_t Length, BOOL isChipRO )
{
#if defined(HAL_REDUCESIZE)
    return FALSE;
#else

    if(Name == NULL) return FALSE;

    BOOL fRet = FALSE;
    BYTE* pXipConfigBuf = NULL;
    const HAL_CONFIG_BLOCK *pLastConfig = NULL;
    HAL_CONFIG_BLOCK_STORAGE_DATA blData;

    if(!GetConfigSectorAddress(blData)) return FALSE;

    if(g_ConfigurationSector.ConfigurationLength == 0xFFFFFFFF)
    {
        return FALSE;
    }

    const ConfigurationSector* pStaticCfg = NULL;

    const HAL_CONFIG_BLOCK *pConfig = NULL;

    GLOBAL_LOCK(irq);

    if(blData.isXIP)
    {
        pConfig = (const HAL_CONFIG_BLOCK*)(blData.ConfigAddress+ g_ConfigurationSector.ConfigurationLength);
        pStaticCfg = &g_ConfigurationSector;
    }
    else
    {
        pXipConfigBuf = (BYTE*)private_malloc(blData.BlockLength);

        if(pXipConfigBuf != NULL)
        {
            blData.Device->Read( blData.ConfigAddress, blData.BlockLength, pXipConfigBuf );

            pConfig = (const HAL_CONFIG_BLOCK*)&pXipConfigBuf[g_ConfigurationSector.ConfigurationLength];

            pStaticCfg = (const ConfigurationSector*)pXipConfigBuf;
        }
        else
        {
            return FALSE;
        }
    }

    if(pConfig != NULL)
    {
        pConfig = pConfig->Find(Name, FALSE, TRUE);

        pLastConfig = pConfig->Find("", FALSE, TRUE);
    }

    if(pConfig != NULL)
    {
        const void* physAddr;
        const void* physEnd;

        // try compacting the config block if the first attempt to update fails
        for(int i=0; i<2; i++)
        {
            // if we could not get the last config then we must be full
            if(pLastConfig != NULL)
            {
                if(blData.isXIP)
                {
                    physAddr = (const void*)pConfig;
                    physEnd  = (const void*)pLastConfig;
                }
                else
                {
                    physAddr = (const void*)(blData.ConfigAddress + ((size_t)pConfig - (size_t)pXipConfigBuf));
                    physEnd  = (const void*)(blData.ConfigAddress + ((size_t)pLastConfig - (size_t)pXipConfigBuf));

                    private_free(pXipConfigBuf);
                    pXipConfigBuf = NULL;
                }

                if(Data != NULL)
                {
                    HAL_CONFIG_BLOCK header;

                    header.Prepare( Name, Data, Length );

                    fRet = UpdateBlock( blData, physAddr, (const HAL_CONFIG_BLOCK*)&header, Data, Length, physEnd, isChipRO );
                }
                else if(physAddr != physEnd)
                {
                    fRet = UpdateBlock( blData, physAddr, NULL, NULL, 0, physEnd, isChipRO );
                }
                else
                {
                    fRet = TRUE;
                }

                if(fRet) break;
            }
        
            CompactBlock( blData, pStaticCfg, pLastConfig );

            if(!blData.isXIP && pXipConfigBuf != NULL)
            {
                blData.Device->Read( blData.ConfigAddress, blData.BlockLength, pXipConfigBuf );
            
                pConfig = (const HAL_CONFIG_BLOCK*)&pXipConfigBuf[g_ConfigurationSector.ConfigurationLength];
            }
            else
            {
                pConfig = (const HAL_CONFIG_BLOCK*)(blData.ConfigAddress + g_ConfigurationSector.ConfigurationLength);
            }

            pConfig = pConfig->Find(Name, FALSE, TRUE);

            pLastConfig = pConfig->Find("", FALSE, TRUE);            
        }
    }


    if(pXipConfigBuf != NULL)
    {
        private_free(pXipConfigBuf);
    }

    return fRet;
#endif
}
void FS_MountVolume( LPCSTR nameSpace, UINT32 serialNumber, UINT32 deviceFlags, BlockStorageDevice* blockStorageDevice )
{
    FileSystemVolume* volume = NULL;
    UINT32 numVolumes = 0;
    FILESYSTEM_DRIVER_INTERFACE* fsDriver = NULL;
    STREAM_DRIVER_INTERFACE* streamDriver = NULL;
    UINT32 i;
    
    if(!nameSpace || !blockStorageDevice)
    {
        return;
    }

    //--//

    // free up any memory taken up by this block storage device in the zombie list
    // so at any given time, we'll only have one set of FileSystemVolume per block 
    // storage device. Here we release (private_free) the memory that was allocated
    // in the previous insertion, later, prior to AddVolume, we'll allocate new memory
    // needed for this insertion.
    FileSystemVolume* current = FileSystemVolumeList::s_zombieVolumeList.FirstValidNode();
    FileSystemVolume* next;
    
    while(current)
    {
        next = current->Next();

        if(!(next && next->Next()))
        {    
            next = NULL;
        }

        // We'll only free the memory of this storage device
        if(current->m_volumeId.blockStorageDevice == blockStorageDevice)
        {
            current->Unlink();

            private_free( current );
        }

        current = next;
    }

    //--//

    /// First we find the FSDriver that will mount the block storage
    for (i = 0; i < g_InstalledFSCount; i++)
    {
        if (g_AvailableFSInterfaces[i].fsDriver && g_AvailableFSInterfaces[i].fsDriver->IsLoadableMedia &&
            g_AvailableFSInterfaces[i].fsDriver->IsLoadableMedia( blockStorageDevice, &numVolumes ))
        {
            fsDriver = g_AvailableFSInterfaces[i].fsDriver;
            streamDriver = g_AvailableFSInterfaces[i].streamDriver;
            break;
        }
    }

    if (!fsDriver)
    {
        numVolumes = 1;
    }

    for (i = 0; i < numVolumes; i++)
    {
        // Allocate the memory for this FileSystemVolume
        volume = (FileSystemVolume*)private_malloc( sizeof(FileSystemVolume) );

        if(!volume) // allocation failed
        {
            return;
        }

        // initialize content to 0
        memset( volume, 0, sizeof(FileSystemVolume) );

        if(!FileSystemVolumeList::AddVolume( volume, nameSpace, serialNumber, deviceFlags,
                                            streamDriver, fsDriver, blockStorageDevice, i, (fsDriver) ? TRUE : FALSE )) // init only when we have a valid fsDriver
        {
            // If for some reason, AddVolume fails, we'll keep trying other volumes
            private_free( volume );
            continue;
        }

        // Now we can notify managed code
        PostManagedEvent( EVENT_STORAGE, EVENT_SUBCATEGORY_MEDIAINSERT, 0, (UINT32)volume );
    }
}
BOOL MicroBooterUpdateProvider::InstallUpdate( MFUpdate* pUpdate, UINT8* pValidation, INT32 validationLen )
{
    if(pUpdate->Providers->Storage == NULL) return FALSE;

    if(!pUpdate->IsValidated()) return FALSE;

    switch(pUpdate->Header.UpdateType)
    {
        case MFUPDATE_UPDATETYPE_FIRMWARE:
            {
                HAL_UPDATE_CONFIG cfg;

                if(sizeof(cfg.UpdateSignature) < validationLen) return FALSE;
                
                cfg.Header.Enable = TRUE;
                cfg.UpdateID = pUpdate->Header.UpdateID;

                if(validationLen == sizeof(UINT32))
                {
                    cfg.UpdateSignType = HAL_UPDATE_CONFIG_SIGN_TYPE__CRC;
                }
                else
                {
                    cfg.UpdateSignType = HAL_UPDATE_CONFIG_SIGN_TYPE__SIGNATURE;
                }
                
                memcpy( cfg.UpdateSignature, pValidation, validationLen );

                if(HAL_CONFIG_BLOCK::UpdateBlockWithName(cfg.GetDriverName(), &cfg, sizeof(cfg), FALSE))
                {
                    CPU_Reset();
                }
            }
            break;
            
        case MFUPDATE_UPDATETYPE_ASSEMBLY:
            {
                BlockStorageStream stream;
                
                if(NULL == BlockStorageList::GetFirstDevice())
                {
                    BlockStorageList::Initialize();
                
                    BlockStorage_AddDevices();
                
                    BlockStorageList::InitializeDevices();
                }

                if(stream.Initialize(BlockUsage::DEPLOYMENT))
                {
                    if(pUpdate->Header.UpdateSubType == MFUPDATE_UPDATESUBTYPE_ASSEMBLY_REPLACE_DEPLOY)
                    {
                        do
                        {
                            stream.Erase(stream.Length);
                        }
                        while(stream.NextStream());

                        stream.Initialize(BlockUsage::DEPLOYMENT);
                    }
                    
                    do
                    {
                        UINT8 buf[512];
                        INT32 offset = 0;
                        INT32 len = sizeof(buf);
                        const BlockDeviceInfo* deviceInfo = stream.Device->GetDeviceInfo();
                        BOOL isXIP = deviceInfo->Attribute.SupportsXIP;
                        
                        const CLR_RECORD_ASSEMBLY* header;
                        INT32  headerInBytes = sizeof(CLR_RECORD_ASSEMBLY);
                        BYTE * headerBuffer  = NULL;
                        
                        if(!isXIP)
                        {
                            headerBuffer = (BYTE*)private_malloc( headerInBytes );  if(!headerBuffer) return FALSE;
                            memset( headerBuffer, 0,  headerInBytes );
                        }
                        
                        while(TRUE)
                        {
                            if(!stream.Read( &headerBuffer, headerInBytes )) break;
                        
                            header = (const CLR_RECORD_ASSEMBLY*)headerBuffer;
                        
                            // check header first before read
                            if(!header->GoodHeader())
                            {
                                stream.Seek(-headerInBytes);
                                
                                if(stream.IsErased(pUpdate->Header.UpdateSize))
                                {
                                    while(offset < pUpdate->Header.UpdateSize)
                                    {
                                        if((pUpdate->Header.UpdateSize - offset) < len)
                                        {
                                            len = pUpdate->Header.UpdateSize - offset;
                                        }
                                        
                                        offset += pUpdate->Providers->Storage->Read(pUpdate->StorageHandle, offset, buf, len);

                                        stream.Write(buf, len);
                                    }

                                    ClrReboot();
                                    return TRUE;
                                }
                                break;
                            }
                        
                            UINT32 AssemblySizeInByte = ROUNDTOMULTIPLE(header->TotalSize(), CLR_UINT32);
                        
                            stream.Seek( AssemblySizeInByte );
                        }
                        if(!isXIP) private_free( headerBuffer );
                    
                    }
                    while(stream.NextStream());
                }

            }
            break;
    }
    
    return FALSE;
}