OvmfPkg: Add CsmSupportLib

This library installs the legacy interrupt, region
and platform support required for CSM support
drivers.

Signed-off-by: jljusten
Reviewed-by: geekboy15a

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12681 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
jljusten 2011-11-10 22:04:19 +00:00
parent 09bb585cb2
commit 8016da21b5
12 changed files with 2326 additions and 0 deletions

View File

@ -0,0 +1,38 @@
/** @file
Platform CSM Support Library
Copyright (c) 2008 - 2011, Intel Corporation. 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 "CsmSupportLib.h"
/**
The constructor function for the platform CSM support library
@retval EFI_SUCCESS The constructor always returns RETURN_SUCCESS.
**/
RETURN_STATUS
EFIAPI
CsmSupportLibConstructor (
VOID
)
{
LegacyRegionInit ();
LegacyInterruptInstall ();
LegacyBiosPlatformInstall ();
return EFI_SUCCESS;
}

View File

@ -0,0 +1,55 @@
/** @file
Platform CSM Support Library
Copyright (c) 2008 - 2011, Intel Corporation. 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.
**/
#ifndef _CSM_SUPPORT_LIB_H_
#define _CSM_SUPPORT_LIB_H_
#include <Uefi.h>
/**
Initialize Legacy Region support
@retval EFI_SUCCESS Successfully initialized
**/
EFI_STATUS
LegacyRegionInit (
VOID
);
/**
Initialize Legacy Interrupt support
@retval EFI_SUCCESS Successfully initialized
**/
EFI_STATUS
LegacyInterruptInstall (
VOID
);
/**
Initialize Legacy Platform support
@retval EFI_SUCCESS Successfully initialized
**/
EFI_STATUS
LegacyBiosPlatformInstall (
VOID
);
#endif

View File

@ -0,0 +1,54 @@
## @file
# Platform CSM Support Library
#
# Copyright (c) 2008 - 2011, Intel Corporation. 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = CsmSupportLib
FILE_GUID = 04e03541-4663-417d-93f6-976378247d61
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = CsmSupportLib
CONSTRUCTOR = CsmSupportLibConstructor
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
CsmSupportLib.c
LegacyInterrupt.c
LegacyRegion.c
LegacyPlatform.c
[Packages]
MdePkg/MdePkg.dec
IntelFrameworkPkg/IntelFrameworkPkg.dec
[Protocols]
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDiskInfoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLegacyBiosPlatformProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLegacyBiosProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiLegacyInterruptProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiLegacyRegion2ProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiPciIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
[LibraryClasses]
BaseLib
PciLib
IoLib

View File

@ -0,0 +1,196 @@
/** @file
Legacy Interrupt Support
Copyright (c) 2006 - 2011, Intel Corporation. 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 "LegacyInterrupt.h"
//
// Handle for the Legacy Interrupt Protocol instance produced by this driver
//
STATIC EFI_HANDLE mLegacyInterruptHandle = NULL;
//
// The Legacy Interrupt Protocol instance produced by this driver
//
STATIC EFI_LEGACY_INTERRUPT_PROTOCOL mLegacyInterrupt = {
GetNumberPirqs,
GetLocation,
ReadPirq,
WritePirq
};
STATIC UINT8 PirqReg[MAX_PIRQ_NUMBER] = { PIRQA, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH };
/**
Return the number of PIRQs supported by this chipset.
@param[in] This Pointer to LegacyInterrupt Protocol
@param[out] NumberPirqs The pointer to return the max IRQ number supported
@retval EFI_SUCCESS Max PIRQs successfully returned
**/
EFI_STATUS
EFIAPI
GetNumberPirqs (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
OUT UINT8 *NumberPirqs
)
{
*NumberPirqs = MAX_PIRQ_NUMBER;
return EFI_SUCCESS;
}
/**
Return PCI location of this device.
$PIR table requires this info.
@param[in] This - Protocol instance pointer.
@param[out] Bus - PCI Bus
@param[out] Device - PCI Device
@param[out] Function - PCI Function
@retval EFI_SUCCESS Bus/Device/Function returned
**/
EFI_STATUS
EFIAPI
GetLocation (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
OUT UINT8 *Bus,
OUT UINT8 *Device,
OUT UINT8 *Function
)
{
*Bus = LEGACY_INT_BUS;
*Device = LEGACY_INT_DEV;
*Function = LEGACY_INT_FUNC;
return EFI_SUCCESS;
}
/**
Builds the PCI configuration address for the register specified by PirqNumber
@param[in] PirqNumber - The PIRQ number to build the PCI configuration address for
@return The PCI Configuration address for the PIRQ
**/
UINTN
GetAddress (
UINT8 PirqNumber
)
{
return PCI_LIB_ADDRESS(
LEGACY_INT_BUS,
LEGACY_INT_DEV,
LEGACY_INT_FUNC,
PirqReg[PirqNumber]
);
}
/**
Read the given PIRQ register
@param[in] This Protocol instance pointer
@param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
@param[out] PirqData Value read
@retval EFI_SUCCESS Decoding change affected.
@retval EFI_INVALID_PARAMETER Invalid PIRQ number
**/
EFI_STATUS
EFIAPI
ReadPirq (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
IN UINT8 PirqNumber,
OUT UINT8 *PirqData
)
{
if (PirqNumber >= MAX_PIRQ_NUMBER) {
return EFI_INVALID_PARAMETER;
}
*PirqData = PciRead8 (GetAddress (PirqNumber));
*PirqData = (UINT8) (*PirqData & 0x7f);
return EFI_SUCCESS;
}
/**
Write the given PIRQ register
@param[in] This Protocol instance pointer
@param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
@param[out] PirqData Value to write
@retval EFI_SUCCESS Decoding change affected.
@retval EFI_INVALID_PARAMETER Invalid PIRQ number
**/
EFI_STATUS
EFIAPI
WritePirq (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
IN UINT8 PirqNumber,
IN UINT8 PirqData
)
{
if (PirqNumber >= MAX_PIRQ_NUMBER) {
return EFI_INVALID_PARAMETER;
}
PciWrite8 (GetAddress (PirqNumber), PirqData);
return EFI_SUCCESS;
}
/**
Initialize Legacy Interrupt support
@retval EFI_SUCCESS Successfully initialized
**/
EFI_STATUS
LegacyInterruptInstall (
VOID
)
{
EFI_STATUS Status;
//
// Make sure the Legacy Interrupt Protocol is not already installed in the system
//
ASSERT_PROTOCOL_ALREADY_INSTALLED(NULL, &gEfiLegacyInterruptProtocolGuid);
//
// Make a new handle and install the protocol
//
Status = gBS->InstallMultipleProtocolInterfaces (
&mLegacyInterruptHandle,
&gEfiLegacyInterruptProtocolGuid,
&mLegacyInterrupt,
NULL
);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -0,0 +1,119 @@
/** @file
Legacy Region Support
Copyright (c) 2006 - 2011, Intel Corporation. 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.
**/
#ifndef _LEGACY_INTERRUPT_H_
#define _LEGACY_INTERRUPT_H_
#include <PiDxe.h>
#include <Protocol/LegacyInterrupt.h>
#include <Library/PciLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#define LEGACY_INT_BUS 0
#define LEGACY_INT_DEV 1
#define LEGACY_INT_FUNC 0
#define PIRQN 0x00 // PIRQ Null
#define PIRQA 0x60
#define PIRQB 0x61
#define PIRQC 0x62
#define PIRQD 0x63
#define PIRQE 0x68
#define PIRQF 0x69
#define PIRQG 0x6A
#define PIRQH 0x6B
#define MAX_PIRQ_NUMBER 8
/**
Return the number of PIRQs supported by this chipset.
@param[in] This Pointer to LegacyInterrupt Protocol
@param[out] NumberPirqs The pointer to return the max IRQ number supported
@retval EFI_SUCCESS Max PIRQs successfully returned
**/
EFI_STATUS
EFIAPI
GetNumberPirqs (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
OUT UINT8 *NumberPirqs
);
/**
Return PCI location of this device.
$PIR table requires this info.
@param[in] This - Protocol instance pointer.
@param[out] Bus - PCI Bus
@param[out] Device - PCI Device
@param[out] Function - PCI Function
@retval EFI_SUCCESS Bus/Device/Function returned
**/
EFI_STATUS
EFIAPI
GetLocation (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
OUT UINT8 *Bus,
OUT UINT8 *Device,
OUT UINT8 *Function
);
/**
Read the given PIRQ register
@param[in] This Protocol instance pointer
@param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
@param[out] PirqData Value read
@retval EFI_SUCCESS Decoding change affected.
@retval EFI_INVALID_PARAMETER Invalid PIRQ number
**/
EFI_STATUS
EFIAPI
ReadPirq (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
IN UINT8 PirqNumber,
OUT UINT8 *PirqData
);
/**
Write the given PIRQ register
@param[in] This Protocol instance pointer
@param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
@param[out] PirqData Value to write
@retval EFI_SUCCESS Decoding change affected.
@retval EFI_INVALID_PARAMETER Invalid PIRQ number
**/
EFI_STATUS
EFIAPI
WritePirq (
IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
IN UINT8 PirqNumber,
IN UINT8 PirqData
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
/** @file
Legacy BIOS Platform support
Copyright (c) 2006 - 2011, Intel Corporation. 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.
**/
#ifndef LEGACY_BIOS_PLATFORM_H_
#define LEGACY_BIOS_PLATFORM_H_
#include <FrameworkDxe.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LegacyInterrupt.h>
#include <Protocol/LegacyRegion2.h>
#include <Protocol/LegacyBiosPlatform.h>
#include <Protocol/FirmwareVolume.h>
#include <Protocol/DiskInfo.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/IoLib.h>
#include <Library/PciLib.h>
#include <Library/PcdLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/DevicePathLib.h>
#include <IndustryStandard/Pci.h>
//
// PIRQ information constants.
//
#define MAX_IRQ_ROUTING_ENTRIES 6
#define MAX_IRQ_PRIORITY_ENTRIES 7
#define V_INTEL_VENDOR_ID 0x8086
#define V_PIIX4_IDE_DEVICE_ID 0x7010
//
// Type declarations
//
typedef struct {
UINT8 SetupValue;
UINT16 DeviceType;
UINT8 Class;
UINT8 SubClass;
} EFI_SETUP_BBS_MAP;
typedef struct {
UINT8 Class;
UINT8 SubClass;
} PCI_CLASS_RECORD;
typedef struct {
EFI_LEGACY_PIRQ_TABLE_HEADER PirqTable;
EFI_LEGACY_IRQ_ROUTING_ENTRY IrqRoutingEntry[MAX_IRQ_ROUTING_ENTRIES];
} EFI_LEGACY_PIRQ_TABLE;
typedef struct {
EFI_HANDLE Handle;
UINT16 Vid;
UINT16 Did;
UINT16 SvId;
UINT16 SysId;
} DEVICE_STRUCTURE;
typedef struct {
EFI_GUID FileName;
UINTN Valid;
} SYSTEM_ROM_TABLE;
typedef struct {
UINT32 Signature;
EFI_HANDLE Handle;
EFI_LEGACY_BIOS_PLATFORM_PROTOCOL LegacyBiosPlatform;
EFI_HANDLE ImageHandle;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
} LEGACY_BIOS_PLATFORM_INSTANCE;
#define LEGACY_BIOS_PLATFORM_INSTANCE_SIGNATURE SIGNATURE_32('P','B','I','O')
#define LEGACY_BIOS_PLATFORM_INSTANCE_FROM_THIS(this) \
CR (this, \
LEGACY_BIOS_PLATFORM_INSTANCE, \
LegacyBiosPlatform, \
LEGACY_BIOS_PLATFORM_INSTANCE_SIGNATURE \
)
#endif

View File

@ -0,0 +1,466 @@
/** @file
Legacy Region Support
Copyright (c) 2006 - 2011, Intel Corporation. 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 "LegacyRegion.h"
//
// 440 PAM map.
//
// PAM Range Offset Bits Operation
// =============== ====== ==== ===============================================================
// 0xC0000-0xC3FFF 0x5a 1:0 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xC4000-0xC7FFF 0x5a 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xC8000-0xCBFFF 0x5b 1:0 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xCC000-0xCFFFF 0x5b 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xD0000-0xD3FFF 0x5c 1:0 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xD4000-0xD7FFF 0x5c 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xD8000-0xDBFFF 0x5d 1:0 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xDC000-0xDFFFF 0x5d 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xE0000-0xE3FFF 0x5e 1:0 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xE4000-0xE7FFF 0x5e 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xE8000-0xEBFFF 0x5f 1:0 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xEC000-0xEFFFF 0x5f 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
// 0xF0000-0xFFFFF 0x59 5:4 00 = DRAM Disabled, 01= Read Only, 10 = Write Only, 11 = Normal
//
STATIC LEGACY_MEMORY_SECTION_INFO mSectionArray[] = {
{0xC0000, SIZE_16KB, FALSE, FALSE},
{0xC4000, SIZE_16KB, FALSE, FALSE},
{0xC8000, SIZE_16KB, FALSE, FALSE},
{0xCC000, SIZE_16KB, FALSE, FALSE},
{0xD0000, SIZE_16KB, FALSE, FALSE},
{0xD4000, SIZE_16KB, FALSE, FALSE},
{0xD8000, SIZE_16KB, FALSE, FALSE},
{0xDC000, SIZE_16KB, FALSE, FALSE},
{0xE0000, SIZE_16KB, FALSE, FALSE},
{0xE4000, SIZE_16KB, FALSE, FALSE},
{0xE8000, SIZE_16KB, FALSE, FALSE},
{0xEC000, SIZE_16KB, FALSE, FALSE},
{0xF0000, SIZE_64KB, FALSE, FALSE}
};
STATIC PAM_REGISTER_VALUE mRegisterValues[] = {
{REG_PAM1_OFFSET, 0x01, 0x02},
{REG_PAM1_OFFSET, 0x10, 0x20},
{REG_PAM2_OFFSET, 0x01, 0x02},
{REG_PAM2_OFFSET, 0x10, 0x20},
{REG_PAM3_OFFSET, 0x01, 0x02},
{REG_PAM3_OFFSET, 0x10, 0x20},
{REG_PAM4_OFFSET, 0x01, 0x02},
{REG_PAM4_OFFSET, 0x10, 0x20},
{REG_PAM5_OFFSET, 0x01, 0x02},
{REG_PAM5_OFFSET, 0x10, 0x20},
{REG_PAM6_OFFSET, 0x01, 0x02},
{REG_PAM6_OFFSET, 0x10, 0x20},
{REG_PAM0_OFFSET, 0x10, 0x20}
};
//
// Handle used to install the Legacy Region Protocol
//
STATIC EFI_HANDLE mHandle = NULL;
//
// Instance of the Legacy Region Protocol to install into the handle database
//
STATIC EFI_LEGACY_REGION2_PROTOCOL mLegacyRegion2 = {
LegacyRegion2Decode,
LegacyRegion2Lock,
LegacyRegion2BootLock,
LegacyRegion2Unlock,
LegacyRegionGetInfo
};
STATIC
EFI_STATUS
LegacyRegionManipulationInternal (
IN UINT32 Start,
IN UINT32 Length,
IN BOOLEAN *ReadEnable,
IN BOOLEAN *WriteEnable,
OUT UINT32 *Granularity
)
{
UINT32 EndAddress;
UINTN Index;
UINTN StartIndex;
//
// Validate input parameters.
//
if (Length == 0 || Granularity == NULL) {
return EFI_INVALID_PARAMETER;
}
EndAddress = Start + Length - 1;
if ((Start < PAM_BASE_ADDRESS) || EndAddress > PAM_LIMIT_ADDRESS) {
return EFI_INVALID_PARAMETER;
}
//
// Loop to find the start PAM.
//
StartIndex = 0;
for (Index = 0; Index < (sizeof(mSectionArray) / sizeof (mSectionArray[0])); Index++) {
if ((Start >= mSectionArray[Index].Start) && (Start < (mSectionArray[Index].Start + mSectionArray[Index].Length))) {
StartIndex = Index;
break;
}
}
ASSERT (Index < (sizeof(mSectionArray) / sizeof (mSectionArray[0])));
//
// Program PAM until end PAM is encountered
//
for (Index = StartIndex; Index < (sizeof(mSectionArray) / sizeof (mSectionArray[0])); Index++) {
if (ReadEnable != NULL) {
if (*ReadEnable) {
PciOr8 (
PCI_LIB_ADDRESS(PAM_PCI_BUS, PAM_PCI_DEV, PAM_PCI_FUNC, mRegisterValues[Index].PAMRegOffset),
mRegisterValues[Index].ReadEnableData
);
} else {
PciAnd8 (
PCI_LIB_ADDRESS(PAM_PCI_BUS, PAM_PCI_DEV, PAM_PCI_FUNC, mRegisterValues[Index].PAMRegOffset),
(UINT8) (~mRegisterValues[Index].ReadEnableData)
);
}
}
if (WriteEnable != NULL) {
if (*WriteEnable) {
PciOr8 (
PCI_LIB_ADDRESS(PAM_PCI_BUS, PAM_PCI_DEV, PAM_PCI_FUNC, mRegisterValues[Index].PAMRegOffset),
mRegisterValues[Index].WriteEnableData
);
} else {
PciAnd8 (
PCI_LIB_ADDRESS(PAM_PCI_BUS, PAM_PCI_DEV, PAM_PCI_FUNC, mRegisterValues[Index].PAMRegOffset),
(UINT8) (~mRegisterValues[Index].WriteEnableData)
);
}
}
//
// If the end PAM is encountered, record its length as granularity and jump out.
//
if ((EndAddress >= mSectionArray[Index].Start) && (EndAddress < (mSectionArray[Index].Start + mSectionArray[Index].Length))) {
*Granularity = mSectionArray[Index].Length;
break;
}
}
ASSERT (Index < (sizeof(mSectionArray) / sizeof (mSectionArray[0])));
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
LegacyRegionGetInfoInternal (
OUT UINT32 *DescriptorCount,
OUT LEGACY_MEMORY_SECTION_INFO **Descriptor
)
{
UINTN Index;
UINT8 PamValue;
//
// Check input parameters
//
if (DescriptorCount == NULL || Descriptor == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Fill in current status of legacy region.
//
*DescriptorCount = sizeof(mSectionArray) / sizeof (mSectionArray[0]);
for (Index = 0; Index < *DescriptorCount; Index++) {
PamValue = PciRead8 (PCI_LIB_ADDRESS(PAM_PCI_BUS, PAM_PCI_DEV, PAM_PCI_FUNC, mRegisterValues[Index].PAMRegOffset));
mSectionArray[Index].ReadEnabled = FALSE;
if ((PamValue & mRegisterValues[Index].ReadEnableData) != 0) {
mSectionArray[Index].ReadEnabled = TRUE;
}
mSectionArray[Index].WriteEnabled = FALSE;
if ((PamValue & mRegisterValues[Index].WriteEnableData) != 0) {
mSectionArray[Index].WriteEnabled = TRUE;
}
}
*Descriptor = mSectionArray;
return EFI_SUCCESS;
}
/**
Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
If the On parameter evaluates to TRUE, this function enables memory reads in the address range
Start to (Start + Length - 1).
If the On parameter evaluates to FALSE, this function disables memory reads in the address range
Start to (Start + Length - 1).
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose attributes
should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address
was not aligned to a region's starting address or if the length
was greater than the number of bytes in the first region.
@param On[in] Decode / Non-Decode flag.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2Decode (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity,
IN BOOLEAN *On
)
{
return LegacyRegionManipulationInternal (Start, Length, On, NULL, Granularity);
}
/**
Modify the hardware to disallow memory attribute changes in a region.
This function makes the attributes of a region read only. Once a region is boot-locked with this
function, the read and write attributes of that region cannot be changed until a power cycle has
reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose
attributes should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address was
not aligned to a region's starting address or if the length was
greater than the number of bytes in the first region.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
@retval EFI_UNSUPPORTED The chipset does not support locking the configuration registers in
a way that will not affect memory regions outside the legacy memory
region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2BootLock (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity
)
{
if ((Start < 0xC0000) || ((Start + Length - 1) > 0xFFFFF)) {
return EFI_INVALID_PARAMETER;
}
return EFI_UNSUPPORTED;
}
/**
Modify the hardware to disallow memory writes in a region.
This function changes the attributes of a memory range to not allow writes.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose
attributes should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address was
not aligned to a region's starting address or if the length was
greater than the number of bytes in the first region.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2Lock (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity
)
{
BOOLEAN WriteEnable;
WriteEnable = FALSE;
return LegacyRegionManipulationInternal (Start, Length, NULL, &WriteEnable, Granularity);
}
/**
Modify the hardware to allow memory writes in a region.
This function changes the attributes of a memory range to allow writes.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose
attributes should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address was
not aligned to a region's starting address or if the length was
greater than the number of bytes in the first region.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2Unlock (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity
)
{
BOOLEAN WriteEnable;
WriteEnable = TRUE;
return LegacyRegionManipulationInternal (Start, Length, NULL, &WriteEnable, Granularity);
}
/**
Get region information for the attributes of the Legacy Region.
This function is used to discover the granularity of the attributes for the memory in the legacy
region. Each attribute may have a different granularity and the granularity may not be the same
for all memory ranges in the legacy region.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param DescriptorCount[out] The number of region descriptor entries returned in the Descriptor
buffer.
@param Descriptor[out] A pointer to a pointer used to return a buffer where the legacy
region information is deposited. This buffer will contain a list of
DescriptorCount number of region descriptors. This function will
provide the memory for the buffer.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegionGetInfo (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
OUT UINT32 *DescriptorCount,
OUT EFI_LEGACY_REGION_DESCRIPTOR **Descriptor
)
{
LEGACY_MEMORY_SECTION_INFO *SectionInfo;
UINT32 SectionCount;
EFI_LEGACY_REGION_DESCRIPTOR *DescriptorArray;
UINTN Index;
UINTN DescriptorIndex;
//
// Get section numbers and information
//
LegacyRegionGetInfoInternal (&SectionCount, &SectionInfo);
//
// Each section has 3 descriptors, corresponding to readability, writeability, and lock status.
//
DescriptorArray = AllocatePool (sizeof (EFI_LEGACY_REGION_DESCRIPTOR) * SectionCount * 3);
if (DescriptorArray == NULL) {
return EFI_OUT_OF_RESOURCES;
}
DescriptorIndex = 0;
for (Index = 0; Index < SectionCount; Index++) {
DescriptorArray[DescriptorIndex].Start = SectionInfo[Index].Start;
DescriptorArray[DescriptorIndex].Length = SectionInfo[Index].Length;
DescriptorArray[DescriptorIndex].Granularity = SectionInfo[Index].Length;
if (SectionInfo[Index].ReadEnabled) {
DescriptorArray[DescriptorIndex].Attribute = LegacyRegionDecoded;
} else {
DescriptorArray[DescriptorIndex].Attribute = LegacyRegionNotDecoded;
}
DescriptorIndex++;
//
// Create descriptor for writeability, according to lock status
//
DescriptorArray[DescriptorIndex].Start = SectionInfo[Index].Start;
DescriptorArray[DescriptorIndex].Length = SectionInfo[Index].Length;
DescriptorArray[DescriptorIndex].Granularity = SectionInfo[Index].Length;
if (SectionInfo[Index].WriteEnabled) {
DescriptorArray[DescriptorIndex].Attribute = LegacyRegionWriteEnabled;
} else {
DescriptorArray[DescriptorIndex].Attribute = LegacyRegionWriteDisabled;
}
DescriptorIndex++;
//
// Chipset does not support bootlock.
//
DescriptorArray[DescriptorIndex].Start = SectionInfo[Index].Start;
DescriptorArray[DescriptorIndex].Length = SectionInfo[Index].Length;
DescriptorArray[DescriptorIndex].Granularity = SectionInfo[Index].Length;
DescriptorArray[DescriptorIndex].Attribute = LegacyRegionNotLocked;
DescriptorIndex++;
}
*DescriptorCount = (UINT32) DescriptorIndex;
*Descriptor = DescriptorArray;
return EFI_SUCCESS;
}
/**
Initialize Legacy Region support
@retval EFI_SUCCESS Successfully initialized
**/
EFI_STATUS
LegacyRegionInit (
VOID
)
{
EFI_STATUS Status;
//
// Install the Legacy Region Protocol on a new handle
//
Status = gBS->InstallMultipleProtocolInterfaces (
&mHandle,
&gEfiLegacyRegion2ProtocolGuid, &mLegacyRegion2,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -0,0 +1,219 @@
/** @file
Legacy Region Support
Copyright (c) 2008 - 2011, Intel Corporation. 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.
**/
#ifndef _LEGACY_REGION_DXE_H_
#define _LEGACY_REGION_DXE_H_
#include <PiDxe.h>
#include <Protocol/LegacyRegion2.h>
#include <IndustryStandard/Pci.h>
#include <Library/PciLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#define PAM_PCI_BUS 0
#define PAM_PCI_DEV 0
#define PAM_PCI_FUNC 0
#define REG_PAM0_OFFSET 0x59 // Programmable Attribute Map 0
#define REG_PAM1_OFFSET 0x5a // Programmable Attribute Map 1
#define REG_PAM2_OFFSET 0x5b // Programmable Attribute Map 2
#define REG_PAM3_OFFSET 0x5c // Programmable Attribute Map 3
#define REG_PAM4_OFFSET 0x5d // Programmable Attribute Map 4
#define REG_PAM5_OFFSET 0x5e // Programmable Attribute Map 5
#define REG_PAM6_OFFSET 0x5f // Programmable Attribute Map 6
#define PAM_BASE_ADDRESS 0xc0000
#define PAM_LIMIT_ADDRESS BASE_1MB
//
// Describes Legacy Region blocks and status.
//
typedef struct {
UINT32 Start;
UINT32 Length;
BOOLEAN ReadEnabled;
BOOLEAN WriteEnabled;
} LEGACY_MEMORY_SECTION_INFO;
//
// Provides a map of the PAM registers and bits used to set Read/Write access.
//
typedef struct {
UINT8 PAMRegOffset;
UINT8 ReadEnableData;
UINT8 WriteEnableData;
} PAM_REGISTER_VALUE;
/**
Modify the hardware to allow (decode) or disallow (not decode) memory reads in a region.
If the On parameter evaluates to TRUE, this function enables memory reads in the address range
Start to (Start + Length - 1).
If the On parameter evaluates to FALSE, this function disables memory reads in the address range
Start to (Start + Length - 1).
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose attributes
should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address
was not aligned to a region's starting address or if the length
was greater than the number of bytes in the first region.
@param On[in] Decode / Non-Decode flag.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2Decode (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity,
IN BOOLEAN *On
);
/**
Modify the hardware to disallow memory writes in a region.
This function changes the attributes of a memory range to not allow writes.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose
attributes should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address was
not aligned to a region's starting address or if the length was
greater than the number of bytes in the first region.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2Lock (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity
);
/**
Modify the hardware to disallow memory attribute changes in a region.
This function makes the attributes of a region read only. Once a region is boot-locked with this
function, the read and write attributes of that region cannot be changed until a power cycle has
reset the boot-lock attribute. Calls to Decode(), Lock() and Unlock() will have no effect.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose
attributes should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address was
not aligned to a region's starting address or if the length was
greater than the number of bytes in the first region.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
@retval EFI_UNSUPPORTED The chipset does not support locking the configuration registers in
a way that will not affect memory regions outside the legacy memory
region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2BootLock (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity
);
/**
Modify the hardware to allow memory writes in a region.
This function changes the attributes of a memory range to allow writes.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param Start[in] The beginning of the physical address of the region whose
attributes should be modified.
@param Length[in] The number of bytes of memory whose attributes should be modified.
The actual number of bytes modified may be greater than the number
specified.
@param Granularity[out] The number of bytes in the last region affected. This may be less
than the total number of bytes affected if the starting address was
not aligned to a region's starting address or if the length was
greater than the number of bytes in the first region.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegion2Unlock (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
IN UINT32 Start,
IN UINT32 Length,
OUT UINT32 *Granularity
);
/**
Get region information for the attributes of the Legacy Region.
This function is used to discover the granularity of the attributes for the memory in the legacy
region. Each attribute may have a different granularity and the granularity may not be the same
for all memory ranges in the legacy region.
@param This[in] Indicates the EFI_LEGACY_REGION_PROTOCOL instance.
@param DescriptorCount[out] The number of region descriptor entries returned in the Descriptor
buffer.
@param Descriptor[out] A pointer to a pointer used to return a buffer where the legacy
region information is deposited. This buffer will contain a list of
DescriptorCount number of region descriptors. This function will
provide the memory for the buffer.
@retval EFI_SUCCESS The region's attributes were successfully modified.
@retval EFI_INVALID_PARAMETER If Start or Length describe an address not in the Legacy Region.
**/
EFI_STATUS
EFIAPI
LegacyRegionGetInfo (
IN EFI_LEGACY_REGION2_PROTOCOL *This,
OUT UINT32 *DescriptorCount,
OUT EFI_LEGACY_REGION_DESCRIPTOR **Descriptor
);
#endif

View File

@ -322,6 +322,9 @@
IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf {
<LibraryClasses>
TimerLib|OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!ifdef $(CSM_ENABLE)
NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
!endif
}
OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf

View File

@ -324,6 +324,9 @@
IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf {
<LibraryClasses>
TimerLib|OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!ifdef $(CSM_ENABLE)
NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
!endif
}
OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf

View File

@ -323,6 +323,9 @@
IntelFrameworkModulePkg/Universal/BdsDxe/BdsDxe.inf {
<LibraryClasses>
TimerLib|OvmfPkg/Library/AcpiTimerLib/AcpiTimerLib.inf
!ifdef $(CSM_ENABLE)
NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
!endif
}
OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf