Sync patches r13953, r13956, r13991, r13992, r14073, r14075, r14205 and r14225 from main trunk.

1. If IDE controller is not in IDE mode, we should not clear IO bar.
2. Remove hard code value and create new PCDs for OpROM reserved range in CSM module.
3. Parse full EDID data to get all video resolutions supported by monitors.
4. Take the highest horizontal resolution as highest video resolution.
5. Call LegacyBiosInstallVgaRom to shadow Legacy VBIOS instead of LegacyBiosInstallPciRom during legacy boot.
6. When EDID comes from hardware INT10 and does not include 800x600, 640x480 and 1024x768, but INT10 supports these modes, add them into GOP mode.



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/branches/UDK2010.SR1@14246 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
vanjeff 2013-04-04 04:27:39 +00:00
parent 688a1eb0a6
commit 31d95c506f
8 changed files with 198 additions and 61 deletions

View file

@ -1,7 +1,7 @@
/** @file
ConsoleOut Routines that speak VGA.
Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -1129,49 +1129,79 @@ ParseEdidData (
((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;
for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {
if ((TimingBits & 0x1) != 0) {
DEBUG ((EFI_D_INFO, "Established Timing: %d x %d\n",
mEstablishedEdidTiming[Index].HorizontalResolution, mEstablishedEdidTiming[Index].VerticalResolution));
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&mEstablishedEdidTiming[Index]);
ValidNumber ++;
}
TimingBits = TimingBits >> 1;
}
} else {
}
//
// Parse the standard timing data
//
BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];
for (Index = 0; Index < 8; Index ++) {
//
// If no Established timing data, read the standard timing data
// Check if this is a valid Standard Timing entry
// VESA documents unused fields should be set to 01h
//
BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];
for (Index = 0; Index < 8; Index ++) {
if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){
//
// A valid Standard Timing
//
HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248);
AspectRatio = (UINT8) (BufferIndex[1] >> 6);
switch (AspectRatio) {
case 0:
VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10);
break;
case 1:
VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
break;
case 2:
VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4);
break;
case 3:
VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9);
break;
default:
VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
break;
}
RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);
TempTiming.HorizontalResolution = HorizontalResolution;
TempTiming.VerticalResolution = VerticalResolution;
TempTiming.RefreshRate = RefreshRate;
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
ValidNumber ++;
if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){
//
// A valid Standard Timing
//
HorizontalResolution = (UINT16) (BufferIndex[0] * 8 + 248);
AspectRatio = (UINT8) (BufferIndex[1] >> 6);
switch (AspectRatio) {
case 0:
VerticalResolution = (UINT16) (HorizontalResolution / 16 * 10);
break;
case 1:
VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
break;
case 2:
VerticalResolution = (UINT16) (HorizontalResolution / 5 * 4);
break;
case 3:
VerticalResolution = (UINT16) (HorizontalResolution / 16 * 9);
break;
default:
VerticalResolution = (UINT16) (HorizontalResolution / 4 * 3);
break;
}
BufferIndex += 2;
RefreshRate = (UINT8) ((BufferIndex[1] & 0x1f) + 60);
DEBUG ((EFI_D_INFO, "Standard Timing: %d x %d\n", HorizontalResolution, VerticalResolution));
TempTiming.HorizontalResolution = HorizontalResolution;
TempTiming.VerticalResolution = VerticalResolution;
TempTiming.RefreshRate = RefreshRate;
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
ValidNumber ++;
}
BufferIndex += 2;
}
//
// Parse the Detailed Timing data
//
BufferIndex = &EdidDataBlock->DetailedTimingDescriptions[0];
for (Index = 0; Index < 4; Index ++, BufferIndex += VESA_BIOS_EXTENSIONS_DETAILED_TIMING_EACH_DESCRIPTOR_SIZE) {
if ((BufferIndex[0] == 0x0) && (BufferIndex[1] == 0x0)) {
//
// Check if this is a valid Detailed Timing Descriptor
// If first 2 bytes are zero, it is monitor descriptor other than detailed timing descriptor
//
continue;
}
//
// Calculate Horizontal and Vertical resolution
//
TempTiming.HorizontalResolution = ((UINT16)(BufferIndex[4] & 0xF0) << 4) | (BufferIndex[2]);
TempTiming.VerticalResolution = ((UINT16)(BufferIndex[7] & 0xF0) << 4) | (BufferIndex[5]);
DEBUG ((EFI_D_INFO, "Detailed Timing %d: %d x %d\n",
Index, TempTiming.HorizontalResolution, TempTiming.VerticalResolution));
ValidEdidTiming->Key[ValidNumber] = CalculateEdidKey (&TempTiming);
ValidNumber ++;
}
ValidEdidTiming->ValidNumber = ValidNumber;
@ -1550,6 +1580,9 @@ BiosVideoCheckForVbe (
continue;
}
DEBUG ((EFI_D_INFO, "Video Controller Mode 0x%x: %d x %d\n",
VbeModeNumber, BiosVideoPrivate->VbeModeInformationBlock->XResolution, BiosVideoPrivate->VbeModeInformationBlock->YResolution));
if (EdidFound && (ValidEdidTiming.ValidNumber > 0)) {
//
// EDID exist, check whether this mode match with any mode in EDID
@ -1557,7 +1590,16 @@ BiosVideoCheckForVbe (
Timing.HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;
Timing.VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;
if (!SearchEdidTiming (&ValidEdidTiming, &Timing)) {
//
// When EDID comes from INT10 call, EDID does not include 800x600, 640x480 and 1024x768,
// but INT10 can support these modes, we add them into GOP mode.
//
if ((BiosVideoPrivate->EdidDiscovered.SizeOfEdid != 0) &&
!((Timing.HorizontalResolution) == 1024 && (Timing.VerticalResolution == 768)) &&
!((Timing.HorizontalResolution) == 800 && (Timing.VerticalResolution == 600)) &&
!((Timing.HorizontalResolution) == 640 && (Timing.VerticalResolution == 480))) {
continue;
}
}
}
@ -1593,8 +1635,9 @@ BiosVideoCheckForVbe (
//
// Record the highest resolution mode to set later
//
if ((BiosVideoPrivate->VbeModeInformationBlock->XResolution >= HighestHorizontalResolution) &&
(BiosVideoPrivate->VbeModeInformationBlock->YResolution >= HighestVerticalResolution)) {
if ((BiosVideoPrivate->VbeModeInformationBlock->XResolution > HighestHorizontalResolution) ||
((BiosVideoPrivate->VbeModeInformationBlock->XResolution == HighestHorizontalResolution) &&
(BiosVideoPrivate->VbeModeInformationBlock->YResolution > HighestVerticalResolution))) {
HighestHorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;
HighestVerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;
HighestResolutionMode = ModeNumber;

View file

@ -1,6 +1,6 @@
/** @file
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -168,6 +168,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128
#define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17
//
// Established Timings: 24 possible resolutions
// Standard Timings: 8 possible resolutions
// Detailed Timings: 4 possible resolutions
//
#define VESA_BIOS_EXTENSIONS_EDID_TIMING_MAX_NUMBER 36
//
// Timing data size for Established Timings, Standard Timings and Detailed Timings
//
#define VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE 3
#define VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE 16
#define VESA_BIOS_EXTENSIONS_DETAILED_TIMING_EACH_DESCRIPTOR_SIZE 18
#define VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE 72
typedef struct {
UINT16 HorizontalResolution;
UINT16 VerticalResolution;
@ -176,7 +191,7 @@ typedef struct {
typedef struct {
UINT32 ValidNumber;
UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER];
UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_TIMING_MAX_NUMBER];
} VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING;
typedef struct {
@ -203,9 +218,9 @@ typedef struct {
UINT8 BlueY; //Blue-y Bits 9 - 2
UINT8 WhiteX; //White-x Bits 9 - 2
UINT8 WhiteY; //White-x Bits 9 - 2
UINT8 EstablishedTimings[3];
UINT8 StandardTimingIdentification[16];
UINT8 DetailedTimingDescriptions[72];
UINT8 EstablishedTimings[VESA_BIOS_EXTENSIONS_ESTABLISHED_TIMING_SIZE];
UINT8 StandardTimingIdentification[VESA_BIOS_EXTENSIONS_STANDARD_TIMING_SIZE];
UINT8 DetailedTimingDescriptions[VESA_BIOS_EXTENSIONS_DETAILED_TIMING_DESCRIPTOR_MAX_SIZE];
UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow
UINT8 Checksum;
} VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK;

View file

@ -682,6 +682,7 @@ LegacyBiosInstall (
LEGACY_BIOS_INSTANCE *Private;
EFI_TO_COMPATIBILITY16_INIT_TABLE *EfiToLegacy16InitTable;
EFI_PHYSICAL_ADDRESS MemoryAddress;
EFI_PHYSICAL_ADDRESS EbdaReservedBaseAddress;
VOID *MemoryPtr;
EFI_PHYSICAL_ADDRESS MemoryAddressUnder1MB;
UINTN Index;
@ -880,9 +881,21 @@ LegacyBiosInstall (
//
// Allocate all 32k chunks from 0x60000 ~ 0x88000 for Legacy OPROMs that
// don't use PMM but look for zeroed memory. Note that various non-BBS
// SCSIs expect different areas to be free
// OpROMs expect different areas to be free
//
for (MemStart = 0x60000; MemStart < 0x88000; MemStart += 0x1000) {
EbdaReservedBaseAddress = MemoryAddress;
MemoryAddress = PcdGet32 (PcdOpromReservedMemoryBase);
MemorySize = PcdGet32 (PcdOpromReservedMemorySize);
//
// Check if base address and size for reserved memory are 4KB aligned.
//
ASSERT ((MemoryAddress & 0xFFF) == 0);
ASSERT ((MemorySize & 0xFFF) == 0);
//
// Check if the reserved memory is below EBDA reserved range.
//
ASSERT ((MemoryAddress < EbdaReservedBaseAddress) && ((MemoryAddress + MemorySize - 1) < EbdaReservedBaseAddress));
for (MemStart = MemoryAddress; MemStart < MemoryAddress + MemorySize; MemStart += 0x1000) {
Status = AllocateLegacyMemory (
AllocateAddress,
MemStart,

View file

@ -140,6 +140,8 @@
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEndOpromShadowAddress
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLowPmmMemorySize
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdHighPmmMemorySize
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemoryBase
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemorySize
[Depex]
gEfiLegacyRegion2ProtocolGuid AND gEfiLegacyInterruptProtocolGuid AND gEfiLegacyBiosPlatformProtocolGuid AND gEfiLegacy8259ProtocolGuid AND gEfiGenericMemTestProtocolGuid AND gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid

View file

@ -1,6 +1,6 @@
/** @file
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -18,6 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <FrameworkDxe.h>
#include <IndustryStandard/Pci.h>
#include <Guid/SmBios.h>
#include <Guid/Acpi.h>
@ -134,6 +135,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define BDA_VIDEO_MODE 0x49
#define IDE_PI_REGISTER_PNE BIT0
#define IDE_PI_REGISTER_SNE BIT2
typedef struct {
UINTN PciSegment;
UINTN PciBus;
@ -1516,4 +1520,20 @@ InternalLegacyBiosFarCall (
IN UINTN StackSize
);
/**
Load a legacy PC-AT OpROM for VGA controller.
@param Private Driver private data.
@retval EFI_SUCCESS Legacy ROM successfully installed for this device.
@retval EFI_DEVICE_ERROR No VGA device handle found, or native EFI video
driver cannot be successfully disconnected, or VGA
thunk driver cannot be successfully connected.
**/
EFI_STATUS
LegacyBiosInstallVgaRom (
IN LEGACY_BIOS_INSTANCE *Private
);
#endif

View file

@ -268,9 +268,9 @@ InitLegacyIdeController (
)
{
EFI_PCI_IO_PROTOCOL *PciIo;
UINT8 Pi;
UINT32 IOBarClear;
EFI_STATUS Status;
PCI_TYPE00 PciData;
//
// If the IDE channel is in compatibility (legacy) mode, remove all
@ -279,21 +279,38 @@ InitLegacyIdeController (
// and has PCI I/O resources allocated
//
Status = gBS->HandleProtocol (
IdeController,
&gEfiPciIoProtocolGuid,
(VOID **) &PciIo
IdeController,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo
);
if (!EFI_ERROR (Status)) {
IOBarClear = 0x00;
PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 1, &Pi);
if ((Pi & 0x01) == 0) {
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &IOBarClear);
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x14, 1, &IOBarClear);
}
if ((Pi & 0x04) == 0) {
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x18, 1, &IOBarClear);
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1C, 1, &IOBarClear);
}
if (EFI_ERROR (Status)) {
return ;
}
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData);
if (EFI_ERROR (Status)) {
return ;
}
//
// Check whether this is IDE
//
if ((PciData.Hdr.ClassCode[2] != PCI_CLASS_MASS_STORAGE) ||
(PciData.Hdr.ClassCode[1] != PCI_CLASS_MASS_STORAGE_IDE)) {
return ;
}
//
// Clear bar for legacy IDE
//
IOBarClear = 0x00;
if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_PNE) == 0) {
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x10, 1, &IOBarClear);
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x14, 1, &IOBarClear);
}
if ((PciData.Hdr.ClassCode[0] & IDE_PI_REGISTER_SNE) == 0) {
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x18, 1, &IOBarClear);
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 0x1C, 1, &IOBarClear);
}
return ;

View file

@ -1,6 +1,6 @@
/** @file
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
@ -1715,6 +1715,20 @@ PciShadowRoms (
if (!EFI_ERROR (Status)) {
continue;
}
//
// If legacy VBIOS Oprom has not been dispatched before, install legacy VBIOS here.
//
if (IS_PCI_DISPLAY (&Pci) && Index == 0) {
Status = LegacyBiosInstallVgaRom (Private);
//
// A return status of EFI_NOT_FOUND is considered valid (No EFI
// driver is controlling video).
//
ASSERT ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND));
continue;
}
//
// Install legacy ROM
//

View file

@ -197,6 +197,19 @@
## The value should be a multiple of 4KB.
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdEbdaReservedMemorySize|0x8000|UINT32|0x30000005
## The PCD is used to specify memory base address for OPROM to find free memory.
# Some OPROMs do not use EBDA or PMM to allocate memory for its usage,
# instead they find the memory filled with zero from 0x20000.
# The value should be a multiple of 4KB.
# The range should be below the EBDA reserved range from
# (CONVENTIONAL_MEMORY_TOP - PcdEbdaReservedMemorySize) to CONVENTIONAL_MEMORY_TOP.
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemoryBase|0x60000|UINT32|0x3000000c
## The PCD is used to specify memory size with bytes for OPROM to find free memory.
## The value should be a multiple of 4KB. And the range should be below the EBDA reserved range from
# (CONVENTIONAL_MEMORY_TOP - PcdEbdaReservedMemorySize) to CONVENTIONAL_MEMORY_TOP.
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdOpromReservedMemorySize|0x28000|UINT32|0x3000000d
## The PCD is used to specify memory size with page number for a pre-allocated reserved memory to be used
# by PEI in S3 phase. The default size 32K. When changing the value of this PCD, the platform
# developer should make sure the memory size is large enough to meet PEI requiremnt in S3 phase.