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