mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-27 12:15:19 +01:00
cd23181296
Signed-off-by: SergeySlice <sergey.slice@gmail.com>
602 lines
18 KiB
C
602 lines
18 KiB
C
/** @file
|
|
Apple RAM Disk library.
|
|
|
|
Copyright (C) 2019, Download-Fritz. All rights reserved.<BR>
|
|
This program and the accompanying materials are licensed and made available
|
|
under the terms and conditions of the BSD License which accompanies this
|
|
distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php.
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include <Uefi.h>
|
|
|
|
#include <Guid/OcVariable.h>
|
|
|
|
#include <Protocol/AppleRamDisk.h>
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/OcDebugLogLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/OcAppleRamDiskLib.h>
|
|
#include <Library/OcFileLib.h>
|
|
#include <Library/OcGuardLib.h>
|
|
#include <Library/OcMemoryLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
#include <Library/OcCryptoLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
#include <Library/UefiLib.h>
|
|
|
|
#define INTERNAL_ASSERT_EXTENT_TABLE_VALID(ExtentTable) \
|
|
ASSERT ((ExtentTable)->Signature == APPLE_RAM_DISK_EXTENT_SIGNATURE); \
|
|
ASSERT ((ExtentTable)->Version == APPLE_RAM_DISK_EXTENT_VERSION); \
|
|
ASSERT ((ExtentTable)->Reserved == 0); \
|
|
ASSERT ((ExtentTable)->Signature2 == APPLE_RAM_DISK_EXTENT_SIGNATURE); \
|
|
ASSERT ((ExtentTable)->ExtentCount > 0); \
|
|
ASSERT ((ExtentTable)->ExtentCount <= ARRAY_SIZE ((ExtentTable)->Extents))
|
|
|
|
/**
|
|
Insert allocated area into extent list. If no extent list
|
|
was created, then it gets allocated.
|
|
|
|
@param[in,out] ExtentTable Extent table, potentially pointing to NULL.
|
|
@param[in] AllocatedArea Allocated area of 1 or more pages.
|
|
@paran[in] AllocatedAreaSize Actual size of allocated area in bytes.
|
|
**/
|
|
STATIC
|
|
VOID
|
|
InternalAddAllocatedArea (
|
|
IN OUT APPLE_RAM_DISK_EXTENT_TABLE **ExtentTable,
|
|
IN EFI_PHYSICAL_ADDRESS AllocatedArea,
|
|
IN UINTN AllocatedAreaSize
|
|
)
|
|
{
|
|
APPLE_RAM_DISK_EXTENT_TABLE *Table;
|
|
|
|
ASSERT (AllocatedArea + AllocatedAreaSize - 1 <= MAX_UINTN);
|
|
ASSERT (AllocatedAreaSize >= EFI_PAGE_SIZE);
|
|
|
|
ZeroMem (
|
|
(VOID *)(UINTN)AllocatedArea,
|
|
EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (AllocatedAreaSize))
|
|
);
|
|
|
|
if (*ExtentTable == NULL) {
|
|
*ExtentTable = (APPLE_RAM_DISK_EXTENT_TABLE *)(UINTN)AllocatedArea;
|
|
|
|
(*ExtentTable)->Signature = APPLE_RAM_DISK_EXTENT_SIGNATURE;
|
|
(*ExtentTable)->Version = APPLE_RAM_DISK_EXTENT_VERSION;
|
|
(*ExtentTable)->Signature2 = APPLE_RAM_DISK_EXTENT_SIGNATURE;
|
|
|
|
AllocatedArea += EFI_PAGE_SIZE;
|
|
AllocatedAreaSize -= EFI_PAGE_SIZE;
|
|
/*
|
|
STATIC_ASSERT (
|
|
sizeof (APPLE_RAM_DISK_EXTENT_TABLE) == EFI_PAGE_SIZE,
|
|
"Extent table different from EFI_PAGE_SIZE is unsupported!"
|
|
);
|
|
*/
|
|
if (AllocatedAreaSize == 0) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
Table = *ExtentTable;
|
|
Table->Extents[Table->ExtentCount].Start = AllocatedArea;
|
|
Table->Extents[Table->ExtentCount].Length = AllocatedAreaSize;
|
|
++Table->ExtentCount;
|
|
}
|
|
|
|
/**
|
|
Perform allocation of RemainingSize data with biggest contiguous area
|
|
first strategy. Allocation extent map is put to the first allocated
|
|
extent.
|
|
|
|
@param[in] BaseAddress Starting allocation address.
|
|
@param[in] TopAddress Ending allocation address.
|
|
@param[in] MemoryType Requested memory type.
|
|
@param[in,out] MemoryMap Current memory map modified as we go.
|
|
@param[in] MemoryMapSize Current memory map size.
|
|
@param[in] DescriptorSize Current memory map descriptor size.
|
|
@param[in] RemainingSize Remaining size to allocate.
|
|
@param[in,out] ExtentTable Updated pointer to allocated area.
|
|
|
|
@retval Size of allocated data.
|
|
**/
|
|
STATIC
|
|
UINTN
|
|
InternalAllocateRemainingSize (
|
|
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
|
IN EFI_PHYSICAL_ADDRESS TopAddress,
|
|
IN EFI_MEMORY_TYPE MemoryType,
|
|
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
|
IN UINTN MemoryMapSize,
|
|
IN UINTN DescriptorSize,
|
|
IN UINTN RemainingSize,
|
|
IN OUT APPLE_RAM_DISK_EXTENT_TABLE **ExtentTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_MEMORY_DESCRIPTOR *EntryWalker;
|
|
EFI_MEMORY_DESCRIPTOR *BiggestEntry;
|
|
EFI_PHYSICAL_ADDRESS AllocatedArea;
|
|
UINT64 BiggestSize;
|
|
UINT64 UsedSize;
|
|
UINTN FinalUsedSize;
|
|
|
|
//
|
|
// Require page aligned base and top addresses.
|
|
//
|
|
ASSERT (BaseAddress == EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (BaseAddress)));
|
|
ASSERT (TopAddress == EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (TopAddress)));
|
|
|
|
while (RemainingSize > 0 && (*ExtentTable == NULL
|
|
|| (*ExtentTable)->ExtentCount < ARRAY_SIZE ((*ExtentTable)->Extents))) {
|
|
|
|
BiggestEntry = NULL;
|
|
BiggestSize = 0;
|
|
|
|
for (
|
|
EntryWalker = MemoryMap;
|
|
(UINT8 *)EntryWalker < ((UINT8 *)MemoryMap + MemoryMapSize);
|
|
EntryWalker = NEXT_MEMORY_DESCRIPTOR (EntryWalker, DescriptorSize)) {
|
|
|
|
//
|
|
// FIXME: This currently skips segments starting before BaseAddress but potentially lasting
|
|
// further: 0, PhysicalStart, BaseAddress, PhysicalEnd, infinity. This was done intentionally,
|
|
// to avoid splitting one entry into two, when TopAddress is before PhysicalEnd, but can still
|
|
// be improved.
|
|
//
|
|
if (EntryWalker->Type != EfiConventionalMemory
|
|
|| EntryWalker->PhysicalStart < BaseAddress
|
|
|| EntryWalker->PhysicalStart >= TopAddress) {
|
|
continue;
|
|
}
|
|
|
|
UsedSize = EFI_PAGES_TO_SIZE (EntryWalker->NumberOfPages);
|
|
if (EntryWalker->PhysicalStart + UsedSize > TopAddress) {
|
|
//
|
|
// Guaranteed to be page aligned as TopAddress is page aligned.
|
|
//
|
|
UsedSize = TopAddress - EntryWalker->PhysicalStart;
|
|
}
|
|
|
|
if (BiggestEntry == NULL || UsedSize > BiggestSize) {
|
|
BiggestEntry = EntryWalker;
|
|
BiggestSize = UsedSize;
|
|
}
|
|
}
|
|
|
|
if (BiggestEntry == NULL || BiggestSize == 0) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCRAM: No entry for allocation %p / 0x%Lx bytes, rem 0x%Lx in 0x%Lx:0x%Lx\n",
|
|
BiggestEntry,
|
|
(UINT64) BiggestSize,
|
|
(UINT64) RemainingSize,
|
|
(UINT64) BaseAddress,
|
|
(UINT64) TopAddress
|
|
));
|
|
return RemainingSize;
|
|
}
|
|
|
|
FinalUsedSize = (UINTN) MIN (BiggestSize, RemainingSize);
|
|
|
|
AllocatedArea = BiggestEntry->PhysicalStart;
|
|
Status = gBS->AllocatePages (
|
|
AllocateAddress,
|
|
MemoryType,
|
|
EFI_SIZE_TO_PAGES (FinalUsedSize),
|
|
&AllocatedArea
|
|
);
|
|
|
|
if (EFI_ERROR(Status)) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCRAM: Broken allocator for 0x%Lx in 0x%Lx bytes, rem 0x%Lx - %r\n",
|
|
(UINT64) BiggestEntry->PhysicalStart,
|
|
(UINT64) FinalUsedSize,
|
|
(UINT64) RemainingSize,
|
|
Status
|
|
));
|
|
return RemainingSize;
|
|
}
|
|
|
|
InternalAddAllocatedArea (ExtentTable, AllocatedArea, FinalUsedSize);
|
|
|
|
RemainingSize -= FinalUsedSize;
|
|
|
|
BiggestEntry->PhysicalStart += EFI_SIZE_TO_PAGES (FinalUsedSize);
|
|
BiggestEntry->NumberOfPages -= EFI_SIZE_TO_PAGES (FinalUsedSize);
|
|
}
|
|
|
|
return RemainingSize;
|
|
}
|
|
|
|
/**
|
|
Request allocation of Size bytes in extents table.
|
|
Extents are put to the first allocated page.
|
|
|
|
1. Retrieve actual memory mapping.
|
|
2. Do allocation at BASE_4GB if requested.
|
|
3. Do additional allocation at any address if still have pages to allocate.
|
|
|
|
@param[in] Size Requested memory size.
|
|
@param[in] MemoryType Requested memory type.
|
|
@param[in] PreferHighMem Try to allocate in upper 4GB first.
|
|
|
|
@retval Allocated extent table.
|
|
**/
|
|
STATIC
|
|
CONST APPLE_RAM_DISK_EXTENT_TABLE *
|
|
InternalAppleRamDiskAllocate (
|
|
IN UINTN Size,
|
|
IN EFI_MEMORY_TYPE MemoryType,
|
|
IN BOOLEAN PreferHighMem
|
|
)
|
|
{
|
|
BOOLEAN Result;
|
|
UINTN MemoryMapSize;
|
|
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
|
UINTN DescriptorSize;
|
|
UINTN RemainingSize;
|
|
APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable;
|
|
|
|
MemoryMap = OcGetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL, NULL, FALSE);
|
|
if (MemoryMap == NULL) {
|
|
return NULL;
|
|
}
|
|
/*
|
|
STATIC_ASSERT (
|
|
sizeof (APPLE_RAM_DISK_EXTENT_TABLE) == EFI_PAGE_SIZE,
|
|
"Extent table different from EFI_PAGE_SIZE is unsupported!"
|
|
);
|
|
*/
|
|
Result = OcOverflowAddUN (Size, EFI_PAGE_SIZE, &RemainingSize);
|
|
if (Result) {
|
|
return NULL;
|
|
}
|
|
|
|
ExtentTable = NULL;
|
|
|
|
//
|
|
// We implement PreferHighMem to avoid colliding with the kernel, which sits
|
|
// in the lower addresses (see more detail in AptioMemoryFix) depending on
|
|
// KASLR offset generated randomly or with slide boot argument.
|
|
//
|
|
if (PreferHighMem) {
|
|
RemainingSize = InternalAllocateRemainingSize (
|
|
BASE_4GB,
|
|
BASE_8EB,
|
|
MemoryType,
|
|
MemoryMap,
|
|
MemoryMapSize,
|
|
DescriptorSize,
|
|
RemainingSize,
|
|
&ExtentTable
|
|
);
|
|
}
|
|
|
|
//
|
|
// This may be tried improved when PreferHighMem is FALSE.
|
|
// 1. One way is implement a bugtracking algorithm, similar to DF algo originally in place.
|
|
// The allocations will go recursively from biggest >= BASE_4G until the strategy fails.
|
|
// When it does, last allocation is discarded, and the strategy tries lower in this case.
|
|
// memory until success.
|
|
// The implementation must be very careful about avoiding recursion and high complexity.
|
|
// 2. Another way could be to try to avoid allocating in kernel area specifically, though
|
|
// allowing to allocate in lower memory. This has a backdash of allocation failures
|
|
// when extent amount exceeds the limit, and may want a third pass. It may also collide
|
|
// with firmware pool allocator.
|
|
//
|
|
// None of those (or any extra) are implemented, as with PreferHighMem = TRUE it should
|
|
// always succeed allocating in higher memory on any host with >= 8 GB of RAM, which is
|
|
// the requirement for modern macOS.
|
|
//
|
|
RemainingSize = InternalAllocateRemainingSize (
|
|
0,
|
|
BASE_8EB,
|
|
MemoryType,
|
|
MemoryMap,
|
|
MemoryMapSize,
|
|
DescriptorSize,
|
|
RemainingSize,
|
|
&ExtentTable
|
|
);
|
|
|
|
if (RemainingSize > 0 && ExtentTable != NULL) {
|
|
OcAppleRamDiskFree (ExtentTable);
|
|
|
|
ExtentTable = NULL;
|
|
}
|
|
|
|
return ExtentTable;
|
|
}
|
|
|
|
CONST APPLE_RAM_DISK_EXTENT_TABLE *
|
|
OcAppleRamDiskAllocate (
|
|
IN UINTN Size,
|
|
IN EFI_MEMORY_TYPE MemoryType
|
|
)
|
|
{
|
|
CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable;
|
|
|
|
//
|
|
// Try to allocate preferrably above BASE_4GB to avoid colliding with the kernel.
|
|
//
|
|
ExtentTable = InternalAppleRamDiskAllocate (Size, MemoryType, TRUE);
|
|
|
|
if (ExtentTable == NULL) {
|
|
//
|
|
// Being here means that we exceeded entry amount in the extent table.
|
|
// Retry with any addresses. Should never happen in reality.
|
|
//
|
|
ExtentTable = InternalAppleRamDiskAllocate (Size, MemoryType, FALSE);
|
|
}
|
|
/*
|
|
DEBUG ((
|
|
DEBUG_BULK_INFO,
|
|
"OCRAM: Extent allocation of %u bytes (%x) gave %p\n",
|
|
(UINT32) Size,
|
|
(UINT32) MemoryType,
|
|
ExtentTable
|
|
));
|
|
*/
|
|
return ExtentTable;
|
|
}
|
|
|
|
BOOLEAN
|
|
OcAppleRamDiskRead (
|
|
IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable,
|
|
IN UINTN Offset,
|
|
IN UINTN Size,
|
|
OUT VOID *Buffer
|
|
)
|
|
{
|
|
UINT8 *BufferBytes;
|
|
|
|
UINT32 Index;
|
|
CONST APPLE_RAM_DISK_EXTENT *Extent;
|
|
|
|
UINTN CurrentOffset;
|
|
UINTN LocalOffset;
|
|
UINTN LocalSize;
|
|
|
|
ASSERT (ExtentTable != NULL);
|
|
INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable);
|
|
ASSERT (Size > 0);
|
|
ASSERT (Buffer != NULL);
|
|
|
|
BufferBytes = Buffer;
|
|
//
|
|
// As per the allocation algorithm, the sum over all Extent->Length must be
|
|
// smaller than MAX_UINTN.
|
|
//
|
|
for (
|
|
Index = 0, CurrentOffset = 0;
|
|
Index < ExtentTable->ExtentCount;
|
|
++Index, CurrentOffset += (UINTN)Extent->Length
|
|
) {
|
|
Extent = &ExtentTable->Extents[Index];
|
|
ASSERT (Extent->Start <= MAX_UINTN);
|
|
ASSERT (Extent->Length <= MAX_UINTN);
|
|
|
|
if (Offset >= CurrentOffset && (Offset - CurrentOffset) < Extent->Length) {
|
|
LocalOffset = (Offset - CurrentOffset);
|
|
LocalSize = (UINTN)MIN ((Extent->Length - LocalOffset), Size);
|
|
CopyMem (
|
|
BufferBytes,
|
|
(VOID *)((UINTN)Extent->Start + LocalOffset),
|
|
LocalSize
|
|
);
|
|
|
|
Size -= LocalSize;
|
|
if (Size == 0) {
|
|
return TRUE;
|
|
}
|
|
|
|
BufferBytes += LocalSize;
|
|
Offset += LocalSize;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN
|
|
OcAppleRamDiskWrite (
|
|
IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable,
|
|
IN UINTN Offset,
|
|
IN UINTN Size,
|
|
IN CONST VOID *Buffer
|
|
)
|
|
{
|
|
CONST UINT8 *BufferBytes;
|
|
|
|
UINT32 Index;
|
|
CONST APPLE_RAM_DISK_EXTENT *Extent;
|
|
|
|
UINTN CurrentOffset;
|
|
UINTN LocalOffset;
|
|
UINTN LocalSize;
|
|
|
|
ASSERT (ExtentTable != NULL);
|
|
INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable);
|
|
ASSERT (Size > 0);
|
|
ASSERT (Buffer != NULL);
|
|
|
|
BufferBytes = Buffer;
|
|
//
|
|
// As per the allocation algorithm, the sum over all Extent->Length must be
|
|
// smaller than MAX_UINTN.
|
|
//
|
|
for (
|
|
Index = 0, CurrentOffset = 0;
|
|
Index < ExtentTable->ExtentCount;
|
|
++Index, CurrentOffset += (UINTN)Extent->Length
|
|
) {
|
|
Extent = &ExtentTable->Extents[Index];
|
|
ASSERT (Extent->Start <= MAX_UINTN);
|
|
ASSERT (Extent->Length <= MAX_UINTN);
|
|
|
|
if (Offset >= CurrentOffset && (Offset - CurrentOffset) < Extent->Length) {
|
|
LocalOffset = (Offset - CurrentOffset);
|
|
LocalSize = (UINTN)MIN ((Extent->Length - LocalOffset), Size);
|
|
CopyMem (
|
|
(VOID *)((UINTN)Extent->Start + LocalOffset),
|
|
BufferBytes,
|
|
LocalSize
|
|
);
|
|
|
|
Size -= LocalSize;
|
|
if (Size == 0) {
|
|
return TRUE;
|
|
}
|
|
|
|
BufferBytes += LocalSize;
|
|
Offset += LocalSize;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOLEAN
|
|
OcAppleRamDiskLoadFile (
|
|
IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable,
|
|
IN EFI_FILE_PROTOCOL *File,
|
|
IN UINTN FileSize
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT64 FilePosition;
|
|
UINT32 Index;
|
|
UINTN RequestedSize;
|
|
UINTN ReadSize;
|
|
UINTN ExtentSize;
|
|
SHA256_CONTEXT Ctx;
|
|
UINT8 Digest[SHA256_DIGEST_SIZE];
|
|
UINT8 *TmpBuffer;
|
|
UINT8 *ExtentBuffer;
|
|
|
|
ASSERT (ExtentTable != NULL);
|
|
INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable);
|
|
ASSERT (File != NULL);
|
|
ASSERT (FileSize > 0);
|
|
|
|
//
|
|
// We need a temporary buffer in lower addresses as several motherboards on APTIO IV,
|
|
// e.g. GA-Z77P-D3 (rev. 1.1), GA-Z87X-UD4H, etc. fail to read directly to high addresses
|
|
// when using FAT filesystem. The original workaround to this was AvoidHighAlloc quirk.
|
|
// REF: https://github.com/acidanthera/bugtracker/issues/449
|
|
//
|
|
TmpBuffer = AllocatePool (BASE_4MB);
|
|
if (TmpBuffer == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
DEBUG_CODE_BEGIN ();
|
|
Sha256Init (&Ctx);
|
|
DEBUG_CODE_END ();
|
|
|
|
FilePosition = 0;
|
|
|
|
for (Index = 0; Index < ExtentTable->ExtentCount && FileSize > 0; ++Index) {
|
|
ASSERT (ExtentTable->Extents[Index].Start <= MAX_UINTN);
|
|
ASSERT (ExtentTable->Extents[Index].Length <= MAX_UINTN);
|
|
|
|
ExtentBuffer = (VOID *)(UINTN) ExtentTable->Extents[Index].Start;
|
|
ExtentSize = (UINTN) ExtentTable->Extents[Index].Length;
|
|
|
|
while (FileSize > 0 && ExtentSize > 0) {
|
|
Status = File->SetPosition (File, FilePosition);
|
|
if (EFI_ERROR(Status)) {
|
|
FreePool (TmpBuffer);
|
|
return FALSE;
|
|
}
|
|
|
|
RequestedSize = MIN (MIN (BASE_4MB, FileSize), ExtentSize);
|
|
ReadSize = RequestedSize;
|
|
Status = File->Read (
|
|
File,
|
|
&ReadSize,
|
|
TmpBuffer
|
|
);
|
|
if (EFI_ERROR(Status) || RequestedSize != ReadSize) {
|
|
FreePool (TmpBuffer);
|
|
return FALSE;
|
|
}
|
|
|
|
DEBUG_CODE_BEGIN ();
|
|
Sha256Update (&Ctx, TmpBuffer, ReadSize);
|
|
DEBUG_CODE_END ();
|
|
|
|
CopyMem (ExtentBuffer, TmpBuffer, ReadSize);
|
|
|
|
FilePosition += ReadSize;
|
|
ExtentBuffer += ReadSize;
|
|
ExtentSize -= ReadSize;
|
|
FileSize -= ReadSize;
|
|
}
|
|
}
|
|
|
|
FreePool (TmpBuffer);
|
|
|
|
//
|
|
// Not enough extents.
|
|
//
|
|
if (FileSize != 0) {
|
|
return FALSE;
|
|
}
|
|
|
|
DEBUG_CODE_BEGIN ();
|
|
Sha256Final (&Ctx, Digest);
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCRAM: SHA-256 Digest is: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
|
Digest[0], Digest[1], Digest[2], Digest[3], Digest[4], Digest[5], Digest[6], Digest[7], Digest[8], Digest[9],
|
|
Digest[10], Digest[11], Digest[12], Digest[13], Digest[14], Digest[15], Digest[16], Digest[17], Digest[18], Digest[19],
|
|
Digest[20], Digest[21], Digest[22], Digest[23], Digest[24], Digest[25], Digest[26], Digest[27], Digest[28], Digest[29],
|
|
Digest[30], Digest[31]
|
|
));
|
|
DEBUG_CODE_END ();
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
OcAppleRamDiskFree (
|
|
IN CONST APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable
|
|
)
|
|
{
|
|
UINT32 Index;
|
|
|
|
ASSERT (ExtentTable != NULL);
|
|
INTERNAL_ASSERT_EXTENT_TABLE_VALID (ExtentTable);
|
|
ASSERT (ExtentTable->Extents[0].Start <= MAX_UINTN);
|
|
ASSERT (ExtentTable->Extents[0].Length <= MAX_UINTN);
|
|
|
|
//
|
|
// Extents are allocated in the first page.
|
|
//
|
|
for (Index = 1; Index < ExtentTable->ExtentCount; ++Index) {
|
|
ASSERT (ExtentTable->Extents[Index].Start <= MAX_UINTN);
|
|
ASSERT (ExtentTable->Extents[Index].Length <= MAX_UINTN);
|
|
|
|
gBS->FreePages (
|
|
(UINTN)ExtentTable->Extents[Index].Start,
|
|
(UINTN)EFI_SIZE_TO_PAGES (ExtentTable->Extents[Index].Length)
|
|
);
|
|
}
|
|
//
|
|
// One page is added to account for the header.
|
|
//
|
|
gBS->FreePages (
|
|
(UINTN)ExtentTable,
|
|
(UINTN)EFI_SIZE_TO_PAGES (ExtentTable->Extents[0].Length) + 1
|
|
);
|
|
}
|