]> git.proxmox.com Git - mirror_edk2.git/blame - ArmVirtPkg/CloudHvAcpiPlatformDxe/CloudHvAcpi.c
ArmVirtPkg: Install Acpi tables for Cloud Hypervisor
[mirror_edk2.git] / ArmVirtPkg / CloudHvAcpiPlatformDxe / CloudHvAcpi.c
CommitLineData
c28fc8ab
JW
1/** @file\r
2 Install Acpi tables for Cloud Hypervisor\r
3\r
4 Copyright (c) 2021, Arm Limited. All rights reserved.<BR>\r
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7**/\r
8\r
9#include <Library/BaseLib.h>\r
10#include <Library/MemoryAllocationLib.h>\r
11#include <IndustryStandard/Acpi63.h>\r
12#include <Protocol/AcpiTable.h>\r
13#include <Library/UefiBootServicesTableLib.h>\r
14#include <Library/UefiDriverEntryPoint.h>\r
15#include <Library/DebugLib.h>\r
16\r
17/**\r
18 Find Acpi table Protocol and return it\r
19\r
20 @return AcpiTable Protocol, which is used to handle Acpi Table, on SUCCESS or NULL on FAILURE.\r
21\r
22**/\r
23STATIC\r
24EFI_ACPI_TABLE_PROTOCOL *\r
25FindAcpiTableProtocol (\r
26 VOID\r
27 )\r
28{\r
29 EFI_STATUS Status;\r
30 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
31\r
32 Status = gBS->LocateProtocol (\r
33 &gEfiAcpiTableProtocolGuid,\r
34 NULL,\r
35 (VOID**)&AcpiTable\r
36 );\r
37 ASSERT_EFI_ERROR (Status);\r
38 return AcpiTable;\r
39}\r
40\r
41/** Install Acpi tables for Cloud Hypervisor\r
42\r
43 @param [in] AcpiProtocol Acpi Protocol which is used to install Acpi tables\r
44\r
45 @return EFI_SUCCESS The table was successfully inserted.\r
46 @return EFI_INVALID_PARAMETER Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL\r
47 and the size field embedded in the ACPI table pointed\r
48 by AcpiTablePtr or DsdtPtr are not in sync.\r
49 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
50 @return EFI_NOT_FOUND DSDT table not found.\r
51**/\r
52EFI_STATUS\r
53EFIAPI\r
54InstallCloudHvAcpiTables (\r
55 IN EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol\r
56 )\r
57{\r
58 UINTN InstalledKey;\r
59 UINTN TableSize;\r
60 UINTN AcpiTableLength;\r
61 UINT64 RsdpPtr;\r
62 UINT64 XsdtPtr;\r
63 UINT64 TableOffset;\r
64 UINT64 AcpiTablePtr;\r
65 UINT64 *DsdtPtr;\r
66 EFI_STATUS Status;\r
67\r
68 if (AcpiProtocol == NULL) {\r
69 return EFI_INVALID_PARAMETER;\r
70 }\r
71\r
72 RsdpPtr = PcdGet64 (PcdCloudHvAcpiRsdpBaseAddress);\r
73 XsdtPtr = ((EFI_ACPI_6_3_ROOT_SYSTEM_DESCRIPTION_POINTER *)RsdpPtr)->XsdtAddress;\r
74 AcpiTableLength = ((EFI_ACPI_COMMON_HEADER *)XsdtPtr)->Length;\r
75 TableOffset = sizeof (EFI_ACPI_DESCRIPTION_HEADER);\r
76 DsdtPtr = NULL;\r
77\r
78 while (TableOffset < AcpiTableLength) {\r
79 AcpiTablePtr = *(UINT64 *)(XsdtPtr + TableOffset);\r
80 TableSize = ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Length;\r
81\r
82 //\r
83 // Install ACPI tables from XSDT\r
84 //\r
85 Status = AcpiProtocol->InstallAcpiTable (\r
86 AcpiProtocol,\r
87 (VOID *)AcpiTablePtr,\r
88 TableSize,\r
89 &InstalledKey\r
90 );\r
91 if (EFI_ERROR (Status)) {\r
92 return Status;\r
93 }\r
94\r
95 //\r
96 // Get DSDT from FADT\r
97 //\r
98 if ((DsdtPtr == NULL) &&\r
99 (EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE ==\r
100 ((EFI_ACPI_COMMON_HEADER *)AcpiTablePtr)->Signature)) {\r
101 DsdtPtr = (UINT64 *)((EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE *)AcpiTablePtr)->XDsdt;\r
102 }\r
103\r
104 TableOffset += sizeof (UINT64);\r
105 } // while\r
106\r
107 if (DsdtPtr == NULL) {\r
108 DEBUG ((DEBUG_ERROR, "%a: no DSDT found\n", __FUNCTION__));\r
109 return EFI_NOT_FOUND;\r
110 }\r
111\r
112 //\r
113 // Install DSDT table\r
114 //\r
115 TableSize = ((EFI_ACPI_COMMON_HEADER *)DsdtPtr)->Length;\r
116 Status = AcpiProtocol->InstallAcpiTable (\r
117 AcpiProtocol,\r
118 DsdtPtr,\r
119 TableSize,\r
120 &InstalledKey\r
121 );\r
122\r
123 return Status;\r
124}\r
125\r
126/** Entry point for Cloud Hypervisor Platform Dxe\r
127\r
128 @param [in] ImageHandle Handle for this image.\r
129 @param [in] SystemTable Pointer to the EFI system table.\r
130\r
131 @return EFI_SUCCESS The table was successfully inserted.\r
132 @return EFI_INVALID_PARAMETER Either AcpiProtocol, AcpiTablePtr or DsdtPtr is NULL\r
133 and the size field embedded in the ACPI table pointed to\r
134 by AcpiTablePtr or DsdtPtr are not in sync.\r
135 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.\r
136 @return EFI_NOT_FOUND DSDT table not found\r
137**/\r
138EFI_STATUS\r
139EFIAPI\r
140CloudHvAcpiPlatformEntryPoint (\r
141 IN EFI_HANDLE ImageHandle,\r
142 IN EFI_SYSTEM_TABLE *SystemTable\r
143 )\r
144{\r
145 EFI_STATUS Status;\r
146\r
147 Status = InstallCloudHvAcpiTables (FindAcpiTableProtocol ());\r
148\r
149 if (EFI_ERROR (Status)) {\r
150 DEBUG ((\r
151 DEBUG_ERROR,\r
152 "%a: Fail to install Acpi table: %r\n",\r
153 __FUNCTION__,\r
154 Status\r
155 ));\r
156 CpuDeadLoop ();\r
157 }\r
158\r
159 return EFI_SUCCESS;\r
160}\r