t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams) { t_FmPcdPrs *p_FmPcdPrs; uintptr_t baseAddr; UNUSED(p_FmPcd); UNUSED(p_FmPcdParams); p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs)); if (!p_FmPcdPrs) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED")); return NULL; } memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs)); if (p_FmPcd->guestId == NCSW_MASTER_ID) { baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm); p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr); p_FmPcdPrs->p_FmPcdPrsRegs = (t_FmPcdPrsRegs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET); } p_FmPcdPrs->fmPcdPrsPortIdStatistics = 0; p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = DEFAULT_prsMaxParseCycleLimit; p_FmPcd->exceptions |= (DEFAULT_fmPcdPrsErrorExceptions | DEFAULT_fmPcdPrsExceptions); return p_FmPcdPrs; }
t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams) { t_FmVspEntry *p_FmVspEntry = NULL; struct fm_storage_profile_params fm_vsp_params; p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry)); if (!p_FmVspEntry) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed")); return NULL; } memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry)); p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams)); if (!p_FmVspEntry->p_FmVspEntryDriverParams) { REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed")); XX_Free(p_FmVspEntry); return NULL; } memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams)); fman_vsp_defconfig(&fm_vsp_params); p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr; p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr; p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr; p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data; p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize; p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather; p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize; p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult; p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp; p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp; p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign; p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset; memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools)); p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm; p_FmVspEntry->portType = p_FmVspParams->portParams.portType; p_FmVspEntry->portId = p_FmVspParams->portParams.portId; p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId; return p_FmVspEntry; }
static t_Error InitMemDebugDatabase(t_MemorySegment *p_Mem) { p_Mem->p_MemDbg = (void *)XX_Malloc(sizeof(t_MemDbg) * p_Mem->num); if (!p_Mem->p_MemDbg) { RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory debug object")); } memset(p_Mem->p_MemDbg, ILLEGAL_BASE, sizeof(t_MemDbg) * p_Mem->num); return E_OK; }
t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools) { t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE); p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools)); if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed")); memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools)); return E_OK; }
t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size) { t_MM *p_MM; uint64_t newBase, newSize; int i; if (!size) { RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)")); } /* Initializes a new MM object */ p_MM = (t_MM *)XX_Malloc(sizeof(t_MM)); if (!p_MM) { RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); } p_MM->h_Spinlock = XX_InitSpinlock(); if (!p_MM->h_Spinlock) { XX_Free(p_MM); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!")); } /* initializes a new memory block */ if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL) RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); /* A busy list is empty */ p_MM->busyBlocks = 0; /*Initializes a new free block for each free list*/ for (i=0; i <= MM_MAX_ALIGNMENT; i++) { newBase = MAKE_ALIGNED( base, (0x1 << i) ); newSize = size - (newBase - base); if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL) RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); } *h_MM = p_MM; return (E_OK); }
/**************************************************************** * Routine: CreateFreeBlock * * Description: * Initializes a new free block of of "size" bytes and * started from "base" address. * * Arguments: * base - base address of the free block * size - size of the free block * * Return value: * A pointer to new created structure returned on success; * Otherwise, NULL. ****************************************************************/ static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size) { t_FreeBlock *p_FreeBlock; p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock)); if ( !p_FreeBlock ) { REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); return NULL; } p_FreeBlock->base = base; p_FreeBlock->end = base + size; p_FreeBlock->p_Next = 0; return p_FreeBlock; }
t_Error MEM_Init(char name[], t_Handle *p_Handle, uint32_t num, uint16_t dataSize, uint16_t prefixSize, uint16_t postfixSize, uint16_t alignment) { uint8_t *p_Memory; uint32_t allocSize; t_Error errCode; allocSize = MEM_ComputePartitionSize(num, dataSize, prefixSize, postfixSize, alignment); p_Memory = (uint8_t *)XX_Malloc(allocSize); if (!p_Memory) { RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment")); } errCode = MEM_InitByAddress(name, p_Handle, num, dataSize, prefixSize, postfixSize, alignment, p_Memory); if (errCode != E_OK) { RETURN_ERROR(MAJOR, errCode, NO_MSG); } ((t_MemorySegment *)(*p_Handle))->allocOwner = e_MEM_ALLOC_OWNER_LOCAL; return E_OK; }
/**************************************************************** * Routine: CreateBusyBlock * * Description: * Initializes a new busy block of "size" bytes and started * rom "base" address. Each busy block has a name that * specified the purpose of the memory allocation. * * Arguments: * base - base address of the busy block * size - size of the busy block * name - name that specified the busy block * * Return value: * A pointer to new created structure returned on success; * Otherwise, NULL. ****************************************************************/ static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name) { t_BusyBlock *p_BusyBlock; uint32_t n; p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock)); if ( !p_BusyBlock ) { REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG); return NULL; } p_BusyBlock->base = base; p_BusyBlock->end = base + size; n = strlen(name); if (n >= MM_MAX_NAME_LEN) n = MM_MAX_NAME_LEN - 1; strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1); p_BusyBlock->name[n] = '\0'; p_BusyBlock->p_Next = 0; return p_BusyBlock; }
t_Error MEM_InitSmart(char name[], t_Handle *p_Handle, uint32_t num, uint16_t dataSize, uint16_t prefixSize, uint16_t postfixSize, uint16_t alignment, uint8_t memPartitionId, bool consecutiveMem) { t_MemorySegment *p_Mem; uint32_t i, blockSize; uint16_t alignPad, endPad; /* prepare in case of error */ *p_Handle = NULL; /* make sure that size is always a multiple of 4 */ if (dataSize & 3) { dataSize &= ~3; dataSize += 4; } /* make sure that the alignment is at least 4 and power of 2 */ if (alignment < 4) { alignment = 4; } else if (!POWER_OF_2(alignment)) { RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Alignment (should be power of 2)")); } /* first allocate the segment descriptor */ p_Mem = (t_MemorySegment *)XX_Malloc(sizeof(t_MemorySegment)); if (!p_Mem) { RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment structure")); } /* allocate the blocks stack */ p_Mem->p_BlocksStack = (uint8_t **)XX_Malloc(num * sizeof(uint8_t*)); if (!p_Mem->p_BlocksStack) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment block pointers stack")); } /* allocate the blocks bases array */ p_Mem->p_Bases = (uint8_t **)XX_Malloc((consecutiveMem ? 1 : num) * sizeof(uint8_t*)); if (!p_Mem->p_Bases) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment base pointers array")); } memset(p_Mem->p_Bases, 0, (consecutiveMem ? 1 : num) * sizeof(uint8_t*)); /* store info about this segment */ p_Mem->num = num; p_Mem->current = 0; p_Mem->dataSize = dataSize; p_Mem->getFailures = 0; p_Mem->allocOwner = e_MEM_ALLOC_OWNER_LOCAL_SMART; p_Mem->consecutiveMem = consecutiveMem; p_Mem->prefixSize = prefixSize; p_Mem->postfixSize = postfixSize; p_Mem->alignment = alignment; p_Mem->h_Spinlock = XX_InitSpinlock(); if (!p_Mem->h_Spinlock) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't create spinlock!")); } alignPad = (uint16_t)PAD_ALIGNMENT(4, prefixSize); /* Make sure the entire size is a multiple of alignment */ endPad = (uint16_t)PAD_ALIGNMENT(alignment, alignPad + prefixSize + dataSize + postfixSize); /* Calculate blockSize */ blockSize = (uint32_t)(alignPad + prefixSize + dataSize + postfixSize + endPad); /* Now allocate the blocks */ if (p_Mem->consecutiveMem) { /* |alignment - 1| bytes at most will be discarded in the beginning of the received segment for alignment reasons, therefore the allocation is of: (alignment + (num * block size)). */ uint8_t *p_Blocks = (uint8_t *) XX_MallocSmart((uint32_t)((num * blockSize) + alignment), memPartitionId, 1); if (!p_Blocks) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment blocks")); } /* Store the memory segment address */ p_Mem->p_Bases[0] = p_Blocks; /* The following manipulation places the data of block[0] in an aligned address, since block size is aligned the following block datas will all be aligned.*/ ALIGN_BLOCK(p_Blocks, prefixSize, alignment); /* initialize the blocks */ for (i = 0; i < num; i++) { p_Mem->p_BlocksStack[i] = p_Blocks; p_Blocks += blockSize; } #ifdef DEBUG_MEM_LEAKS p_Mem->blockOffset = (uint32_t)(p_Mem->p_BlocksStack[0] - p_Mem->p_Bases[0]); p_Mem->blockSize = blockSize; #endif /* DEBUG_MEM_LEAKS */ } else { /* |alignment - 1| bytes at most will be discarded in the beginning of the received segment for alignment reasons, therefore the allocation is of: (alignment + block size). */ for (i = 0; i < num; i++) { uint8_t *p_Block = (uint8_t *) XX_MallocSmart((uint32_t)(blockSize + alignment), memPartitionId, 1); if (!p_Block) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment blocks")); } /* Store the memory segment address */ p_Mem->p_Bases[i] = p_Block; /* The following places the data of each block in an aligned address */ ALIGN_BLOCK(p_Block, prefixSize, alignment); #ifdef DEBUG_MEM_LEAKS /* Need 4 bytes before the meaningful bytes to store the block index. We know we have them because alignment is at least 4 bytes. */ if (p_Block == p_Mem->p_Bases[i]) p_Block += alignment; *(uint32_t *)(p_Block - 4) = i; #endif /* DEBUG_MEM_LEAKS */ p_Mem->p_BlocksStack[i] = p_Block; } } /* store name */ strncpy(p_Mem->name, name, MEM_MAX_NAME_LENGTH-1); /* return handle to caller */ *p_Handle = (t_Handle)p_Mem; #ifdef DEBUG_MEM_LEAKS { t_Error errCode = InitMemDebugDatabase(p_Mem); if (errCode != E_OK) RETURN_ERROR(MAJOR, errCode, NO_MSG); } #endif /* DEBUG_MEM_LEAKS */ return E_OK; }
t_Error MEM_InitByAddress(char name[], t_Handle *p_Handle, uint32_t num, uint16_t dataSize, uint16_t prefixSize, uint16_t postfixSize, uint16_t alignment, uint8_t *p_Memory) { t_MemorySegment *p_Mem; uint32_t i, blockSize; uint16_t alignPad, endPad; uint8_t *p_Blocks; /* prepare in case of error */ *p_Handle = NULL; if (!p_Memory) { RETURN_ERROR(MAJOR, E_NULL_POINTER, ("Memory blocks")); } p_Blocks = p_Memory; /* make sure that the alignment is at least 4 and power of 2 */ if (alignment < 4) { alignment = 4; } else if (!POWER_OF_2(alignment)) { RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Alignment (should be power of 2)")); } /* first allocate the segment descriptor */ p_Mem = (t_MemorySegment *)XX_Malloc(sizeof(t_MemorySegment)); if (!p_Mem) { RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment structure")); } /* allocate the blocks stack */ p_Mem->p_BlocksStack = (uint8_t **)XX_Malloc(num * sizeof(uint8_t*)); if (!p_Mem->p_BlocksStack) { XX_Free(p_Mem); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment block pointers stack")); } /* allocate the blocks bases array */ p_Mem->p_Bases = (uint8_t **)XX_Malloc(sizeof(uint8_t*)); if (!p_Mem->p_Bases) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory segment base pointers array")); } memset(p_Mem->p_Bases, 0, sizeof(uint8_t*)); /* store info about this segment */ p_Mem->num = num; p_Mem->current = 0; p_Mem->dataSize = dataSize; p_Mem->p_Bases[0] = p_Blocks; p_Mem->getFailures = 0; p_Mem->allocOwner = e_MEM_ALLOC_OWNER_EXTERNAL; p_Mem->consecutiveMem = TRUE; p_Mem->prefixSize = prefixSize; p_Mem->postfixSize = postfixSize; p_Mem->alignment = alignment; /* store name */ strncpy(p_Mem->name, name, MEM_MAX_NAME_LENGTH-1); p_Mem->h_Spinlock = XX_InitSpinlock(); if (!p_Mem->h_Spinlock) { MEM_Free(p_Mem); RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't create spinlock!")); } alignPad = (uint16_t)PAD_ALIGNMENT(4, prefixSize); /* Make sure the entire size is a multiple of alignment */ endPad = (uint16_t)PAD_ALIGNMENT(alignment, (alignPad + prefixSize + dataSize + postfixSize)); /* The following manipulation places the data of block[0] in an aligned address, since block size is aligned the following block datas will all be aligned */ ALIGN_BLOCK(p_Blocks, prefixSize, alignment); blockSize = (uint32_t)(alignPad + prefixSize + dataSize + postfixSize + endPad); /* initialize the blocks */ for (i=0; i < num; i++) { p_Mem->p_BlocksStack[i] = p_Blocks; p_Blocks += blockSize; } /* return handle to caller */ *p_Handle = (t_Handle)p_Mem; #ifdef DEBUG_MEM_LEAKS { t_Error errCode = InitMemDebugDatabase(p_Mem); if (errCode != E_OK) RETURN_ERROR(MAJOR, errCode, NO_MSG); p_Mem->blockOffset = (uint32_t)(p_Mem->p_BlocksStack[0] - p_Mem->p_Bases[0]); p_Mem->blockSize = blockSize; } #endif /* DEBUG_MEM_LEAKS */ return E_OK; }
t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion) { t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp; SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE); SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE); p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion)); if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion) RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed")); memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion)); return E_OK; }