/** Internal Function. Allocate a pool by specified PoolIndex. @param PoolIndex Index which indicate the Pool size. @param FreePoolHdr The returned Free pool. @retval EFI_OUT_OF_RESOURCES Allocation failed. @retval EFI_SUCCESS Pool successfully allocated. **/ EFI_STATUS InternalAllocPoolByIndex ( IN UINTN PoolIndex, OUT FREE_POOL_HEADER **FreePoolHdr ) { EFI_STATUS Status; FREE_POOL_HEADER *Hdr; EFI_PHYSICAL_ADDRESS Address; ASSERT (PoolIndex <= MAX_POOL_INDEX); Status = EFI_SUCCESS; if (PoolIndex == MAX_POOL_INDEX) { Status = SmmInternalAllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } Hdr = (FREE_POOL_HEADER *) (UINTN) Address; } else if (!IsListEmpty (&mSmmPoolLists[PoolIndex])) { Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[PoolIndex]), FREE_POOL_HEADER, Link); RemoveEntryList (&Hdr->Link); } else { Status = InternalAllocPoolByIndex (PoolIndex + 1, &Hdr); if (!EFI_ERROR (Status)) { Hdr->Header.Size >>= 1; Hdr->Header.Available = TRUE; InsertHeadList (&mSmmPoolLists[PoolIndex], &Hdr->Link); Hdr = (FREE_POOL_HEADER*)((UINT8*)Hdr + Hdr->Header.Size); } }
/** Internal Function. Allocate a pool by specified PoolIndex. @param PoolType Type of pool to allocate. @param PoolIndex Index which indicate the Pool size. @param FreePoolHdr The returned Free pool. @retval EFI_OUT_OF_RESOURCES Allocation failed. @retval EFI_SUCCESS Pool successfully allocated. **/ EFI_STATUS InternalAllocPoolByIndex ( IN EFI_MEMORY_TYPE PoolType, IN UINTN PoolIndex, OUT FREE_POOL_HEADER **FreePoolHdr ) { EFI_STATUS Status; FREE_POOL_HEADER *Hdr; POOL_TAIL *Tail; EFI_PHYSICAL_ADDRESS Address; SMM_POOL_TYPE SmmPoolType; Address = 0; SmmPoolType = UefiMemoryTypeToSmmPoolType(PoolType); ASSERT (PoolIndex <= MAX_POOL_INDEX); Status = EFI_SUCCESS; Hdr = NULL; if (PoolIndex == MAX_POOL_INDEX) { Status = SmmInternalAllocatePages (AllocateAnyPages, PoolType, EFI_SIZE_TO_PAGES (MAX_POOL_SIZE << 1), &Address, FALSE); if (EFI_ERROR (Status)) { return EFI_OUT_OF_RESOURCES; } Hdr = (FREE_POOL_HEADER *) (UINTN) Address; } else if (!IsListEmpty (&mSmmPoolLists[SmmPoolType][PoolIndex])) { Hdr = BASE_CR (GetFirstNode (&mSmmPoolLists[SmmPoolType][PoolIndex]), FREE_POOL_HEADER, Link); RemoveEntryList (&Hdr->Link); } else { Status = InternalAllocPoolByIndex (PoolType, PoolIndex + 1, &Hdr); if (!EFI_ERROR (Status)) { Hdr->Header.Signature = 0; Hdr->Header.Size >>= 1; Hdr->Header.Available = TRUE; Hdr->Header.Type = 0; Tail = HEAD_TO_TAIL(&Hdr->Header); Tail->Signature = 0; Tail->Size = 0; InsertHeadList (&mSmmPoolLists[SmmPoolType][PoolIndex], &Hdr->Link); Hdr = (FREE_POOL_HEADER*)((UINT8*)Hdr + Hdr->Header.Size); } }