get the pmbase from the BIOS resource list

When the STM is setup by the BIOS, the pmbase is placed in the
BIOS resource list.  The pmbase value is obtained by calling the
platform's setup function and is the first item in the IO address
section of the BIOS resource list.
This commit is contained in:
Eugene D Myers 2020-04-27 17:34:33 -04:00
parent 901a32ecf8
commit a1227fed88
4 changed files with 74 additions and 16 deletions

View File

@ -1270,7 +1270,6 @@ LaunchBack (
**/
extern void PrintSmiEnRegister(UINT32 Index); // found in PcPciHandler.c
VOID
InitializeSmmMonitor (
IN X86_REGISTER *Register
@ -1289,13 +1288,11 @@ InitializeSmmMonitor (
Index = GetIndexFromStack (Register);
ApInit (Index, Register);
}
//PrintSmiEnRegister(Index); /* debug*/
CommonInit (Index);
VmcsInit (Index);
//
PrintSmiEnRegister(Index); /* DEBUG*/
AsmWbinvd(); // flush caches
LaunchBack (Index);
return ;

View File

@ -52,6 +52,9 @@ void SetTimerRate(UINT16 value);
(((DEV) & 0x1F) << 15) | \
(((FN) & 0x07) <<12))
void PrintSmiEnRegister(UINT32 Index);
extern STM_GUEST_CONTEXT_COMMON mGuestContextCommonSmm[];
typedef int device_t;
static UINT16 pmbase = 0x0;
@ -106,7 +109,25 @@ static device_t get_pcu_dev(void)
UINT16 get_pmbase(void)
{
return pcie_read_config16(get_pcu_dev(), D31F0_PMBASE ) & 0xFFF8;
if (pmbase == 0)
{
// find the pmbase in the BIOS resource list
STM_RSC *Resource;
// the pmbase is the first IO resource
Resource = GetStmFirstResource (
(STM_RSC *)mGuestContextCommonSmm[SMI_HANDLER].BiosHwResourceRequirementsPtr,
IO_RANGE);
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));
}
}
return pmbase;
}
void StartTimer(void)
@ -117,7 +138,6 @@ void StartTimer(void)
smi_en |= PERIODIC_EN;
//DEBUG((EFI_D_INFO, "-- StartSwTimer pmbase: %x smi_en: %x \n", pmbase, smi_en));
DEBUG((EFI_D_INFO,
"StartTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n",
smi_en,
@ -133,11 +153,8 @@ void SetEndOfSmi(void)
UINT32 smi_en = IoRead32(pmbase + SMI_EN);
smi_en |= EOS_EN; // set the bit
//DEBUG((EFI_D_DEBUG, "-- StartSwTimer pmbase: %x smi_en: %x \n", pmbase, smi_en));
//DEBUG((EFI_D_DEBUG, "-- SW Timer Started - smi_en: 0x%08lx smi_sts: 0x%08lx\n", smi_en, smi_sts));
IoWrite32(pmbase + SMI_EN, smi_en);
DEBUG((EFI_D_ERROR, "SetEndOfSmi smi_en: 0x%08lx smi_sts: 0x%08lx\n", IoRead32(pmbase + SMI_EN), IoRead32(pmbase + SMI_STS)));
//DEBUG((EFI_D_INFO, "SetEndOfSmi smi_en: 0x%08lx smi_sts: 0x%08lx\n", IoRead32(pmbase + SMI_EN), IoRead32(pmbase + SMI_STS)));
}
@ -170,12 +187,6 @@ void StopSwTimer(void)
smi_en &= ~PERIODIC_EN;
IoWrite32(pmbase + SMI_EN, smi_en);
//DEBUG((EFI_D_INFO, "-- SW Timer Stopped - pre-smi_en %x post-smi_en: %x\n", pre_smi_en, post_smi_en));
DEBUG((EFI_D_INFO,
"StopSwTimer - smi_en: 0x%08lx smi_sts: 0x%08lx\n",
IoRead32(pmbase + SMI_EN),
IoRead32(pmbase + SMI_STS)));
}
int CheckTimerSTS(UINT32 Index)
@ -195,7 +206,6 @@ int CheckTimerSTS(UINT32 Index)
}
else
{
//DEBUG((EFI_D_DEBUG, "%ld CheckTimerSTS - No Timer Interrupt Detected\n", Index, smi_sts));
return 0;
}
}

View File

@ -569,6 +569,23 @@ VOID
RegisterBiosResource (
IN STM_RSC *Resource
);
/**^M
^M
This function returns the first STM resource of resource type.^M
^M
@param Resource STM resource list^M
@param RscType resource type
^M
@return STM resource^M
^M
**/
STM_RSC *
GetStmFirstResource (
IN STM_RSC *Resource,
IN UINT16 RscType
);
/**
@ -616,6 +633,7 @@ LookupSmiGuestVirtualToGuestPhysical (
@retval TRUE HostPhysicalAddress is found
@retval FALSE HostPhysicalAddress is not found
**/
BOOLEAN
LookupSmiGuestPhysicalToHostPhysical (

View File

@ -1922,4 +1922,37 @@ RegisterBiosResource (
RegisterBiosResource ((STM_RSC *)(UINTN)Resource->End.ResourceListContinuation);
}
}
/**^M
^M
This function returns the first STM resource of resource type.^M
^M
@param Resource STM resource list^M
@param RscType resource type
^M
@return STM resource^M
^M
**/
STM_RSC *
GetStmFirstResource (
IN STM_RSC *Resource,
IN UINT16 RscType
)
{
if (Resource == NULL) {
return NULL;
}
while (Resource->Header.RscType != END_OF_RESOURCES) {
if ((Resource->Header.IgnoreResource == 0) &&
(Resource->Header.RscType == RscType)) {
return Resource;
}
Resource = (STM_RSC *)((UINTN)Resource + Resource->Header.Length);
}
if (Resource->End.ResourceListContinuation != 0) {
return GetStmFirstResource ((STM_RSC *)(UINTN)Resource->End.ResourceListContinuation, RscType);
}
return NULL;
}