diff --git a/MdeModulePkg/Application/UiApp/FrontPage.c b/MdeModulePkg/Application/UiApp/FrontPage.c index b9b0cdf545..e43a0f0f9c 100644 --- a/MdeModulePkg/Application/UiApp/FrontPage.c +++ b/MdeModulePkg/Application/UiApp/FrontPage.c @@ -7,6 +7,10 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include +#include +#include + #include "FrontPage.h" #include "FrontPageCustomizedUi.h" @@ -33,6 +37,8 @@ UINT32 mSetupTextModeRow = 0; UINT32 mSetupHorizontalResolution = 0; UINT32 mSetupVerticalResolution = 0; +EFI_SYSTEM_TABLE * gSystemTable = NULL; + FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = { FRONT_PAGE_CALLBACK_DATA_SIGNATURE, NULL, @@ -564,6 +570,216 @@ WarnNoBootableMedia ( FreePool(String); } +BOOLEAN +StandardSignatureIsAuthenticAMD ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx == CPUID_SIGNATURE_AUTHENTIC_AMD_EBX && + RegEcx == CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx == CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); +} + +BOOLEAN +StandardSignatureIsGenuineIntel ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid (CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx == CPUID_SIGNATURE_GENUINE_INTEL_EBX && + RegEcx == CPUID_SIGNATURE_GENUINE_INTEL_ECX && + RegEdx == CPUID_SIGNATURE_GENUINE_INTEL_EDX); +} + +typedef struct { + CHAR8 Signature[8]; + UINT8 Checksum; + CHAR8 OemId[6]; + UINT8 Revision; + UINT32 RsdtAddress; +} ACPI_RSDP; + +CHAR8 RSDP_SIGNATURE[8] = {'R', 'S', 'D', ' ', 'P', 'T', 'R', ' '}; + +typedef struct { + CHAR8 Signature[4]; + UINT32 Length; + UINT8 Revision; + UINT8 Checksum; + CHAR8 OemId[6]; + CHAR8 OemTableId[8]; + UINT32 OemRevision; + UINT32 CreatorId; + UINT32 CreatorRevision; +} ACPI_SDT_HEADER; + +CHAR8 RSDT_SIGNATURE[4] = {'R', 'S', 'D', 'T'}; + +STATIC ACPI_SDT_HEADER* FindAcpiTable(CHAR8 Name[4]) { + UINTN Index; + EFI_CONFIGURATION_TABLE* ConfigurationTable; + UINTN RsdpPtr; + ACPI_RSDP* Rsdp; + UINTN RsdtPtr; + ACPI_SDT_HEADER* Rsdt; + UINTN TablePtr; + ACPI_SDT_HEADER* Table; + + DEBUG ((EFI_D_INFO, "FindAcpiTable: '%c%c%c%c'\n", + Name[0], + Name[1], + Name[2], + Name[3] + )); + + if (gSystemTable == NULL) { + DEBUG ((EFI_D_INFO, " System Table missing\n")); + return NULL; + } + + // Search the table for an entry that matches the ACPI Table Guid + for (Index = 0; Index < gSystemTable->NumberOfTableEntries; Index++) { + if (CompareGuid (&gEfiAcpiTableGuid, &(gSystemTable->ConfigurationTable[Index].VendorGuid))) { + ConfigurationTable = &gSystemTable->ConfigurationTable[Index]; + break; + } + } + + if (ConfigurationTable == NULL) { + DEBUG ((EFI_D_INFO, " ACPI Configuration Table missing\n")); + return NULL; + } + + RsdpPtr = (UINTN)ConfigurationTable->VendorTable; + DEBUG ((EFI_D_INFO, " RSDP 0x%x\n", RsdpPtr)); + Rsdp = (ACPI_RSDP*)RsdpPtr; + DEBUG ((EFI_D_INFO, " Signature: '%c%c%c%c%c%c%c%c'\n", + Rsdp->Signature[0], + Rsdp->Signature[1], + Rsdp->Signature[2], + Rsdp->Signature[3], + Rsdp->Signature[4], + Rsdp->Signature[5], + Rsdp->Signature[6], + Rsdp->Signature[7] + )); + if (CompareMem(Rsdp->Signature, RSDP_SIGNATURE, 8) != 0) { + DEBUG ((EFI_D_INFO, " RSDP invalid signature\n")); + return NULL; + } + DEBUG ((EFI_D_INFO, " Revision: 0x%x\n", Rsdp->Revision)); + + RsdtPtr = (UINTN)Rsdp->RsdtAddress; + DEBUG ((EFI_D_INFO, " RSDT 0x%x\n", RsdpPtr)); + Rsdt = (ACPI_SDT_HEADER*)RsdtPtr; + DEBUG ((EFI_D_INFO, " Signature: '%c%c%c%c'\n", + Rsdt->Signature[0], + Rsdt->Signature[1], + Rsdt->Signature[2], + Rsdt->Signature[3] + )); + if (CompareMem(Rsdt->Signature, RSDT_SIGNATURE, 4) != 0) { + DEBUG ((EFI_D_INFO, " RSDT invalid signature\n")); + return NULL; + } + DEBUG ((EFI_D_INFO, " Revision: 0x%x\n", Rsdt->Revision)); + DEBUG ((EFI_D_INFO, " Length: 0x%x\n", Rsdt->Length)); + + for (Index = sizeof(ACPI_SDT_HEADER); Index < Rsdt->Length; Index += 4) { + TablePtr = (UINTN)(*(UINT32*)(RsdtPtr + Index)); + DEBUG ((EFI_D_INFO, " Table %d: 0x%x\n", Index, TablePtr)); + Table = (ACPI_SDT_HEADER*)TablePtr; + DEBUG ((EFI_D_INFO, " Signature: '%c%c%c%c'\n", + Table->Signature[0], + Table->Signature[1], + Table->Signature[2], + Table->Signature[3] + )); + DEBUG ((EFI_D_INFO, " Revision: 0x%x\n", Table->Revision)); + DEBUG ((EFI_D_INFO, " Length: 0x%x\n", Table->Length)); + + if (CompareMem(Table->Signature, Name, 4) == 0) { + DEBUG ((EFI_D_INFO, " Match found\n")); + return Table; + } + } + + DEBUG ((EFI_D_INFO, " No match found\n")); + return NULL; +} + +STATIC VOID FirmwareConfigurationInformation(VOID) { + EFI_STRING_ID Token; + + Token = STRING_TOKEN (STR_VIRTUALIZATION); + if (StandardSignatureIsGenuineIntel()) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Intel Virtualization", NULL); + + Token = STRING_TOKEN (STR_VIRTUALIZATION_STATUS); + IA32_CR4 Cr4; + Cr4.UintN = AsmReadCr4 (); + if (Cr4.Bits.VMXE) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-x: Active", NULL); + } else { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-x: Deactivated", NULL); + } + + Token = STRING_TOKEN (STR_IOMMU_STATUS); + CHAR8 TableName[4] = {'D', 'M', 'A', 'R'}; + if (FindAcpiTable(TableName)) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-d: Active", NULL); + } else { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"VT-d: Deactivated", NULL); + } + + Token = STRING_TOKEN(STR_ME_STATUS); + //TODO: proper test for ME + BOOLEAN me_active = FALSE; + if (!me_active) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"The Intel Management Engine is disabled at runtime to increase security.", NULL); + } + } else if (StandardSignatureIsAuthenticAMD()) { + //TODO: verify AMD tests + + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD Virtualization", NULL); + + Token = STRING_TOKEN (STR_VIRTUALIZATION_STATUS); + MSR_IA32_EFER_REGISTER MsrEfer; + MsrEfer.Uint64 = AsmReadMsr64 (MSR_CORE_IA32_EFER); + if (MsrEfer.Bits.SVME) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-V: Active", NULL); + } else { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-V: Deactivated", NULL); + } + + Token = STRING_TOKEN (STR_IOMMU_STATUS); + //TODO: proper test for AMD IOMMU + BOOLEAN iommu_active = FALSE; + if (iommu_active) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-Vi: Active", NULL); + } else { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"AMD-Vi: Deactivated", NULL); + } + } + + Token = STRING_TOKEN (STR_TPM_STATUS); + CHAR8 TableName[4] = {'T', 'P', 'M', '2'}; + if (FindAcpiTable(TableName)) { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Trusted Platform Module: Active", NULL); + } else { + HiiSetString (gFrontPagePrivate.HiiHandle, Token, L"Trusted Platform Module: Deactivated", NULL); + } +} + /** Update the information for the Front Page based on Smbios information. @@ -587,6 +803,8 @@ UpdateFrontPageStrings ( WarnNoBootableMedia (); + FirmwareConfigurationInformation(); + Status = EfiGetSystemConfigurationTable (&gEfiSmbiosTableGuid, (VOID **) &Table); if (EFI_ERROR (Status) || Table == NULL) { return; @@ -876,6 +1094,8 @@ InitializeUserInterface ( UINTN BootTextColumn; UINTN BootTextRow; + gSystemTable = SystemTable; + if (!mModeInitialized) { // // After the console is ready, get current video resolution @@ -1081,4 +1301,3 @@ SetupResetReminder ( gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); } } - diff --git a/MdeModulePkg/Application/UiApp/FrontPageStrings.uni b/MdeModulePkg/Application/UiApp/FrontPageStrings.uni index 1ca0a21729..934a2cb94d 100644 --- a/MdeModulePkg/Application/UiApp/FrontPageStrings.uni +++ b/MdeModulePkg/Application/UiApp/FrontPageStrings.uni @@ -14,8 +14,14 @@ #string STR_FRONT_PAGE_TITLE #language en-US "Front Page" #string STR_FRONT_PAGE_COMPUTER_MODEL #language en-US "" #string STR_FRONT_PAGE_BIOS_VERSION #language en-US "" +#string STR_FIRMWARE_INFO #language en-US "Firmware Configuration Information" #string STR_BOOT_DEFAULT_PROMPT #language en-US "Boot Default" #string STR_BOOT_DEFAULT_HELP #language en-US "Boot the default entry" #string STR_MISSING_STRING #language en-US "Missing String" #string STR_NO_BOOTABLE_MEDIA #language en-US "" #string STR_EMPTY_STRING #language en-US "" +#string STR_VIRTUALIZATION #language en-US "" +#string STR_VIRTUALIZATION_STATUS #language en-US "" +#string STR_IOMMU_STATUS #language en-US "" +#string STR_TPM_STATUS #language en-US "" +#string STR_ME_STATUS #language en-US "" diff --git a/MdeModulePkg/Application/UiApp/FrontPageVfr.Vfr b/MdeModulePkg/Application/UiApp/FrontPageVfr.Vfr index dc3fd383fb..6d036c7cfe 100644 --- a/MdeModulePkg/Application/UiApp/FrontPageVfr.Vfr +++ b/MdeModulePkg/Application/UiApp/FrontPageVfr.Vfr @@ -10,6 +10,7 @@ #define FORMSET_GUID { 0x9e0c30bc, 0x3f06, 0x4ba6, 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe } #define FRONT_PAGE_FORM_ID 0x7600 +#define FIRMWARE_INFO_FORM_ID 0x7601 #define LABEL_FRONTPAGE_INFORMATION 0x1000 #define LABEL_END 0xffff @@ -34,9 +35,26 @@ formset // label LABEL_END; + subtitle text = STRING_TOKEN(STR_EMPTY_STRING); + goto FIRMWARE_INFO_FORM_ID, + prompt = STRING_TOKEN(STR_FIRMWARE_INFO), + help = STRING_TOKEN(STR_EMPTY_STRING); + subtitle text = STRING_TOKEN(STR_EMPTY_STRING); subtitle text = STRING_TOKEN(STR_NO_BOOTABLE_MEDIA); endform; + form formid = FIRMWARE_INFO_FORM_ID, + title = STRING_TOKEN(STR_FIRMWARE_INFO); + + subtitle text = STRING_TOKEN(STR_VIRTUALIZATION); + subtitle text = STRING_TOKEN(STR_VIRTUALIZATION_STATUS); + subtitle text = STRING_TOKEN(STR_IOMMU_STATUS); + subtitle text = STRING_TOKEN(STR_EMPTY_STRING); + subtitle text = STRING_TOKEN(STR_TPM_STATUS); + subtitle text = STRING_TOKEN(STR_EMPTY_STRING); + subtitle text = STRING_TOKEN(STR_ME_STATUS); + endform; + endformset; diff --git a/MdeModulePkg/Application/UiApp/UiApp.inf b/MdeModulePkg/Application/UiApp/UiApp.inf index e64e92aee3..5686442b04 100644 --- a/MdeModulePkg/Application/UiApp/UiApp.inf +++ b/MdeModulePkg/Application/UiApp/UiApp.inf @@ -56,6 +56,7 @@ UefiBootManagerLib [Guids] + gEfiAcpiTableGuid ## CONSUMES ## GUID gEfiIfrTianoGuid ## CONSUMES ## GUID (Extended IFR Guid Opcode) gEfiIfrFrontPageGuid ## CONSUMES ## GUID gEfiSmbiosTableGuid ## CONSUMES diff --git a/MdePkg/Include/Register/Intel/ArchitecturalMsr.h b/MdePkg/Include/Register/Intel/ArchitecturalMsr.h index 28e71cf713..eeb13fb489 100644 --- a/MdePkg/Include/Register/Intel/ArchitecturalMsr.h +++ b/MdePkg/Include/Register/Intel/ArchitecturalMsr.h @@ -6378,7 +6378,11 @@ typedef union { /// [Bit 11] Execute Disable Bit Enable: IA32_EFER.NXE (R/W). /// UINT32 NXE:1; - UINT32 Reserved3:20; + /// + /// [ Bit 12] Secure Virtual Machine Enable (AMD only) + /// + UINT32 SVME:1; + UINT32 Reserved3:19; UINT32 Reserved4:32; } Bits; ///