diff --git a/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 7015c2bcda..0ab2e3d813 100644 --- a/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/MsvmPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -69,6 +69,7 @@ gMsvmPkgTokenSpaceGuid.PcdHighMmioGapBasePageNumber ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdHighMmioGapSizeInPages ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdHostEmulatorsWhenHardwareIsolated ## CONSUMES + gMsvmPkgTokenSpaceGuid.PcdHvEnabled ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdLoadOempTable ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdLowMmioGapBasePageNumber ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdLowMmioGapSizeInPages ## CONSUMES diff --git a/MsvmPkg/AcpiPlatformDxe/Facp.c b/MsvmPkg/AcpiPlatformDxe/Facp.c index 94f8707cab..89f9cb1fef 100644 --- a/MsvmPkg/AcpiPlatformDxe/Facp.c +++ b/MsvmPkg/AcpiPlatformDxe/Facp.c @@ -48,9 +48,12 @@ Return Value: } // - // Set the hypervisor vendor identity to MsHyperV + // Set the hypervisor vendor identity to MsHyperV when Hv is enabled. // - CopyMem(&facp->HypervisorVendorIdentity, "MsHyperV", 8); + if (PcdGetBool(PcdHvEnabled)) + { + CopyMem(&facp->HypervisorVendorIdentity, "MsHyperV", 8); + } if (PcdGetBool(PcdLowPowerS0IdleEnabled)) { diff --git a/MsvmPkg/EfiHvDxe/EfiHv.c b/MsvmPkg/EfiHvDxe/EfiHv.c index 984ae648ed..6824b1645d 100644 --- a/MsvmPkg/EfiHvDxe/EfiHv.c +++ b/MsvmPkg/EfiHvDxe/EfiHv.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -2320,6 +2321,11 @@ EfiHvInitialize ( { EFI_STATUS status; + if (!PcdGetBool(PcdHvEnabled)) + { + return EFI_UNSUPPORTED; + } + InitializeListHead(&mHostVisiblePageList); #if defined (MDE_CPU_X64) diff --git a/MsvmPkg/EfiHvDxe/EfiHvDxe.inf b/MsvmPkg/EfiHvDxe/EfiHvDxe.inf index b47ab34e9f..b10ae4225e 100644 --- a/MsvmPkg/EfiHvDxe/EfiHvDxe.inf +++ b/MsvmPkg/EfiHvDxe/EfiHvDxe.inf @@ -59,6 +59,9 @@ [Protocols.AARCH64] gHardwareInterruptProtocolGuid ## CONSUMES +[Pcd] + gMsvmPkgTokenSpaceGuid.PcdHvEnabled ## CONSUMES + [Pcd.X64] gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaBoundary ## CONSUMES gMsvmPkgTokenSpaceGuid.PcdIsolationSharedGpaCanonicalizationBitmask ## CONSUMES diff --git a/MsvmPkg/EventLogDxe/EventLogDxe.c b/MsvmPkg/EventLogDxe/EventLogDxe.c index ad3be2a8af..19159a0fc6 100644 --- a/MsvmPkg/EventLogDxe/EventLogDxe.c +++ b/MsvmPkg/EventLogDxe/EventLogDxe.c @@ -6,11 +6,11 @@ **/ #include "EventLogDxe.h" +#include #include #include "StatusCode.h" #include "EventLogger.h" -EFI_HV_PROTOCOL *mHv; EFI_HV_IVM_PROTOCOL *mHvIvm; EFI_STATUS @@ -43,24 +43,26 @@ Return Value: EFI_STATUS status; DEBUG((DEBUG_INIT, "EventLog Driver Starting\n")); + // - // Initialize the event channel management and then the status code protocol + // The IVM protocol is required for hardware-isolated VMs. Check this + // before EventLoggerInitialize, which installs protocols — returning + // error after that would leave dangling protocol entries. // - status = EventLoggerInitialize(); - - if (EFI_ERROR(status)) + if (IsHardwareIsolatedNoParavisor()) { - goto Exit; - } - - status = gBS->LocateProtocol(&gEfiHvProtocolGuid, NULL, (VOID **)&mHv); + status = gBS->LocateProtocol(&gEfiHvIvmProtocolGuid, NULL, (VOID **)&mHvIvm); - if (EFI_ERROR(status)) - { - goto Exit; + if (EFI_ERROR(status)) + { + goto Exit; + } } - status = gBS->LocateProtocol(&gEfiHvIvmProtocolGuid, NULL, (VOID **)&mHvIvm); + // + // Initialize the event channel management and then the status code protocol + // + status = EventLoggerInitialize(); if (EFI_ERROR(status)) { diff --git a/MsvmPkg/EventLogDxe/EventLogDxe.inf b/MsvmPkg/EventLogDxe/EventLogDxe.inf index 0ebd231fec..447be1a794 100644 --- a/MsvmPkg/EventLogDxe/EventLogDxe.inf +++ b/MsvmPkg/EventLogDxe/EventLogDxe.inf @@ -61,8 +61,7 @@ [Protocols] gEfiEventLogProtocolGuid ## PRODUCES gEfiFirmwareVolume2ProtocolGuid ## CONSUMES - gEfiHvIvmProtocolGuid ## CONSUMES - gEfiHvProtocolGuid ## CONSUMES + gEfiHvIvmProtocolGuid ## SOMETIMES_CONSUMES gEfiRscHandlerProtocolGuid ## CONSUMES gEfiStatusCodeRuntimeProtocolGuid ## PRODUCES diff --git a/MsvmPkg/Include/Ppi/SecPlatformType.h b/MsvmPkg/Include/Ppi/SecPlatformType.h new file mode 100644 index 0000000000..000d751967 --- /dev/null +++ b/MsvmPkg/Include/Ppi/SecPlatformType.h @@ -0,0 +1,32 @@ +/** @file + SEC Platform Type PPI definition. + + This PPI is installed by the SEC phase to communicate the platform type + to PEI modules. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SEC_PLATFORM_TYPE_H_ +#define SEC_PLATFORM_TYPE_H_ + +/// +/// Platform type values passed by the loader. +/// +typedef enum { + MsvmSecPlatformHyperV = 0, // Hyper-V with MS extensions + MsvmSecPlatformGeneric = 1, // Generic virtualization (no MS extensions) +} MSVM_SEC_PLATFORM_TYPE; + +/// +/// PPI carrying the platform type from SEC to PEI. +/// +typedef struct { + MSVM_SEC_PLATFORM_TYPE PlatformType; +} MSVM_SEC_PLATFORM_TYPE_PPI; + +extern EFI_GUID gMsvmSecPlatformTypePpiGuid; + +#endif // SEC_PLATFORM_TYPE_H_ diff --git a/MsvmPkg/Library/CrashLib/AArch64/Crash.c b/MsvmPkg/Library/CrashLib/AArch64/Crash.c index 865e2b008f..1bdabcf463 100644 --- a/MsvmPkg/Library/CrashLib/AArch64/Crash.c +++ b/MsvmPkg/Library/CrashLib/AArch64/Crash.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -51,72 +52,76 @@ ReportCrash( IN UINTN MessageLength ) { - // - // Set the guest ID before writing crash registers, if necessary. - // - HV_REGISTER_VALUE registerValue; - HV_STATUS status = AsmGetVpRegister(HvRegisterGuestOsId, ®isterValue); - ASSERT(status == HV_STATUS_SUCCESS); - - if (registerValue.Reg64 == 0) + if (PcdGetBool(PcdHvEnabled)) { - DEBUG((EFI_D_INFO, "GuestOsId is not set in ReportCrash(); setting now.\n")); - - HV_GUEST_OS_ID_CONTENTS guestOsId; - guestOsId.AsUINT64 = 0; - guestOsId.OsId = HvGuestOsMicrosoftUndefined; - guestOsId.VendorId = HvGuestOsVendorMicrosoft; - - status = AsmSetVpRegister64(HvRegisterGuestOsId, guestOsId.AsUINT64); + // + // Set the guest ID before writing crash registers, if necessary. + // + HV_REGISTER_VALUE registerValue; + HV_STATUS status = AsmGetVpRegister(HvRegisterGuestOsId, ®isterValue); ASSERT(status == HV_STATUS_SUCCESS); - } - else - { - DEBUG((EFI_D_VERBOSE, "GuestOsId is 0x%llx.\n", (UINTN)registerValue.Reg64)); - } - - // - // Determine if crash MSRs are supported - // - status = AsmGetVpRegister(HvRegisterPrivilegesAndFeaturesInfo, ®isterValue); - ASSERT(status == HV_STATUS_SUCCESS); - - DEBUG((EFI_D_VERBOSE, "HvRegisterFeaturesInfo (low) is 0x%llx.\n", (UINTN)registerValue.Reg128.Low64)); - DEBUG((EFI_D_VERBOSE, "HvRegisterFeaturesInfo (high) is 0x%llx.\n", (UINTN)registerValue.Reg128.High64)); - HV_HYPERVISOR_FEATURES hvFeatures; - *((PHV_UINT128)&hvFeatures) = registerValue.Reg128; + if (registerValue.Reg64 == 0) + { + DEBUG((EFI_D_INFO, "GuestOsId is not set in ReportCrash(); setting now.\n")); + + HV_GUEST_OS_ID_CONTENTS guestOsId; + guestOsId.AsUINT64 = 0; + guestOsId.OsId = HvGuestOsMicrosoftUndefined; + guestOsId.VendorId = HvGuestOsVendorMicrosoft; + + status = AsmSetVpRegister64(HvRegisterGuestOsId, guestOsId.AsUINT64); + ASSERT(status == HV_STATUS_SUCCESS); + } + else + { + DEBUG((EFI_D_VERBOSE, "GuestOsId is 0x%llx.\n", (UINTN)registerValue.Reg64)); + } + + // + // Determine if crash MSRs are supported + // + status = AsmGetVpRegister(HvRegisterPrivilegesAndFeaturesInfo, ®isterValue); + ASSERT(status == HV_STATUS_SUCCESS); - if (!hvFeatures.GuestCrashRegsAvailable) - { - DEBUG((EFI_D_INFO, "GuestCrashRegister enlightenment is not available.\n")); - return; + DEBUG((EFI_D_VERBOSE, "HvRegisterFeaturesInfo (low) is 0x%llx.\n", (UINTN)registerValue.Reg128.Low64)); + DEBUG((EFI_D_VERBOSE, "HvRegisterFeaturesInfo (high) is 0x%llx.\n", (UINTN)registerValue.Reg128.High64)); + + HV_HYPERVISOR_FEATURES hvFeatures; + *((PHV_UINT128)&hvFeatures) = registerValue.Reg128; + + if (hvFeatures.GuestCrashRegsAvailable) + { + // + // N.B. For ARM64, the crash control registers cannot currently be read for capabilities. + // + + AsmSetVpRegister64(HvRegisterGuestCrashP0, Param0); + AsmSetVpRegister64(HvRegisterGuestCrashP1, Param1); + AsmSetVpRegister64(HvRegisterGuestCrashP2, Param2); + AsmSetVpRegister64(HvRegisterGuestCrashP3, MessageBuffer); + AsmSetVpRegister64(HvRegisterGuestCrashP4, MessageLength); + + // + // Write the control register. + // + HV_CRASH_CTL_REG_CONTENTS writeCrashCtlReg; + writeCrashCtlReg.AsUINT64 = 0; + writeCrashCtlReg.CrashNotify = 1; + + writeCrashCtlReg.CrashMessage = 1; + writeCrashCtlReg.NoCrashDump = 1; + writeCrashCtlReg.PreOSId = MSVM_PKG_CRASH_ID; + + AsmSetVpRegister64(HvRegisterGuestCrashCtl, writeCrashCtlReg.AsUINT64); + DEBUG((EFI_D_INFO, "ReportCrash successful.\n")); + } + else + { + DEBUG((EFI_D_INFO, "GuestCrashRegister enlightenment is not available.\n")); + } } - // - // N.B. For ARM64, the crash control registers cannot currently be read for capabilities. - // - - AsmSetVpRegister64(HvRegisterGuestCrashP0, Param0); - AsmSetVpRegister64(HvRegisterGuestCrashP1, Param1); - AsmSetVpRegister64(HvRegisterGuestCrashP2, Param2); - AsmSetVpRegister64(HvRegisterGuestCrashP3, MessageBuffer); - AsmSetVpRegister64(HvRegisterGuestCrashP4, MessageLength); - - // - // Write the control register. - // - HV_CRASH_CTL_REG_CONTENTS writeCrashCtlReg; - writeCrashCtlReg.AsUINT64 = 0; - writeCrashCtlReg.CrashNotify = 1; - - writeCrashCtlReg.CrashMessage = 1; - writeCrashCtlReg.NoCrashDump = 1; - writeCrashCtlReg.PreOSId = MSVM_PKG_CRASH_ID; - - AsmSetVpRegister64(HvRegisterGuestCrashCtl, writeCrashCtlReg.AsUINT64); - DEBUG((EFI_D_INFO, "ReportCrash successful.\n")); - // // Tell the host to collect EFI diagnostics. // diff --git a/MsvmPkg/Library/CrashLib/CrashLib.inf b/MsvmPkg/Library/CrashLib/CrashLib.inf index 6a7d8736e6..c56af5bbe0 100644 --- a/MsvmPkg/Library/CrashLib/CrashLib.inf +++ b/MsvmPkg/Library/CrashLib/CrashLib.inf @@ -42,3 +42,6 @@ [LibraryClasses.AARCH64] ArmSmcLib HvHypercallLib + +[Pcd.AARCH64] + gMsvmPkgTokenSpaceGuid.PcdHvEnabled ## CONSUMES diff --git a/MsvmPkg/MsvmPkg.dec b/MsvmPkg/MsvmPkg.dec index b46b7ce80b..b5eb427a21 100644 --- a/MsvmPkg/MsvmPkg.dec +++ b/MsvmPkg/MsvmPkg.dec @@ -52,9 +52,10 @@ gMsvmUnableToBootEventGuid = {0x3c8d08a8, 0x42c5, 0x4c33, {0xa6, 0xd8, 0x13, 0xf4, 0xda, 0x4a, 0xa6, 0x85}} [Ppis] + gMsvmSecPlatformTypePpiGuid = {0x7a3b9e2c, 0x4d15, 0x4f8a, {0xb1, 0x0e, 0x3c, 0x5d, 0x8f, 0x2a, 0x6b, 0x47}} [Protocols] - gMsvmAziHsmProtocolGuid = {0x38976D4E, 0x7454, 0x40CF, {0x9E, 0x12, 0x95, 0xCE, 0x61, 0xA4, 0xCD, 0x6C}} + gMsvmAziHsmProtocolGuid = {0x38976D4E, 0x7454, 0x40CF, {0x9E, 0x12, 0x95, 0xCE, 0x61, 0xA4, 0xCD, 0x6C}} # Hyper-V Protocol gEfiHvProtocolGuid = {0xa261a0f1, 0xaa53, 0x4c83, {0x94, 0xda, 0x12, 0x0c, 0xdf, 0x6d, 0x8c, 0x8d}} gEfiHvIvmProtocolGuid = {0xc40a31b5, 0x3899, 0x4f76, {0xbf, 0x7e, 0x32, 0x95, 0x83, 0x3f, 0xee, 0xe7}} @@ -304,6 +305,7 @@ gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled|FALSE|BOOLEAN|0x6065 gMsvmPkgTokenSpaceGuid.PcdMtrrsInitializedAtLoad|FALSE|BOOLEAN|0x6067 gMsvmPkgTokenSpaceGuid.PcdVmbusEnabled|TRUE|BOOLEAN|0x6068 + gMsvmPkgTokenSpaceGuid.PcdHvEnabled|TRUE|BOOLEAN|0x6069 gMsvmPkgTokenSpaceGuid.PcdForceDmaBounceEnabled|FALSE|BOOLEAN|0x6076 # UEFI_CONFIG_PROCESSOR_INFORMATION diff --git a/MsvmPkg/MsvmPkgAARCH64.dsc b/MsvmPkg/MsvmPkgAARCH64.dsc index 2c0d7dcb79..4d05d31e76 100644 --- a/MsvmPkg/MsvmPkgAARCH64.dsc +++ b/MsvmPkg/MsvmPkgAARCH64.dsc @@ -699,6 +699,7 @@ gMsvmPkgTokenSpaceGuid.PcdHostEmulatorsWhenHardwareIsolated|FALSE gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled|FALSE gMsvmPkgTokenSpaceGuid.PcdVmbusEnabled|TRUE + gMsvmPkgTokenSpaceGuid.PcdHvEnabled|TRUE gMsvmPkgTokenSpaceGuid.PcdForceDmaBounceEnabled|FALSE # UEFI_CONFIG_PROCESSOR_INFORMATION diff --git a/MsvmPkg/MsvmPkgX64.dsc b/MsvmPkg/MsvmPkgX64.dsc index 010983e2fb..b58cd404dd 100644 --- a/MsvmPkg/MsvmPkgX64.dsc +++ b/MsvmPkg/MsvmPkgX64.dsc @@ -717,6 +717,7 @@ gMsvmPkgTokenSpaceGuid.PcdHostEmulatorsWhenHardwareIsolated|FALSE gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled|FALSE gMsvmPkgTokenSpaceGuid.PcdVmbusEnabled|TRUE + gMsvmPkgTokenSpaceGuid.PcdHvEnabled|TRUE gMsvmPkgTokenSpaceGuid.PcdForceDmaBounceEnabled|FALSE # UEFI_CONFIG_PROCESSOR_INFORMATION diff --git a/MsvmPkg/PlatformPei/Config.c b/MsvmPkg/PlatformPei/Config.c index 70ea627b32..6deb211dab 100644 --- a/MsvmPkg/PlatformPei/Config.c +++ b/MsvmPkg/PlatformPei/Config.c @@ -946,6 +946,17 @@ ConfigSetUefiConfigFlags( PEI_FAIL_FAST_IF_FAILED(PcdSetBoolS(PcdTpmLocalityRegsEnabled, (UINT8) ConfigFlags->Flags.TpmLocalityRegsEnabled)); PEI_FAIL_FAST_IF_FAILED(PcdSetBoolS(PcdMtrrsInitializedAtLoad, (UINT8) ConfigFlags->Flags.MtrrsInitializedAtLoad)); PEI_FAIL_FAST_IF_FAILED(PcdSetBoolS(PcdVmbusEnabled, !ConfigFlags->Flags.VmbusDisabled)); + + // + // VMBus requires Hv. PcdHvEnabled was already set from the SEC platform + // type PPI in InitializePlatform(). Validate consistency here. + // + if (!PcdGetBool(PcdHvEnabled) && !ConfigFlags->Flags.VmbusDisabled) + { + DEBUG((DEBUG_ERROR, "Invalid config: VMBus enabled but Hv disabled.\n")); + FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + } + PEI_FAIL_FAST_IF_FAILED(PcdSetBoolS(PcdPciDisableBusEnumeration, (UINT8) ConfigFlags->Flags.PciResourcesPreAssigned)); PEI_FAIL_FAST_IF_FAILED(PcdSetBoolS(PcdForceDmaBounceEnabled, (UINT8) ConfigFlags->Flags.ForceDmaBounceEnabled)); diff --git a/MsvmPkg/PlatformPei/Platform.c b/MsvmPkg/PlatformPei/Platform.c index 655eac842e..ec5c8227fb 100644 --- a/MsvmPkg/PlatformPei/Platform.c +++ b/MsvmPkg/PlatformPei/Platform.c @@ -27,6 +27,7 @@ #if defined(MDE_CPU_AARCH64) #include +#include #endif #if defined (MDE_CPU_X64) #include @@ -1040,6 +1041,44 @@ Return Value: ZeroMem(&context, sizeof(context)); +#if defined(MDE_CPU_AARCH64) + // + // On AARCH64, determine HV presence from the platform type passed by the + // loader via the SEC platform type PPI. This is the single source of truth. + // + { + MSVM_SEC_PLATFORM_TYPE_PPI *SecPlatformTypePpi; + BOOLEAN HvEnabled; + + status = PeiServicesLocatePpi( + &gMsvmSecPlatformTypePpiGuid, + 0, + NULL, + (VOID **)&SecPlatformTypePpi + ); + if (EFI_ERROR(status)) + { + DEBUG((DEBUG_ERROR, "Failed to locate SEC Platform Type PPI: %r\n", status)); + FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + } + + switch (SecPlatformTypePpi->PlatformType) + { + case MsvmSecPlatformHyperV: + HvEnabled = TRUE; + break; + case MsvmSecPlatformGeneric: + HvEnabled = FALSE; + break; + default: + DEBUG((DEBUG_ERROR, "Unrecognized platform type: %d\n", SecPlatformTypePpi->PlatformType)); + FAIL_FAST_UNEXPECTED_HOST_BEHAVIOR(); + } + + PEI_FAIL_FAST_IF_FAILED(PcdSetBoolS(PcdHvEnabled, HvEnabled)); + } +#endif + // // Determine whether this system is running isolated in order to determine // the correct mechanism for loading the configuration. diff --git a/MsvmPkg/PlatformPei/PlatformPei.inf b/MsvmPkg/PlatformPei/PlatformPei.inf index c6a785e213..40ac4cc2dd 100644 --- a/MsvmPkg/PlatformPei/PlatformPei.inf +++ b/MsvmPkg/PlatformPei/PlatformPei.inf @@ -183,6 +183,7 @@ gMsvmPkgTokenSpaceGuid.PcdTpmLocalityRegsEnabled gMsvmPkgTokenSpaceGuid.PcdMtrrsInitializedAtLoad gMsvmPkgTokenSpaceGuid.PcdVmbusEnabled + gMsvmPkgTokenSpaceGuid.PcdHvEnabled gMsvmPkgTokenSpaceGuid.PcdForceDmaBounceEnabled gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesPtr gMsvmPkgTokenSpaceGuid.PcdPcieBarAperturesSize @@ -203,6 +204,9 @@ [Ppis] gEfiPeiMasterBootModePpiGuid +[Ppis.AARCH64] + gMsvmSecPlatformTypePpiGuid ## CONSUMES + [Depex] TRUE diff --git a/MsvmPkg/Sec/AArch64/SecEntry.S b/MsvmPkg/Sec/AArch64/SecEntry.S index 9057c6aae2..116fd2e519 100644 --- a/MsvmPkg/Sec/AArch64/SecEntry.S +++ b/MsvmPkg/Sec/AArch64/SecEntry.S @@ -11,13 +11,12 @@ ASM_FUNC(_ModuleEntryPoint) // Loader sets register state that become inputs to this function // x0 - Firmware Volume Base Address // x1 - Stack Base Address + // x2 - Platform Type (MSVM_SEC_PLATFORM_TYPE; 0 = HyperV, 1 = Generic) // bl SerialWriteBanner // print banner to COM2 mov sp, x1 // Establish stack - leave x1 as second arg to C code - ldr x2, [x0, #8] // Get PEI Core entry from second entry in FV reset vector - bl SecStartupWithStack // jump to C code with 3 args (x0,x1,x2) ASM_FUNC(HvInvokeDebugger) diff --git a/MsvmPkg/Sec/AArch64/SecEntry.masm b/MsvmPkg/Sec/AArch64/SecEntry.masm deleted file mode 100644 index 4fd0a96c2a..0000000000 --- a/MsvmPkg/Sec/AArch64/SecEntry.masm +++ /dev/null @@ -1,128 +0,0 @@ -/** @file - SecEntry - - Copyright (c) Microsoft Corporation. - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - - AREA |.text|,ALIGN=3,CODE,READONLY - - EXPORT _ModuleEntryPoint - EXPORT SetGuestOsId - IMPORT SecStartupWithStack - -_ModuleEntryPoint PROC - // Loader sets register state that become inputs to this function - // x0 - Firmware Volume Base Address - // x1 - Stack Base Address - - // bl SerialWriteBanner // print banner to COM2 - mov sp, x1 // Establish stack - leave x1 as second arg to C code - b SecStartupWithStack // jump to C code with 2 args (x0,x1) - -_ModuleEntryPoint ENDP - -HvInvokeDebugger PROC - - // *untested* - - mov x2, x0 // supplemental Code: from caller in x0 - mov x1, 0x1 // reason: HV_DEBUG_INVOKE_REASON_CLOCK_WATCHDOG - ldr x0, =0x000000000001000A // hypercall input - IsFast = 1, CallCode = 0A - hvc #1 - and x0, x0, #0xFFFF // isolate result code - ret - -HvInvokeDebugger ENDP - -SetGuestOsId PROC - - ldr x0, =0x0000000100010051 // hypercall input (rep 1 argument, fast, HvCallSetVpRegisters) - ldr x1, =0xFFFFFFFFFFFFFFFF // partition id (self) - ldr x2, =0x00000000FFFFFFFE // pad + vp index (-2 == self) - ldr x3, =0x0000000000090002 // pad + RegisterName == HvRegisterGuestOsId - mov x4, #0 // pad - mov x5, #0x0001000000000000 // RegisterValue.Low == HvGuestOsVendorMicrosoft | HvGuestOsMicrosoftUndefined - mov x6, #0 // RegisterValue.High - hvc #1 - and x0, x0, #0xFFFF // isolate result - ret - -SetGuestOsId ENDP - -// -// SerialWriteBanner -// -// Writes "SECMAIN @ ELn" where n is the current EL. -// -SerialWriteBanner PROC - - // writes a - - ldr x9, =0x00000000EFFEB000 - mov w10, #0x1B // ESC - strb w10, [x9] - mov w10, #0x63 // 'c' - strb w10, [x9] - mov w10, #0x1B // ESC - strb w10, [x9] - mov w10, #0x5B // '[' - strb w10, [x9] - mov w10, #0x33 // '3' - strb w10, [x9] - mov w10, #0x4A // 'J' - strb w10, [x9] - mov w10, #0x53 // 'S' - strb w10, [x9] - mov w10, #0x45 // 'E' - strb w10, [x9] - mov w10, #0x43 // 'C' - strb w10, [x9] - mov w10, #0x4D // 'M' - strb w10, [x9] - mov w10, #0x41 // 'A' - strb w10, [x9] - mov w10, #0x49 // 'I' - strb w10, [x9] - mov w10, #0x4E // 'N' - strb w10, [x9] - mov w10, #0x20 // ' ' - strb w10, [x9] - mov w10, #0x40 // '@' - strb w10, [x9] - mov w10, #0x20 // ' ' - strb w10, [x9] - mov w10, #0x45 // 'E' - strb w10, [x9] - mov w10, #0x4C // 'L' - strb w10, [x9] - - // TODO: What's the constant for ARM64_CurrentEL format? - // mrs x8, #ARM64_CurrentEL - cmp x8, #0x8 - bgt %f3 - beq %f2 - cbnz x8, %f1 -5 - bne %b5 // shouldn't get here -1 - mov w10, #0x31 // '1' - b %f4 -2 - mov w10, #0x32 // '2' - b %f4 -3 - mov w10, #0x33 // '3' - b %f4 -4 - strb w10, [x9] - mov w10, #0x0D // '\r' - strb w10, [x9] - mov w10, #0x0A // '\n' - strb w10, [x9] - ret - -SerialWriteBanner ENDP - - END diff --git a/MsvmPkg/Sec/AArch64/SecMain.c b/MsvmPkg/Sec/AArch64/SecMain.c index a8741478de..f46b680c65 100644 --- a/MsvmPkg/Sec/AArch64/SecMain.c +++ b/MsvmPkg/Sec/AArch64/SecMain.c @@ -14,6 +14,7 @@ #include #include #include +#include VOID SetGuestOsId(); @@ -37,14 +38,23 @@ EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = TemporaryRamMigration }; +MSVM_SEC_PLATFORM_TYPE_PPI mSecPlatformTypePpi = +{ + MsvmSecPlatformHyperV +}; EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = { { - (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + EFI_PEI_PPI_DESCRIPTOR_PPI, &gEfiTemporaryRamSupportPpiGuid, &mTemporaryRamSupportPpi }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gMsvmSecPlatformTypePpiGuid, + &mSecPlatformTypePpi + }, }; @@ -110,7 +120,8 @@ VOID EFIAPI SecStartupWithStack ( IN EFI_FIRMWARE_VOLUME_HEADER *BootFv, - IN VOID *TopOfCurrentStack + IN VOID *TopOfCurrentStack, + IN UINT64 PlatformType ) /*++ @@ -125,6 +136,9 @@ Routine Description: TopOfCurrentStack - the top of the current stack + PlatformType - Platform type from the loader (MSVM_SEC_PLATFORM_TYPE). + 0 = HyperV (default), 1 = Generic. + Return Value: None. @@ -138,12 +152,26 @@ Return Value: DEBUG((DEBUG_VERBOSE, sequence)); DEBUG((DEBUG_VERBOSE, - ">>> SecStartupWithStack @ %p (%p, %p)\n", + ">>> SecStartupWithStack @ %p (%p, %p, 0x%llx)\n", SecStartupWithStack, BootFv, - TopOfCurrentStack + TopOfCurrentStack, + PlatformType )); + // + // Store the platform type for the PPI so PEI modules can access it. + // Fail immediately if the loader passed an unrecognized platform type. + // + if (PlatformType != MsvmSecPlatformHyperV && + PlatformType != MsvmSecPlatformGeneric) + { + DEBUG((DEBUG_ERROR, "Unrecognized platform type: 0x%llx\n", PlatformType)); + ASSERT(FALSE); + CpuDeadLoop(); + } + mSecPlatformTypePpi.PlatformType = (MSVM_SEC_PLATFORM_TYPE)PlatformType; + // // Initialize floating point operating environment // to be compliant with UEFI spec. @@ -181,8 +209,12 @@ Return Value: // // Set the guest OS ID so that hypercalls are possible. + // Only do this when running under Hyper-V. // - SetGuestOsId(); + if (PlatformType == MsvmSecPlatformHyperV) + { + SetGuestOsId(); + } // // Initialize Debug Agent to support source level debug in SEC/PEI phases diff --git a/MsvmPkg/Sec/SecMain.inf b/MsvmPkg/Sec/SecMain.inf index b5f039e977..09bf2c9d65 100644 --- a/MsvmPkg/Sec/SecMain.inf +++ b/MsvmPkg/Sec/SecMain.inf @@ -28,7 +28,6 @@ X64/SecMain.c [Sources.AARCH64] - AArch64/SecEntry.masm AArch64/SecEntry.S AArch64/SecMain.c @@ -63,6 +62,9 @@ [Ppis] gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED +[Ppis.AARCH64] + gMsvmSecPlatformTypePpiGuid # PPI ALWAYS_PRODUCED + [FixedPcd] gMsvmPkgTokenSpaceGuid.PcdBiosBaseAddress gMsvmPkgTokenSpaceGuid.PcdCom1RegisterBase