]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/AcpiPlatformDxe/CloudHvAcpi.c
OvmfPkg/PlatformInitLib: Transfer GUID Extension HOB
[mirror_edk2.git] / OvmfPkg / AcpiPlatformDxe / CloudHvAcpi.c
1 /** @file
2 OVMF ACPI Cloud Hypervisor support
3
4 Copyright (c) 2021, Intel Corporation. All rights reserved.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <IndustryStandard/CloudHv.h> // CLOUDHV_RSDP_ADDRESS
11 #include <IndustryStandard/Xen/arch-x86/hvm/start_info.h> // hvm_start_info
12 #include <Library/BaseLib.h> // CpuDeadLoop()
13 #include <Library/DebugLib.h> // DEBUG()
14 #include <Library/PcdLib.h> // PcdGet32()
15
16 #include "AcpiPlatform.h"
17
18 // Get the ACPI tables from EBDA start
19 EFI_STATUS
20 EFIAPI
21 InstallCloudHvTables (
22 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol
23 )
24 {
25 EFI_STATUS Status;
26 UINTN TableHandle;
27
28 EFI_ACPI_DESCRIPTION_HEADER *Xsdt;
29 VOID *CurrentTableEntry;
30 UINTN CurrentTablePointer;
31 EFI_ACPI_DESCRIPTION_HEADER *CurrentTable;
32 UINTN Index;
33 UINTN NumberOfTableEntries;
34 EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt2Table;
35 EFI_ACPI_DESCRIPTION_HEADER *DsdtTable;
36 EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *AcpiRsdpStructurePtr;
37 UINT32 *PVHResetVectorData;
38 struct hvm_start_info *pvh_start_info;
39
40 Fadt2Table = NULL;
41 DsdtTable = NULL;
42 TableHandle = 0;
43 NumberOfTableEntries = 0;
44 AcpiRsdpStructurePtr = NULL;
45 PVHResetVectorData = NULL;
46 pvh_start_info = NULL;
47
48 PVHResetVectorData = (VOID *)(UINTN)PcdGet32 (PcdXenPvhStartOfDayStructPtr);
49 if (PVHResetVectorData == 0) {
50 return EFI_NOT_FOUND;
51 }
52
53 pvh_start_info = (struct hvm_start_info *)(UINTN)PVHResetVectorData[0];
54 AcpiRsdpStructurePtr = (EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)(UINTN)pvh_start_info->rsdp_paddr;
55
56 // If XSDT table is found, just install its tables.
57 // Otherwise, try to find and install the RSDT tables.
58 //
59 if (AcpiRsdpStructurePtr->XsdtAddress) {
60 //
61 // Retrieve the addresses of XSDT and
62 // calculate the number of its table entries.
63 //
64 Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)
65 AcpiRsdpStructurePtr->XsdtAddress;
66 NumberOfTableEntries = (Xsdt->Length -
67 sizeof (EFI_ACPI_DESCRIPTION_HEADER)) /
68 sizeof (UINT64);
69
70 //
71 // Install ACPI tables found in XSDT.
72 //
73 for (Index = 0; Index < NumberOfTableEntries; Index++) {
74 //
75 // Get the table entry from XSDT
76 //
77 CurrentTableEntry = (VOID *)((UINT8 *)Xsdt +
78 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
79 Index * sizeof (UINT64));
80 CurrentTablePointer = (UINTN)*(UINT64 *)CurrentTableEntry;
81 CurrentTable = (EFI_ACPI_DESCRIPTION_HEADER *)CurrentTablePointer;
82
83 //
84 // Install the XSDT tables
85 //
86 Status = AcpiProtocol->InstallAcpiTable (
87 AcpiProtocol,
88 CurrentTable,
89 CurrentTable->Length,
90 &TableHandle
91 );
92
93 if (EFI_ERROR (Status)) {
94 ASSERT_EFI_ERROR (Status);
95 return Status;
96 }
97
98 //
99 // Get the X-DSDT table address from the table FADT
100 //
101 if (!AsciiStrnCmp ((CHAR8 *)&CurrentTable->Signature, "FACP", 4)) {
102 Fadt2Table = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)
103 (UINTN)CurrentTablePointer;
104 DsdtTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)Fadt2Table->XDsdt;
105 }
106 }
107 } else {
108 return EFI_NOT_FOUND;
109 }
110
111 //
112 // Install DSDT table. If we reached this point without finding the DSDT,
113 // then we're out of sync with the hypervisor, and cannot continue.
114 //
115 if (DsdtTable == NULL) {
116 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));
117 ASSERT (FALSE);
118 CpuDeadLoop ();
119 }
120
121 Status = AcpiProtocol->InstallAcpiTable (
122 AcpiProtocol,
123 DsdtTable,
124 DsdtTable->Length,
125 &TableHandle
126 );
127 if (EFI_ERROR (Status)) {
128 ASSERT_EFI_ERROR (Status);
129 return Status;
130 }
131
132 return EFI_SUCCESS;
133 }