ehcimem.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 775 行 · 第 1/2 页
C
775 行
// reset associated bits in bit arry
//
for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / MEM_UNIT_SIZE); Count++) {
ASSERT ((TempHeaderPtr->BitArrayPtr[Index] & bit (Index2) )== bit (Index2));
TempHeaderPtr->BitArrayPtr[Index] ^= (UINT8) (bit (Index2));
Index2++;
if (Index2 == 8) {
Index += 1;
Index2 = 0;
}
}
//
// break the loop
//
break;
}
}
//
// Release emptied memory blocks (only if the memory block is not
// the first one in the memory header list
//
for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {
ASSERT (MemoryHeader->Next != NULL);
if (IsMemoryBlockEmptied (TempHeaderPtr)) {
DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);
//
// when the TempHeaderPtr is freed in FreeMemoryHeader(),
// the TempHeaderPtr is pointing to nonsense content.
//
gBS->RestoreTPL (OldTpl);
FreeMemoryHeader (HcDev, TempHeaderPtr);
OldTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY + 1);
//
// reset the TempHeaderPtr, continue search for
// another empty memory block.
//
TempHeaderPtr = MemoryHeader->Next;
continue;
}
TempHeaderPtr = TempHeaderPtr->Next;
}
gBS->RestoreTPL (OldTpl);
}
VOID
InsertMemoryHeaderToList (
IN MEMORY_MANAGE_HEADER *MemoryHeader,
IN MEMORY_MANAGE_HEADER *NewMemoryHeader
)
/*++
Routine Description:
Insert Memory Header To List
Arguments:
MemoryHeader - MEMORY_MANAGE_HEADER
NewMemoryHeader - MEMORY_MANAGE_HEADER
Returns:
VOID
--*/
{
MEMORY_MANAGE_HEADER *TempHeaderPtr;
for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
if (TempHeaderPtr->Next == NULL) {
TempHeaderPtr->Next = NewMemoryHeader;
break;
}
}
}
EFI_STATUS
AllocMemInMemoryBlock (
IN MEMORY_MANAGE_HEADER *MemoryHeader,
OUT VOID **Pool,
IN UINTN NumberOfMemoryUnit
)
/*++
Routine Description:
Alloc Memory In MemoryBlock
Arguments:
MemoryHeader - MEMORY_MANAGE_HEADER
Pool - Place to store pointer to memory
NumberOfMemoryUnit - Number Of Memory Unit
Returns:
EFI_SUCCESS Success
EFI_NOT_FOUND Can't find the free memory
--*/
{
UINTN TempBytePos;
UINTN FoundBytePos;
UINT8 Index;
UINT8 FoundBitPos;
UINT8 ByteValue;
UINT8 BitValue;
UINTN NumberOfZeros;
UINTN Count;
FoundBytePos = 0;
FoundBitPos = 0;
ByteValue = MemoryHeader->BitArrayPtr[0];
NumberOfZeros = 0;
Index = 0;
for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {
//
// Pop out BitValue from a byte in TempBytePos.
//
BitValue = (UINT8) (ByteValue & 0x1);
//
// right shift the byte
//
ByteValue = ByteValue >> 1;
if (BitValue == 0) {
//
// Found a free bit, the NumberOfZeros only record the number
// of those consecutive zeros
//
NumberOfZeros++;
//
// Found enough consecutive free space, break the loop
//
if (NumberOfZeros >= NumberOfMemoryUnit) {
break;
}
} else {
//
// Encountering a '1', meant the bit is ocupied.
//
if (NumberOfZeros >= NumberOfMemoryUnit) {
//
// Found enough consecutive free space,break the loop
//
break;
} else {
//
// the NumberOfZeros only record the number of those consecutive zeros,
// so reset the NumberOfZeros to 0 when encountering '1' before finding
// enough consecutive '0's
//
NumberOfZeros = 0;
//
// reset the (FoundBytePos,FoundBitPos) to the position of '1'
//
FoundBytePos = TempBytePos;
FoundBitPos = Index;
}
}
//
// step forward a bit
//
Index++;
if (Index == 8) {
//
// step forward a byte, getting the byte value,
// and reset the bit pos.
//
TempBytePos += 1;
ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];
Index = 0;
}
}
if (NumberOfZeros < NumberOfMemoryUnit) {
return EFI_NOT_FOUND;
}
//
// Found enough free space.
//
//
// The values recorded in (FoundBytePos,FoundBitPos) have two conditions:
// 1)(FoundBytePos,FoundBitPos) record the position
// of the last '1' before the consecutive '0's, it must
// be adjusted to the start position of the consecutive '0's.
// 2)the start address of the consecutive '0's is just the start of
// the bitarray. so no need to adjust the values of
// (FoundBytePos,FoundBitPos).
//
if ((MemoryHeader->BitArrayPtr[FoundBytePos] & bit (FoundBitPos)) != 0) {
FoundBitPos += 1;
}
//
// Have the (FoundBytePos,FoundBitPos) make sense.
//
if (FoundBitPos > 7) {
FoundBytePos += 1;
FoundBitPos -= 8;
}
//
// Set the memory as allocated
//
for (TempBytePos = FoundBytePos, Index = FoundBitPos, Count = 0; Count < NumberOfMemoryUnit; Count++) {
ASSERT ((MemoryHeader->BitArrayPtr[TempBytePos] & bit (Index) )== 0);
MemoryHeader->BitArrayPtr[TempBytePos] |= bit (Index);
Index++;
if (Index == 8) {
TempBytePos += 1;
Index = 0;
}
}
*Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * MEM_UNIT_SIZE;
return EFI_SUCCESS;
}
BOOLEAN
IsMemoryBlockEmptied (
IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr
)
/*++
Routine Description:
Is Memory Block Emptied
Arguments:
MemoryHeaderPtr - MEMORY_MANAGE_HEADER
Returns:
TRUE Empty
FALSE Not Empty
--*/
{
UINTN Index;
for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {
if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {
return FALSE;
}
}
return TRUE;
}
VOID
DelinkMemoryBlock (
IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,
IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader
)
/*++
Routine Description:
Delink Memory Block
Arguments:
FirstMemoryHeader - MEMORY_MANAGE_HEADER
NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER
Returns:
VOID
--*/
{
MEMORY_MANAGE_HEADER *TempHeaderPtr;
if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {
return ;
}
for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL; TempHeaderPtr = TempHeaderPtr->Next) {
if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {
//
// Link the before and after
//
TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
NeedFreeMemoryHeader->Next = NULL;
break;
}
}
}
EFI_STATUS
InitialMemoryManagement (
IN USB2_HC_DEV *HcDev
)
/*++
Routine Description:
Initialize Memory Management
Arguments:
HcDev - USB2_HC_DEV
Returns:
EFI_SUCCESS Success
EFI_DEVICE_ERROR Fail
--*/
{
EFI_STATUS Status;
MEMORY_MANAGE_HEADER *MemoryHeader;
UINTN MemPages;
MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto exit;
}
HcDev->MemoryHeader = MemoryHeader;
exit:
return Status;
}
EFI_STATUS
DeinitialMemoryManagement (
IN USB2_HC_DEV *HcDev
)
/*++
Routine Description:
Deinitialize Memory Management
Arguments:
HcDev - USB2_HC_DEV
Returns:
EFI_SUCCESS Success
EFI_DEVICE_ERROR Fail
--*/
{
MEMORY_MANAGE_HEADER *TempHeaderPtr;
for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {
DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);
//
// when the TempHeaderPtr is freed in FreeMemoryHeader(),
// the TempHeaderPtr is pointing to nonsense content.
//
FreeMemoryHeader (HcDev, TempHeaderPtr);
//
// reset the TempHeaderPtr,continue free another memory block.
//
TempHeaderPtr = HcDev->MemoryHeader->Next;
}
FreeMemoryHeader (HcDev, HcDev->MemoryHeader);
return EFI_SUCCESS;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?