mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-27 12:15:19 +01:00
f35acfa5ab
Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
183 lines
5.3 KiB
C
183 lines
5.3 KiB
C
/**
|
|
|
|
Low memory fixes for some UEFI boards to load OSX.
|
|
|
|
by dmazar, based on modbin info:
|
|
http://www.projectosx.com/forum/index.php?showtopic=2428&st=0&p=17766&#entry17766
|
|
|
|
confirmed by akbar102 with Aspire 5750G with InsydeH2O UEFI:
|
|
http://www.projectosx.com/forum/index.php?showtopic=2428&st=300&p=19078&#entry19078
|
|
|
|
**/
|
|
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/UefiLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/CpuLib.h>
|
|
|
|
#include <Protocol/LoadedImage.h>
|
|
|
|
#include "NVRAMDebug.h"
|
|
#include "Lib.h"
|
|
|
|
// DBG_TO: 0=no debug, 1=serial, 2=console
|
|
// serial requires
|
|
// [PcdsFixedAtBuild]
|
|
// gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x07
|
|
// gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0xFFFFFFFF
|
|
// in package DSC file
|
|
#define DBG_TO 0
|
|
|
|
#if DBG_TO == 2
|
|
#define DBG(...) AsciiPrint(__VA_ARGS__);
|
|
#elif DBG_TO == 1
|
|
#define DBG(...) DebugPrint(1, __VA_ARGS__);
|
|
#else
|
|
#define DBG(...)
|
|
#endif
|
|
|
|
#include "../Version.h"
|
|
CONST CHAR8* CloverRevision = REVISION_STR;
|
|
|
|
|
|
// the highest address that kernel will use
|
|
#define KERNEL_TOP_ADDRESS 0x10000000 // 256MB
|
|
|
|
EFI_IMAGE_START gStartImage = NULL;
|
|
|
|
/** Free all mem regions between 0x100000 and KERNEL_TOP_ADDRESS */
|
|
EFI_STATUS
|
|
DoFixes(VOID)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINTN MemoryMapSize;
|
|
EFI_MEMORY_DESCRIPTOR *MemoryMap;
|
|
UINTN MapKey;
|
|
UINTN DescriptorSize;
|
|
UINT32 DescriptorVersion;
|
|
EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;
|
|
EFI_MEMORY_DESCRIPTOR *Desc;
|
|
|
|
Status = GetMemoryMapAlloc(gBS->GetMemoryMap, &MemoryMapSize, &MemoryMap, &MapKey, &DescriptorSize, &DescriptorVersion);
|
|
if (EFI_ERROR(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = EFI_NOT_FOUND;
|
|
|
|
//DBG("MEMMAP: Size=%d, Addr=%p, DescSize=%d, DescVersion: 0x%x\n", MemoryMapSize, MemoryMap, DescriptorSize, DescriptorVersion);
|
|
//DBG("Type Start End VStart # Pages Attributes\n");
|
|
MemoryMapEnd = NEXT_MEMORY_DESCRIPTOR(MemoryMap, MemoryMapSize);
|
|
for (Desc = MemoryMap ; Desc < MemoryMapEnd; Desc = NEXT_MEMORY_DESCRIPTOR(Desc, DescriptorSize)) {
|
|
/*
|
|
DBG("%-12s %lX-%lX %lX %lX %lX\n",
|
|
EfiMemoryTypeDesc[Desc->Type],
|
|
Desc->PhysicalStart,
|
|
Desc->PhysicalStart + EFI_PAGES_TO_SIZE(Desc->NumberOfPages) - 1,
|
|
Desc->VirtualStart,
|
|
Desc->NumberOfPages,
|
|
Desc->Attribute
|
|
);
|
|
*/
|
|
if (Desc->Type == EfiConventionalMemory // free mem
|
|
|| Desc->PhysicalStart + EFI_PAGES_TO_SIZE((UINTN)Desc->NumberOfPages) <= 0x100000 // below critical space
|
|
|| Desc->PhysicalStart >= KERNEL_TOP_ADDRESS // above critical space
|
|
)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// occupied mem block - free it
|
|
Status = gBS->FreePages(Desc->PhysicalStart, Desc->NumberOfPages);
|
|
DBG("FreePages: At %lx, Num=0x%x = %r\n", Desc->PhysicalStart, Desc->NumberOfPages, Status);
|
|
}
|
|
|
|
// release mem
|
|
FreePool(MemoryMap);
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
/** Called to start an image. If this is boot.efi, then do our fixes.*/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MOStartImage (
|
|
IN EFI_HANDLE ImageHandle,
|
|
OUT UINTN *ExitDataSize,
|
|
OUT CHAR16 **ExitData OPTIONAL
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_LOADED_IMAGE_PROTOCOL *Image;
|
|
CHAR16 *FilePathText = NULL;
|
|
|
|
DBG("StartImage(%lx)\n", ImageHandle);
|
|
|
|
// find out image name from EfiLoadedImageProtocol
|
|
Status = gBS->OpenProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &Image, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
if (Status != EFI_SUCCESS) {
|
|
DBG("ERROR: MOStartImage: OpenProtocol(gEfiLoadedImageProtocolGuid) = %r\n", Status);
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
FilePathText = FileDevicePathToText(Image->FilePath);
|
|
if (FilePathText != NULL) {
|
|
DBG("FilePath: %s\n", FilePathText);
|
|
}
|
|
DBG("ImageBase: %p - %lx (%lx)\n", Image->ImageBase, (UINT64)Image->ImageBase + Image->ImageSize, Image->ImageSize);
|
|
Status = gBS->CloseProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, gImageHandle, NULL);
|
|
if (EFI_ERROR(Status)) {
|
|
DBG("CloseProtocol error: %r\n", Status);
|
|
}
|
|
|
|
// check if this is boot.efi
|
|
if (StrStriBasic(FilePathText, L"boot.efi")) {
|
|
// it is - fix lower mem
|
|
DoFixes();
|
|
}
|
|
|
|
// call original to do the job
|
|
Status = gStartImage(ImageHandle, ExitDataSize, ExitData);
|
|
|
|
if (FilePathText != NULL) {
|
|
gBS->FreePool(FilePathText);
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
|
|
/** Entry point. Installs StartImage override to detect boot.efi start. */
|
|
EFI_STATUS
|
|
EFIAPI
|
|
OsxLowMemFixDrvEntrypoint (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
//EFI_PHYSICAL_ADDRESS Addr;
|
|
|
|
// install StartImage override
|
|
gStartImage = gBS->StartImage;
|
|
gBS->StartImage = MOStartImage;
|
|
gBS->Hdr.CRC32 = 0;
|
|
gBS->CalculateCrc32(gBS, sizeof(EFI_BOOT_SERVICES), &gBS->Hdr.CRC32);
|
|
|
|
/*
|
|
// alloc test regions
|
|
Addr = 0x2000000;
|
|
gBS->AllocatePages(AllocateAddress, EfiBootServicesData, 0xcc, &Addr);
|
|
Addr = 0x0F0000;
|
|
gBS->AllocatePages(AllocateAddress, EfiBootServicesData, 0x40, &Addr);
|
|
Addr = 0x160000;
|
|
gBS->AllocatePages(AllocateAddress, EfiBootServicesData, 0xaa, &Addr);
|
|
Addr = 0x5FFF000;
|
|
gBS->AllocatePages(AllocateAddress, EfiBootServicesData, 0x4, &Addr);
|
|
*/
|
|
return EFI_SUCCESS;
|
|
}
|
|
|