mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-11 14:28:08 +01:00
168 lines
5.5 KiB
C
168 lines
5.5 KiB
C
|
//Slice 2013
|
||
|
|
||
|
#include "Platform.h"
|
||
|
|
||
|
#ifndef DEBUG_ALL
|
||
|
#define DEBUG_EDID 1
|
||
|
#else
|
||
|
#define DEBUG_EDID DEBUG_ALL
|
||
|
#endif
|
||
|
|
||
|
#if DEBUG_EDID == 0
|
||
|
#define DBG(...)
|
||
|
#else
|
||
|
#define DBG(...) DebugLog(DEBUG_EDID, __VA_ARGS__)
|
||
|
#endif
|
||
|
|
||
|
EFI_STATUS EFIAPI GetEdidImpl(
|
||
|
IN EFI_EDID_OVERRIDE_PROTOCOL *This,
|
||
|
IN EFI_HANDLE *ChildHandle,
|
||
|
OUT UINT32 *Attributes,
|
||
|
IN OUT UINTN *EdidSize,
|
||
|
IN OUT UINT8 **Edid
|
||
|
)
|
||
|
{
|
||
|
*Edid = gSettings.CustomEDID;
|
||
|
*EdidSize = 128;
|
||
|
*Attributes = 0;
|
||
|
if (*Edid) {
|
||
|
return EFI_SUCCESS;
|
||
|
}
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
EFI_EDID_OVERRIDE_PROTOCOL gEdidOverride =
|
||
|
{
|
||
|
GetEdidImpl
|
||
|
};
|
||
|
|
||
|
EFI_STATUS
|
||
|
InitializeEdidOverride ()
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
EFI_EDID_OVERRIDE_PROTOCOL *EdidOverride;
|
||
|
|
||
|
EdidOverride = AllocateCopyPool(sizeof(EFI_EDID_OVERRIDE_PROTOCOL), &gEdidOverride);
|
||
|
|
||
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||
|
&gImageHandle,
|
||
|
&gEfiEdidOverrideProtocolGuid,
|
||
|
EdidOverride,
|
||
|
NULL
|
||
|
);
|
||
|
if (EFI_ERROR (Status)) {
|
||
|
DBG("Can't install EdidOverride on ImageHandle\n");
|
||
|
}
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
//used only if VBiosPatchNeeded and if no CustomEDID
|
||
|
UINT8* getCurrentEdid (VOID)
|
||
|
{
|
||
|
EFI_STATUS Status;
|
||
|
EFI_EDID_ACTIVE_PROTOCOL *EdidProtocol;
|
||
|
UINT8 *Edid;
|
||
|
|
||
|
DBG ("EdidActive:");
|
||
|
Edid = NULL;
|
||
|
Status = gBS->LocateProtocol (&gEfiEdidActiveProtocolGuid, NULL, (VOID**)&EdidProtocol);
|
||
|
if (!EFI_ERROR (Status)) {
|
||
|
DBG(" size=%d", EdidProtocol->SizeOfEdid);
|
||
|
if (EdidProtocol->SizeOfEdid > 0) {
|
||
|
Edid = AllocateCopyPool (EdidProtocol->SizeOfEdid, EdidProtocol->Edid);
|
||
|
}
|
||
|
}
|
||
|
DBG(" %a\n", Edid != NULL ? "found" : "not found");
|
||
|
|
||
|
return Edid;
|
||
|
}
|
||
|
|
||
|
VOID DebugDumpEDID(CONST CHAR8 *Message, INTN N)
|
||
|
{
|
||
|
INTN i,j;
|
||
|
// Don't dump in the case of debug logging because of too slow output
|
||
|
if (GlobalConfig.DebugLog) {
|
||
|
return;
|
||
|
}
|
||
|
DBG("%a size:%d\n", Message, N);
|
||
|
for (i=0; i<N; i+=10) {
|
||
|
DBG("%03d |", i);
|
||
|
for (j=0; j<10; j++) {
|
||
|
if (i+j > N-1) break;
|
||
|
DBG(" %02x", gSettings.CustomEDID[i+j]);
|
||
|
}
|
||
|
DBG("\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//Used at OS start
|
||
|
// if EFI_SUCCESS then result in gSettings.CustomEDID != NULL
|
||
|
// first priority is CustomEDID
|
||
|
// second is UEFI EDID from EdidDiscoveredProtocol
|
||
|
EFI_STATUS GetEdidDiscovered(VOID)
|
||
|
{
|
||
|
EFI_STATUS Status = EFI_SUCCESS;
|
||
|
UINTN N = 0;
|
||
|
UINT8 NewChecksum;
|
||
|
//gEDID = NULL;
|
||
|
|
||
|
if (gSettings.CustomEDID) {
|
||
|
N = gSettings.CustomEDIDsize;
|
||
|
DebugDumpEDID("--- Custom EDID Table", N);
|
||
|
} else {
|
||
|
Status = gBS->LocateProtocol (&gEfiEdidDiscoveredProtocolGuid, NULL, (VOID **)&EdidDiscovered);
|
||
|
if (!EFI_ERROR (Status)) { //discovered
|
||
|
N = EdidDiscovered->SizeOfEdid;
|
||
|
if (!GlobalConfig.DebugLog) {
|
||
|
DBG("EdidDiscovered size=%d\n", N);
|
||
|
}
|
||
|
if (N == 0) {
|
||
|
return EFI_NOT_FOUND;
|
||
|
}
|
||
|
gSettings.CustomEDID = AllocateAlignedPages(EFI_SIZE_TO_PAGES(N), 128);
|
||
|
CopyMem(gSettings.CustomEDID, EdidDiscovered->Edid, N);
|
||
|
DebugDumpEDID("--- Discovered EDID Table", N);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (gSettings.CustomEDID) {
|
||
|
// begin patching result
|
||
|
if (gSettings.VendorEDID) {
|
||
|
DBG(" VendorID = 0x%04lx changed to 0x%04lx\n", ((UINT16*)gSettings.CustomEDID)[4], gSettings.VendorEDID);
|
||
|
((UINT16*)gSettings.CustomEDID)[4] = gSettings.VendorEDID;
|
||
|
}
|
||
|
|
||
|
if (gSettings.ProductEDID) {
|
||
|
DBG(" ProductID = 0x%04lx changed to 0x%04lx\n", ((UINT16*)gSettings.CustomEDID)[5], gSettings.ProductEDID);
|
||
|
((UINT16*)gSettings.CustomEDID)[5] = gSettings.ProductEDID;
|
||
|
}
|
||
|
|
||
|
if (gSettings.EdidFixHorizontalSyncPulseWidth) {
|
||
|
DBG(" HorizontalSyncPulseWidth = 0x%02lx changed to 0x%02lx\n", ((UINT8*)gSettings.CustomEDID)[63], gSettings.EdidFixHorizontalSyncPulseWidth);
|
||
|
UINT8 LsBits, MsBits;
|
||
|
LsBits = gSettings.EdidFixHorizontalSyncPulseWidth & 0xff;
|
||
|
MsBits = (gSettings.EdidFixHorizontalSyncPulseWidth >> 8) & 0x03;
|
||
|
((UINT8*)gSettings.CustomEDID)[63] = LsBits;
|
||
|
LsBits = ((UINT8*)gSettings.CustomEDID)[65] & ~0x30;
|
||
|
((UINT8*)gSettings.CustomEDID)[65] = LsBits | (MsBits << 4);
|
||
|
}
|
||
|
|
||
|
if (gSettings.EdidFixVideoInputSignal) {
|
||
|
DBG(" VideoInputSignal = 0x%02lx changed to 0x%02lx\n", ((UINT8*)gSettings.CustomEDID)[20], gSettings.EdidFixVideoInputSignal);
|
||
|
((UINT8*)gSettings.CustomEDID)[20] = gSettings.EdidFixVideoInputSignal;
|
||
|
}
|
||
|
|
||
|
NewChecksum = (UINT8)(256 - Checksum8(gSettings.CustomEDID, 127));
|
||
|
if ((gSettings.VendorEDID) || (gSettings.ProductEDID) || (gSettings.EdidFixHorizontalSyncPulseWidth) || (gSettings.EdidFixVideoInputSignal)) {
|
||
|
((UINT8*)gSettings.CustomEDID)[127] = NewChecksum;
|
||
|
DebugDumpEDID("--- Patched EDID Table", N);
|
||
|
} else if (((UINT8*)gSettings.CustomEDID)[127] != NewChecksum) {
|
||
|
DBG(" Fix wrong checksum = 0x%02lx changed to ", ((UINT8*)gSettings.CustomEDID)[127]);
|
||
|
((UINT8*)gSettings.CustomEDID)[127] = NewChecksum;
|
||
|
DBG("0x%02lx\n", ((UINT8*)gSettings.CustomEDID)[127]);
|
||
|
DebugDumpEDID("--- Patched EDID Table", N);
|
||
|
}
|
||
|
}
|
||
|
return Status;
|
||
|
}
|