OvmfPkg: Add support for memory above 4GB

When QEMU has more than 3.5GB of RAM, it will map the
additional memory above 4GB.  This change will make that
RAM accessible to OVMF.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11266 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jljusten 2011-01-21 16:51:00 +00:00
parent 999a815e9f
commit c0e1097656
3 changed files with 81 additions and 7 deletions

View File

@ -36,7 +36,7 @@ Module Name:
STATIC STATIC
UINTN UINTN
GetSystemMemorySize ( GetSystemMemorySizeBelow4gb (
) )
{ {
UINT8 Cmos0x34; UINT8 Cmos0x34;
@ -58,6 +58,31 @@ GetSystemMemorySize (
} }
STATIC
UINT64
GetSystemMemorySizeAbove4gb (
)
{
UINT32 Size;
UINTN CmosIndex;
//
// CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
// * CMOS(0x5d) is the most significant size byte
// * CMOS(0x5c) is the middle size byte
// * CMOS(0x5b) is the least significant size byte
// * The size is specified in 64kb chunks
//
Size = 0;
for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
}
return LShiftU64 (Size, 16);
}
/** /**
Peform Memory Detection Peform Memory Detection
@ -71,23 +96,25 @@ MemDetect (
EFI_STATUS Status; EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS MemoryBase; EFI_PHYSICAL_ADDRESS MemoryBase;
UINT64 MemorySize; UINT64 MemorySize;
UINT64 TotalMemorySize; UINT64 LowerMemorySize;
UINT64 UpperMemorySize;
DEBUG ((EFI_D_ERROR, "MemDetect called\n")); DEBUG ((EFI_D_ERROR, "MemDetect called\n"));
// //
// Determine total memory size available // Determine total memory size available
// //
TotalMemorySize = (UINT64)GetSystemMemorySize (); LowerMemorySize = GetSystemMemorySizeBelow4gb ();
UpperMemorySize = GetSystemMemorySizeAbove4gb ();
// //
// Determine the range of memory to use during PEI // Determine the range of memory to use during PEI
// //
MemoryBase = PcdGet32 (PcdOvmfMemFvBase) + PcdGet32 (PcdOvmfMemFvSize); MemoryBase = PcdGet32 (PcdOvmfMemFvBase) + PcdGet32 (PcdOvmfMemFvSize);
MemorySize = TotalMemorySize - MemoryBase; MemorySize = LowerMemorySize - MemoryBase;
if (MemorySize > SIZE_16MB) { if (MemorySize > SIZE_64MB) {
MemoryBase = TotalMemorySize - SIZE_16MB; MemoryBase = LowerMemorySize - SIZE_64MB;
MemorySize = SIZE_16MB; MemorySize = SIZE_64MB;
} }
// //
@ -103,6 +130,10 @@ MemDetect (
AddMemoryRangeHob (BASE_1MB, MemoryBase); AddMemoryRangeHob (BASE_1MB, MemoryBase);
AddMemoryRangeHob (0, BASE_512KB + BASE_128KB); AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);
if (UpperMemorySize != 0) {
AddUntestedMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);
}
return MemoryBase + MemorySize; return MemoryBase + MemorySize;
} }

View File

@ -103,6 +103,37 @@ AddMemoryRangeHob (
AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase)); AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
} }
VOID
AddUntestedMemoryBaseSizeHob (
EFI_PHYSICAL_ADDRESS MemoryBase,
UINT64 MemorySize
)
{
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE,
MemoryBase,
MemorySize
);
}
VOID
AddUntestedMemoryRangeHob (
EFI_PHYSICAL_ADDRESS MemoryBase,
EFI_PHYSICAL_ADDRESS MemoryLimit
)
{
AddUntestedMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
}
VOID VOID
MemMapInitialization ( MemMapInitialization (
EFI_PHYSICAL_ADDRESS TopOfMemory EFI_PHYSICAL_ADDRESS TopOfMemory

View File

@ -39,6 +39,18 @@ AddMemoryRangeHob (
EFI_PHYSICAL_ADDRESS MemoryLimit EFI_PHYSICAL_ADDRESS MemoryLimit
); );
VOID
AddUntestedMemoryBaseSizeHob (
EFI_PHYSICAL_ADDRESS MemoryBase,
UINT64 MemorySize
);
VOID
AddUntestedMemoryRangeHob (
EFI_PHYSICAL_ADDRESS MemoryBase,
EFI_PHYSICAL_ADDRESS MemoryLimit
);
EFI_PHYSICAL_ADDRESS EFI_PHYSICAL_ADDRESS
MemDetect ( MemDetect (
VOID VOID