diff --git a/OvmfPkg/Include/IndustryStandard/Microvm.h b/OvmfPkg/Include/IndustryStandard/Microvm.h index c56547c4f2..ae0c2e5311 100644 --- a/OvmfPkg/Include/IndustryStandard/Microvm.h +++ b/OvmfPkg/Include/IndustryStandard/Microvm.h @@ -9,4 +9,11 @@ #define MICROVM_PSEUDO_DEVICE_ID 0xfff1 +/* generic event device */ +#define MICROVM_GED_MMIO_BASE 0xfea00000 +#define MICROVM_GED_MMIO_BASE_REGS (MICROVM_GED_MMIO_BASE + 0x200) +#define MICROVM_ACPI_GED_REG_SLEEP_CTL 0x00 +#define MICROVM_ACPI_GED_REG_RESET 0x02 +#define MICROVM_ACPI_GED_RESET_VALUE 0x42 + #endif // __MICROVM_H__ diff --git a/OvmfPkg/Include/OvmfPlatforms.h b/OvmfPkg/Include/OvmfPlatforms.h index 77dd818e30..3b85593b70 100644 --- a/OvmfPkg/Include/OvmfPlatforms.h +++ b/OvmfPkg/Include/OvmfPlatforms.h @@ -15,6 +15,7 @@ #include #include #include +#include // // OVMF Host Bridge DID Address diff --git a/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibMicrovm.inf b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibMicrovm.inf new file mode 100644 index 0000000000..564b1d3022 --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibMicrovm.inf @@ -0,0 +1,37 @@ +## @file +# DXE library instance for ResetSystem library class for OVMF +# +# Copyright (C) 2020, Red Hat, Inc. +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ResetSystemLibMicrovm + FILE_GUID = 7cd630bb-f581-4d1a-97ca-9dbc900e26a4 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib|SEC PEI_CORE PEIM DXE_CORE + +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + ResetSystemLibMicrovm.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + TimerLib diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.c b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.c new file mode 100644 index 0000000000..0de8b39f54 --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.c @@ -0,0 +1,49 @@ +/** @file + Reset System Library functions for OVMF + + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include // BIT1 +#include + +#include // CpuDeadLoop() +#include // ASSERT() +#include +#include // IoWrite8() +#include // ResetCold() +#include // MicroSecondDelay() +#include // EfiGoneVirtual() +#include // PIIX4_PMBA_VALUE + +EFI_STATUS +EFIAPI +DxeResetSystemLibMicrovmConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINTN Address = MICROVM_GED_MMIO_BASE; + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor; + + DEBUG ((DEBUG_INFO, "%a: start\n", __FUNCTION__)); + + Status = gDS->GetMemorySpaceDescriptor (Address, &Descriptor); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: GetMemorySpaceDescriptor failed\n", __FUNCTION__)); + return RETURN_UNSUPPORTED; + } + + Status = gDS->SetMemorySpaceAttributes (Address, SIZE_4KB, + Descriptor.Attributes | EFI_MEMORY_RUNTIME); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "%a: SetMemorySpaceAttributes failed\n", __FUNCTION__)); + return RETURN_UNSUPPORTED; + } + + DEBUG ((DEBUG_INFO, "%a: done\n", __FUNCTION__)); + return EFI_SUCCESS; +} diff --git a/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf new file mode 100644 index 0000000000..ac9c259964 --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf @@ -0,0 +1,40 @@ +## @file +# DXE library instance for ResetSystem library class for OVMF +# +# Copyright (C) 2020, Red Hat, Inc. +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 1.29 + BASE_NAME = ResetSystemLibMicrovm + FILE_GUID = 3d6faf60-804a-4ca9-a36a-1a92416919d0 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = ResetSystemLib|DXE_DRIVER DXE_RUNTIME_DRIVER SMM_CORE DXE_SMM_DRIVER UEFI_DRIVER UEFI_APPLICATION + CONSTRUCTOR = DxeResetSystemLibMicrovmConstructor + +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + ResetSystemLibMicrovm.c + DxeResetSystemLibMicrovm.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + DxeServicesTableLib + IoLib + TimerLib diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLibMicrovm.c b/OvmfPkg/Library/ResetSystemLib/ResetSystemLibMicrovm.c new file mode 100644 index 0000000000..5c714cf06a --- /dev/null +++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLibMicrovm.c @@ -0,0 +1,89 @@ +/** @file + Reset System Library functions for OVMF + + Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include // BIT1 + +#include // CpuDeadLoop() +#include // ASSERT() +#include // IoWrite8() +#include // ResetCold() +#include // MicroSecondDelay() +#include // EfiGoneVirtual() +#include // PIIX4_PMBA_VALUE + +static UINTN MicrovmGedBase (VOID) +{ + VOID *Address = (VOID*) MICROVM_GED_MMIO_BASE_REGS; + + if (EfiGoneVirtual ()) { + EfiConvertPointer (0, &Address); + DEBUG ((DEBUG_INFO, "%a: virtual -> 0x%x\n", __FUNCTION__, Address)); + } else { + DEBUG ((DEBUG_INFO, "%a: physical -> 0x%x\n", __FUNCTION__, Address)); + } + + return (UINTN) Address; +} + +static VOID MicrovmReset (VOID) +{ + UINTN Address = MicrovmGedBase(); + + DEBUG ((DEBUG_INFO, "%a: microvm reset via ged\n", __FUNCTION__)); + MmioWrite8 (Address + MICROVM_ACPI_GED_REG_RESET, + MICROVM_ACPI_GED_RESET_VALUE); + CpuDeadLoop (); +} + +static VOID MicrovmShutdown (VOID) +{ + UINTN Address = MicrovmGedBase(); + + DEBUG ((DEBUG_INFO, "%a: microvm poweroff via ged\n", __FUNCTION__)); + MmioWrite8 (Address + MICROVM_ACPI_GED_REG_SLEEP_CTL, + (1 << 5) /* enable bit */ | + (5 << 2) /* typ == S5 */); + CpuDeadLoop (); +} + +VOID EFIAPI ResetCold (VOID) +{ + MicrovmReset(); +} + +VOID EFIAPI ResetWarm (VOID) +{ + MicrovmReset(); +} + +VOID +EFIAPI +ResetPlatformSpecific ( + IN UINTN DataSize, + IN VOID *ResetData + ) +{ + MicrovmReset(); +} + +VOID +EFIAPI +ResetSystem ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + MicrovmReset(); +} + +VOID EFIAPI ResetShutdown (VOID) +{ + MicrovmShutdown(); +} diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc index 019b50de7d..3cc951f0d9 100644 --- a/OvmfPkg/Microvm/MicrovmX64.dsc +++ b/OvmfPkg/Microvm/MicrovmX64.dsc @@ -128,7 +128,7 @@ [LibraryClasses] PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibMicrovm.inf PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf BaseLib|MdePkg/Library/BaseLib/BaseLib.inf @@ -318,7 +318,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -336,7 +336,7 @@ [LibraryClasses.common.UEFI_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -351,7 +351,7 @@ [LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf @@ -376,7 +376,7 @@ [LibraryClasses.common.UEFI_APPLICATION] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf @@ -389,7 +389,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf @@ -410,7 +410,7 @@ [LibraryClasses.common.SMM_CORE] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf - ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLib.inf + ResetSystemLib|OvmfPkg/Library/ResetSystemLib/DxeResetSystemLibMicrovm.inf SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index aeb39595aa..df2d9ad015 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -161,6 +161,7 @@ MemMapInitialization ( AddIoMemoryRangeHob (0x0A0000, BASE_1MB); if (mHostBridgeDevId == 0xffff /* microvm */) { + AddIoMemoryBaseSizeHob (MICROVM_GED_MMIO_BASE, SIZE_4KB); AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB); /* ioapic #1 */ AddIoMemoryBaseSizeHob (0xFEC10000, SIZE_4KB); /* ioapic #2 */ return;