TianoCore EDK2 master
Loading...
Searching...
No Matches
TdxAcpiTable.c
Go to the documentation of this file.
1
12#include <Library/DebugLib.h>
13#include <Library/BaseLib.h>
18#include <Library/PcdLib.h>
20#include <Library/TdxLib.h>
23#include <Protocol/AcpiTable.h>
25#include <Library/UefiLib.h>
27#include <Protocol/Cpu.h>
28#include <Uefi.h>
29#include <TdxAcpiTable.h>
30
43EFIAPI
45 VOID
46 )
47{
49 VOID *ApLoopFunc;
50 UINT32 RelocationPages;
51 MP_RELOCATION_MAP RelocationMap;
52 MP_WAKEUP_MAILBOX *RelocatedMailBox;
53 EFI_STATUS Status;
54
55 Address = 0;
56 ApLoopFunc = NULL;
57 ZeroMem (&RelocationMap, sizeof (RelocationMap));
58
59 //
60 // Get information needed to setup aps running in their
61 // run loop in allocated acpi reserved memory
62 // Add another page for mailbox
63 //
64 AsmGetRelocationMap (&RelocationMap);
65 if ((RelocationMap.RelocateApLoopFuncAddress == 0) || (RelocationMap.RelocateApLoopFuncSize == 0)) {
66 DEBUG ((DEBUG_ERROR, "Failed to get the RelocationMap.\n"));
67 return 0;
68 }
69
70 RelocationPages = EFI_SIZE_TO_PAGES ((UINT32)RelocationMap.RelocateApLoopFuncSize) + 1;
71
72 Status = gBS->AllocatePages (AllocateAnyPages, EfiACPIMemoryNVS, RelocationPages, &Address);
73 if (EFI_ERROR (Status)) {
74 DEBUG ((DEBUG_ERROR, "Failed to allocate pages for MailboxRelocation. %r\n", Status));
75 return 0;
76 }
77
78 ZeroMem ((VOID *)Address, EFI_PAGES_TO_SIZE (RelocationPages));
79
80 ApLoopFunc = (VOID *)((UINTN)Address + EFI_PAGE_SIZE);
81
82 CopyMem (
83 ApLoopFunc,
84 RelocationMap.RelocateApLoopFuncAddress,
85 RelocationMap.RelocateApLoopFuncSize
86 );
87
88 DEBUG ((
89 DEBUG_INFO,
90 "Ap Relocation: mailbox %llx, loop %p\n",
91 Address,
92 ApLoopFunc
93 ));
94
95 //
96 // Initialize mailbox
97 //
98 RelocatedMailBox = (MP_WAKEUP_MAILBOX *)Address;
99 RelocatedMailBox->Command = MpProtectedModeWakeupCommandNoop;
100 RelocatedMailBox->ApicId = MP_CPU_PROTECTED_MODE_MAILBOX_APICID_INVALID;
101 RelocatedMailBox->WakeUpVector = 0;
102
103 //
104 // Wakup APs and have been move to the finalized run loop
105 // They will spin until guest OS wakes them
106 //
108
110 MpProtectedModeWakeupCommandWakeup,
111 (UINT64)ApLoopFunc,
112 (UINT64)RelocatedMailBox,
113 0,
114 0,
115 0
116 );
117
118 return Address;
119}
120
127VOID
128EFIAPI
130 IN EFI_EVENT Event,
131 IN VOID *Context
132 )
133{
134 EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol;
135 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
136 EFI_STATUS Status;
137 UINTN Index;
138 EFI_ACPI_SDT_HEADER *Table;
139 EFI_ACPI_TABLE_VERSION Version;
140 UINTN OriginalTableKey;
141 UINTN NewTableKey;
142 UINT8 *NewMadtTable;
143 UINTN NewMadtTableLength;
144 EFI_PHYSICAL_ADDRESS RelocateMailboxAddress;
147
148 Index = 0;
149 NewMadtTable = NULL;
150 MadtHeader = NULL;
151
152 Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (void **)&AcpiSdtProtocol);
153 if (EFI_ERROR (Status)) {
154 DEBUG ((DEBUG_ERROR, "Unable to locate ACPI SDT protocol.\n"));
155 return;
156 }
157
158 RelocateMailboxAddress = RelocateMailbox ();
159 if (RelocateMailboxAddress == 0) {
160 ASSERT (FALSE);
161 DEBUG ((DEBUG_ERROR, "Failed to relocate Td mailbox\n"));
162 return;
163 }
164
165 do {
166 Status = AcpiSdtProtocol->GetAcpiTable (Index, &Table, &Version, &OriginalTableKey);
167
168 if (!EFI_ERROR (Status) && (Table->Signature == EFI_ACPI_1_0_APIC_SIGNATURE)) {
169 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (void **)&AcpiTableProtocol);
170 if (EFI_ERROR (Status)) {
171 DEBUG ((DEBUG_ERROR, "Unable to locate ACPI Table protocol.\n"));
172 break;
173 }
174
175 NewMadtTableLength = Table->Length + sizeof (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE);
176 NewMadtTable = AllocatePool (NewMadtTableLength);
177 if (NewMadtTable == NULL) {
178 DEBUG ((DEBUG_ERROR, "%a: OUT_OF_SOURCES error.\n", __func__));
179 break;
180 }
181
182 CopyMem (NewMadtTable, (UINT8 *)Table, Table->Length);
183 MadtHeader = (EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)NewMadtTable;
184 MadtHeader->Header.Length = (UINT32)NewMadtTableLength;
185
186 MadtMpWk = (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE *)(NewMadtTable + Table->Length);
187 MadtMpWk->Type = EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP;
188 MadtMpWk->Length = sizeof (EFI_ACPI_6_4_MULTIPROCESSOR_WAKEUP_STRUCTURE);
189 MadtMpWk->MailBoxVersion = 0;
190 MadtMpWk->Reserved = 0;
191 MadtMpWk->MailBoxAddress = RelocateMailboxAddress;
192
193 Status = AcpiTableProtocol->InstallAcpiTable (AcpiTableProtocol, NewMadtTable, NewMadtTableLength, &NewTableKey);
194 if (EFI_ERROR (Status)) {
195 DEBUG ((DEBUG_ERROR, "Failed to install new MADT table. %r\n", Status));
196 break;
197 }
198
199 Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, OriginalTableKey);
200 if (EFI_ERROR (Status)) {
201 DEBUG ((DEBUG_ERROR, "Uninstall old MADT table error.\n"));
202 }
203
204 break;
205 }
206
207 Index++;
208 } while (!EFI_ERROR (Status));
209
210 if (NewMadtTable != NULL) {
211 FreePool (NewMadtTable);
212 }
213}
UINT64 UINTN
#define EFI_ACPI_1_0_APIC_SIGNATURE
Definition: Acpi10.h:627
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define NULL
Definition: Base.h:319
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_PHYSICAL_ADDRESS EFIAPI RelocateMailbox(VOID)
Definition: TdxAcpiTable.c:44
VOID EFIAPI AlterAcpiTable(IN EFI_EVENT Event, IN VOID *Context)
Definition: TdxAcpiTable.c:129
VOID EFIAPI MpSerializeStart(VOID)
Definition: TdxMailbox.c:98
VOID EFIAPI MpSendWakeupCommand(IN UINT16 Command, IN UINT64 WakeupVector, IN UINT64 WakeupArgs1, IN UINT64 WakeupArgs2, IN UINT64 WakeupArgs3, IN UINT64 WakeupArgs4)
Definition: TdxMailbox.c:66
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
EFI_BOOT_SERVICES * gBS
@ EfiACPIMemoryNVS
@ AllocateAnyPages
Definition: UefiSpec.h:33