mirror of https://review.coreboot.org/STM.git
Allow options for the PMBASE (ACPI Base Address)
How this value is determined is dependent on the platform. This patch allows the developer to manually set the address; get it from the BIOS resource list, which is set during initialization by coreboot; or read it from the chipset registers. Signed-off-by: Eugene D. Myers <edmyers@tycho.nsa.gov>
This commit is contained in:
parent
65bd757686
commit
396e497f38
|
@ -5,6 +5,7 @@ project(stm C ASM)
|
|||
|
||||
if("${BIOS}" STREQUAL "coreboot")
|
||||
add_definitions( -DCOREBOOT32 )
|
||||
add_definitions( -DPMBASE_BIOS_RESOURCE )
|
||||
message("Building for Coreboot")
|
||||
endif()
|
||||
|
||||
|
@ -40,6 +41,10 @@ if("${STMPE_ENABLED}")
|
|||
message("STM/PE Enabled")
|
||||
endif()
|
||||
|
||||
if("${PMBASE}")
|
||||
add_definitions( -DCONFIG_PMBASE=${PMBASE} )
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Xlinker -Map=stm.map -Xlinker --build-id=none -Xlinker --no-dynamic-linker -Xlinker --noinhibit-exec -Os -falign-functions -ffreestanding -s -pie --entry _ModuleEntryPoint -u _ModuleEntryPoint -nostdlib -n -z common-page-size=0x40 -fno-asynchronous-unwind-tables -fno-jump-tables -fPIC -fno-stack-protector -fno-stack-check -include PcdData.h -T ${PROJECT_SOURCE_DIR}/StmPkg/Core/Stm.lds")
|
||||
|
||||
set(CMAKE_ASM_FLAGS "-include BaseAsm.h -fPIC")
|
||||
|
|
|
@ -14,21 +14,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
|
||||
#include "StmRuntime.h"
|
||||
#include "PeStm.h"
|
||||
#include "Library/PciExpressLib.h"
|
||||
|
||||
void SetTimerRate(UINT16 value);
|
||||
|
||||
// interval timer support
|
||||
|
||||
//#define CONFIG_MMCONF_BASE_ADDRESS 0xF8000000///
|
||||
//#define DEFAULT_PCIEXBAR CONFIG_MMCONF_BASE_ADDRESS // frm sandybridge.h
|
||||
|
||||
|
||||
// from pci_devs.h
|
||||
#define PCU_DEV 0x1F
|
||||
|
||||
// from lcp.h
|
||||
|
||||
/* D30:F0 LPC bridge */
|
||||
#define D31F0_PMBASE 0x40
|
||||
#define D31F0_GEN_PMCON_1 0xA0
|
||||
#define D31F0_GEN_PMCON_3 0xA4
|
||||
|
@ -45,72 +34,25 @@ void SetTimerRate(UINT16 value);
|
|||
#define SWSMI_TMR_STS (1<<6)
|
||||
#define PERIODIC_STS (1<<14)
|
||||
|
||||
|
||||
// from arch/io.h
|
||||
#define PCI_DEV(SEGBUS, DEV, FN) ( \
|
||||
(((SEGBUS) & 0xFFF) << 20) | \
|
||||
(((DEV) & 0x1F) << 15) | \
|
||||
(((FN) & 0x07) <<12))
|
||||
|
||||
void PrintSmiEnRegister(UINT32 Index);
|
||||
void PrintSmiEnRegister (UINT32 Index);
|
||||
extern STM_GUEST_CONTEXT_COMMON mGuestContextCommonSmm[];
|
||||
|
||||
typedef int device_t;
|
||||
|
||||
static UINT16 pmbase = 0x0;
|
||||
|
||||
static UINT16 read16(UINTN addr)
|
||||
{
|
||||
return *((volatile UINT16 *) (addr));
|
||||
}
|
||||
|
||||
static void write16(UINTN addr, UINT16 Reg16)
|
||||
{
|
||||
*((volatile UINT16 *) (addr)) = Reg16;
|
||||
}
|
||||
|
||||
static UINT32 read32(UINTN addr)
|
||||
{
|
||||
return *((volatile UINT32 *) (addr));
|
||||
}
|
||||
|
||||
static UINT16 pcie_read_config16(device_t dev, unsigned int whereat)
|
||||
{
|
||||
UINTN addr;
|
||||
|
||||
addr = ((UINTN) mHostContextCommon.PciExpressBaseAddress) | dev | whereat;
|
||||
//DEBUG((EFI_D_DEBUG, "pcie_read_config16 %x\n", addr));
|
||||
return read16(addr);
|
||||
}
|
||||
|
||||
static UINT32 pcie_read_config32(device_t dev, unsigned int whereat)
|
||||
{
|
||||
UINTN addr;
|
||||
|
||||
addr = ((UINTN) mHostContextCommon.PciExpressBaseAddress) | dev | whereat;
|
||||
//DEBUG((EFI_D_DEBUG, "pcie_read_config32 %x\n", addr));
|
||||
return read32(addr);
|
||||
}
|
||||
|
||||
static void pcie_write_config16(device_t dev, unsigned int whereat, UINT16 Reg16)
|
||||
{
|
||||
UINTN addr;
|
||||
|
||||
addr = ((UINTN) mHostContextCommon.PciExpressBaseAddress) | dev | whereat;
|
||||
write16(addr, Reg16);
|
||||
return;
|
||||
}
|
||||
|
||||
static device_t get_pcu_dev(void)
|
||||
{
|
||||
//DEBUG((EFI_D_DEBUG, "get_pcu_dev - return %x\n", PCI_DEV(0, PCU_DEV, 0)));
|
||||
return PCI_DEV(0, PCU_DEV, 0);
|
||||
}
|
||||
|
||||
UINT16 get_pmbase(void)
|
||||
UINT16 get_pmbase (void)
|
||||
{
|
||||
if (pmbase == 0)
|
||||
{
|
||||
#ifdef CONFIG_PMBASE
|
||||
pmbase = CONFIG_PMBASE;
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"get_pmbase - (from CONFIG_PMBASE) set at 0x%x\n",
|
||||
pmbase));
|
||||
#else
|
||||
#ifdef PMBASE_BIOS_RESOURCE
|
||||
// find the pmbase in the BIOS resource list
|
||||
|
||||
STM_RSC *Resource;
|
||||
|
@ -119,20 +61,39 @@ UINT16 get_pmbase(void)
|
|||
Resource = GetStmFirstResource (
|
||||
(STM_RSC *)mGuestContextCommonSmm[SMI_HANDLER].BiosHwResourceRequirementsPtr,
|
||||
IO_RANGE);
|
||||
if(Resource == NULL)
|
||||
DEBUG((EFI_D_ERROR,
|
||||
if (Resource == NULL)
|
||||
DEBUG ((EFI_D_ERROR,
|
||||
"get_pmbase - Error pmbase not found in resource list\n"));
|
||||
else
|
||||
{
|
||||
pmbase = Resource->Io.Base;
|
||||
DEBUG((EFI_D_INFO,
|
||||
"get_pmbase - pmbase set at 0x%x\n", pmbase));
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"get_pmbase - (from BIOS RSC) pmbase set at 0x%x\n",
|
||||
pmbase));
|
||||
}
|
||||
}
|
||||
#else
|
||||
pmbase = PciExpressRead16 (PCI_EXPRESS_LIB_ADDRESS (0, 0x1f, 0, D31F0_PMBASE));
|
||||
|
||||
if ((pmbase & 0x1) != 0x1)
|
||||
{
|
||||
DEBUG((EFI_D_ERROR,
|
||||
"get_pmbase - Error in pmbase value: 0x%x\n",
|
||||
pmbase));
|
||||
pmbase = 0;
|
||||
}
|
||||
|
||||
pmbase &= 0xFFFC;
|
||||
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"get_pmbase - (from PCI Memory) pmbase set at 0x%x\n",
|
||||
pmbase));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return pmbase;
|
||||
}
|
||||
|
||||
void StartTimer(void)
|
||||
void StartTimer (void)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
|
@ -140,66 +101,65 @@ void StartTimer(void)
|
|||
|
||||
smi_en |= PERIODIC_EN;
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"StartTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n",
|
||||
smi_en,
|
||||
smi_sts));
|
||||
#endif
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
IoWrite32 (pmbase + SMI_STS, PERIODIC_STS);
|
||||
IoWrite32 (pmbase + SMI_EN, smi_en);
|
||||
}
|
||||
|
||||
void SetEndOfSmi(void)
|
||||
void SetEndOfSmi (void)
|
||||
{
|
||||
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
UINT16 pmbase = get_pmbase ();
|
||||
UINT32 smi_en = IoRead32 (pmbase + SMI_EN);
|
||||
smi_en |= EOS_EN; // set the bit
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"-- SetEndOfSmi pmbase: %x smi_en: %x \n",
|
||||
pmbase,
|
||||
smi_en));
|
||||
#endif
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
IoWrite32 (pmbase + SMI_EN, smi_en);
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"SetEndOfSmi smi_en: 0x%08lx smi_sts: 0x%08lx\n",
|
||||
IoRead32(pmbase + SMI_EN),
|
||||
IoRead32(pmbase + SMI_STS)));
|
||||
IoRead32 (pmbase + SMI_EN),
|
||||
IoRead32 (pmbase + SMI_STS)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintSmiEnRegister(UINT32 Index)
|
||||
void PrintSmiEnRegister (UINT32 Index)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
DEBUG((EFI_D_INFO,
|
||||
UINT16 pmbase = get_pmbase ();
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"%ld PrintSmiEnRegister smi_en: 0x%08x smi_sts: 0x%08x\n",
|
||||
Index,
|
||||
IoRead32(pmbase + SMI_EN),
|
||||
IoRead32(pmbase + SMI_STS)));
|
||||
IoRead32 (pmbase + SMI_EN),
|
||||
IoRead32 (pmbase + SMI_STS)));
|
||||
}
|
||||
|
||||
void AckTimer(void)
|
||||
void AckTimer (void)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
UINT16 pmbase = get_pmbase ();
|
||||
|
||||
IoWrite32 (pmbase + SMI_STS, PERIODIC_STS);
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"AckTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n",
|
||||
IoRead32(pmbase + SMI_EN),
|
||||
IoRead32(pmbase + SMI_STS)));
|
||||
IoRead32 (pmbase + SMI_EN),
|
||||
IoRead32 (pmbase + SMI_STS)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void StopSwTimer(void)
|
||||
void StopSwTimer (void)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
UINT16 pmbase = get_pmbase ();
|
||||
UINT32 smi_en = IoRead32 (pmbase + SMI_EN);
|
||||
|
||||
smi_en &= ~PERIODIC_EN;
|
||||
IoWrite32(pmbase + SMI_EN, smi_en);
|
||||
IoWrite32 (pmbase + SMI_EN, smi_en);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -213,21 +173,21 @@ void StopSwTimer(void)
|
|||
* 2 - Timer interrupt plus additional SMI
|
||||
*/
|
||||
|
||||
int CheckTimerSTS(UINT32 Index)
|
||||
int CheckTimerSTS (UINT32 Index)
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT32 smi_sts = IoRead32(pmbase + SMI_STS);
|
||||
UINT16 pmbase = get_pmbase ();
|
||||
UINT32 smi_sts = IoRead32 (pmbase + SMI_STS);
|
||||
#if 0
|
||||
DEBUG((EFI_D_ERROR, "%ld CheckTimerSTS - 0x%08lx\n", Index, smi_sts));
|
||||
#endif
|
||||
if((smi_sts & PERIODIC_STS) == PERIODIC_STS)
|
||||
if ((smi_sts & PERIODIC_STS) == PERIODIC_STS)
|
||||
{
|
||||
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
|
||||
UINT32 smi_en = IoRead32 (pmbase + SMI_EN);
|
||||
UINT32 other_smi = (smi_en & smi_sts) & ~PERIODIC_STS;
|
||||
|
||||
if(other_smi == 0)
|
||||
if (other_smi == 0)
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - Timer Interrupt Detected\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
|
@ -235,7 +195,7 @@ int CheckTimerSTS(UINT32 Index)
|
|||
}
|
||||
else
|
||||
{
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - Timer + other SMI found\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
|
@ -245,7 +205,7 @@ int CheckTimerSTS(UINT32 Index)
|
|||
else
|
||||
{
|
||||
#if 0
|
||||
DEBUG((EFI_D_INFO,
|
||||
DEBUG ((EFI_D_INFO,
|
||||
"%ld CheckTimerSTS - No Timer Interrupt Detected\n",
|
||||
Index,
|
||||
smi_sts));
|
||||
|
@ -254,36 +214,35 @@ int CheckTimerSTS(UINT32 Index)
|
|||
}
|
||||
}
|
||||
|
||||
void ClearTimerSTS()
|
||||
void ClearTimerSTS ()
|
||||
{
|
||||
UINT16 pmbase = get_pmbase();
|
||||
UINT16 pmbase = get_pmbase ();
|
||||
|
||||
// just want to clear the status - do not touch the rest
|
||||
IoWrite32(pmbase + SMI_STS, PERIODIC_STS);
|
||||
IoWrite32 (pmbase + SMI_STS, PERIODIC_STS);
|
||||
}
|
||||
|
||||
void SetMaxSwTimerInt()
|
||||
void SetMaxSwTimerInt ()
|
||||
{
|
||||
SetTimerRate(3);
|
||||
SetTimerRate (0);
|
||||
}
|
||||
|
||||
void SetMinSwTimerInt()
|
||||
void SetMinSwTimerInt ()
|
||||
{
|
||||
SetTimerRate(0);
|
||||
SetTimerRate (3);
|
||||
}
|
||||
|
||||
void SetTimerRate(UINT16 value)
|
||||
void SetTimerRate (UINT16 value)
|
||||
{
|
||||
UINT16 Reg16;
|
||||
UINT16 TimeOut;
|
||||
device_t PcuDev = get_pcu_dev();
|
||||
|
||||
if( value > 3)
|
||||
if (value > 3)
|
||||
{
|
||||
value = 3;
|
||||
}
|
||||
TimeOut = (value << 0);
|
||||
|
||||
Reg16 = pcie_read_config16(PcuDev, D31F0_GEN_PMCON_1);
|
||||
pcie_write_config16(PcuDev, D31F0_GEN_PMCON_1, Reg16|TimeOut);
|
||||
Reg16 = PciExpressRead16 (PCI_EXPRESS_LIB_ADDRESS (0, 0x1f, 0, D31F0_GEN_PMCON_1));
|
||||
PciExpressWrite16 (PCI_EXPRESS_LIB_ADDRESS (0, 0x1f, 0, D31F0_GEN_PMCON_1), Reg16|TimeOut);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue