]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/Acpi/AcpiSupportDxe/AcpiSupportAcpiSupportProtocol.c
InstallAcpiTable() - Do not update the checksum in the passed in buffer – the buffer...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / Acpi / AcpiSupportDxe / AcpiSupportAcpiSupportProtocol.c
1 /** @file
2 ACPI Support Protocol implementation
3
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution. The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 //
18 // Includes
19 //
20 #include "AcpiSupport.h"
21 //
22 // The maximum number of tables that pre-allocated.
23 //
24 UINTN mEfiAcpiMaxNumTables = EFI_ACPI_MAX_NUM_TABLES;
25 /**
26 This function adds an ACPI table to the table list. It will detect FACS and
27 allocate the correct type of memory and properly align the table.
28
29 @param AcpiSupportInstance Instance of the protocol.
30 @param Table Table to add.
31 @param Checksum Does the table require checksumming.
32 @param Version The version of the list to add the table to.
33 @param Handle Pointer for returning the handle.
34
35 @return EFI_SUCCESS The function completed successfully.
36 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
37 @return EFI_ABORTED The table is a duplicate of a table that is required
38 to be unique.
39 **/
40 EFI_STATUS
41 AddTableToList (
42 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance,
43 IN VOID *Table,
44 IN BOOLEAN Checksum,
45 IN EFI_ACPI_TABLE_VERSION Version,
46 OUT UINTN *Handle
47 );
48 /**
49 This function finds and removes the table specified by the handle.
50
51 @param AcpiSupportInstance Instance of the protocol.
52 @param Version Bitmask of which versions to remove.
53 @param Handle Table to remove.
54
55 @return EFI_SUCCESS The function completed successfully.
56 @return EFI_ABORTED An error occurred.
57 @return EFI_NOT_FOUND Handle not found in table list.
58 **/
59 EFI_STATUS
60 RemoveTableFromList (
61 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance,
62 IN EFI_ACPI_TABLE_VERSION Version,
63 IN UINTN Handle
64 );
65 /**
66 This function calculates and updates an UINT8 checksum.
67
68 @param Buffer Pointer to buffer to checksum
69 @param Size Number of bytes to checksum
70 @param ChecksumOffset Offset to place the checksum result in
71
72 @return EFI_SUCCESS The function completed successfully.
73 **/
74 EFI_STATUS
75 AcpiPlatformChecksum (
76 IN VOID *Buffer,
77 IN UINTN Size,
78 IN UINTN ChecksumOffset
79 );
80 /**
81 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
82
83 @param AcpiSupportInstance Protocol instance private data.
84
85 @return EFI_SUCCESS The function completed successfully.
86
87 **/
88 EFI_STATUS
89 ChecksumCommonTables (
90 IN OUT EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance
91 );
92
93 /**
94 This function returns a table specified by an index if it exists.
95
96 The function returns a buffer containing the table that the caller must free.
97 The function also returns a handle used to identify the table for update or
98 deletion using the SetAcpiTable function.
99
100 @param This Instance of the protocol.
101 @param Index Zero-based index of the table to retrieve.
102 @param Table Returned pointer to the table.
103 @param Version Versions that the table is currently used in.
104 @param Handle Handle of the table, used in updating tables.
105
106 @retval EFI_SUCCESS The function completed successfully.
107 @retval EFI_NOT_FOUND The requested table does not exist.
108
109 **/
110 EFI_STATUS
111 EFIAPI
112 GetAcpiTable (
113 IN EFI_ACPI_SUPPORT_PROTOCOL *This,
114 IN INTN Index,
115 OUT VOID **Table,
116 OUT EFI_ACPI_TABLE_VERSION *Version,
117 OUT UINTN *Handle
118 )
119
120 {
121 EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance;
122 INTN TempIndex;
123 LIST_ENTRY *CurrentLink;
124 LIST_ENTRY *StartLink;
125 EFI_ACPI_TABLE_LIST *CurrentTable;
126
127 //
128 // Check for invalid input parameters
129 //
130 ASSERT (This);
131 ASSERT (Table);
132 ASSERT (Handle);
133
134 //
135 // Get the instance of the protocol
136 //
137 AcpiSupportInstance = EFI_ACPI_SUPPORT_INSTANCE_FROM_ACPI_SUPPORT_THIS (This);
138
139 //
140 // Find the table
141 //
142 CurrentLink = AcpiSupportInstance->TableList.ForwardLink;
143 StartLink = &AcpiSupportInstance->TableList;
144 for (TempIndex = 0; (TempIndex < Index) && (CurrentLink != StartLink) && (CurrentLink != NULL); TempIndex++) {
145 CurrentLink = CurrentLink->ForwardLink;
146 }
147
148 if (TempIndex != Index || CurrentLink == StartLink) {
149 return EFI_NOT_FOUND;
150 }
151 //
152 // Get handle and version
153 //
154 CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);
155 *Handle = CurrentTable->Handle;
156 *Version = CurrentTable->Version;
157
158 //
159 // Copy the table
160 //
161 *Table = AllocateCopyPool (CurrentTable->Table->Length, CurrentTable->Table);
162 ASSERT (*Table);
163
164 return EFI_SUCCESS;
165 }
166 /**
167 This function adds, removes, or updates ACPI tables. If the address is not
168 null and the handle value is null, the table is added. If both the address and
169 handle are not null, the table at handle is updated with the table at address.
170 If the address is null and the handle is not, the table at handle is deleted.
171
172 @param This Pointer of the protocol.
173 @param Table Pointer to a table.
174 @param Checksum Boolean indicating if the checksum should be calculated.
175 @param Version Version(s) to set.
176 @param Handle Handle of the table.
177
178 @return EFI_SUCCESS The function completed successfully.
179 @return EFI_INVALID_PARAMETER Both the Table and *Handle were NULL.
180 @return EFI_ABORTED Could not complete the desired request.
181
182 **/
183 EFI_STATUS
184 EFIAPI
185 SetAcpiTable (
186 IN EFI_ACPI_SUPPORT_PROTOCOL *This,
187 IN VOID *Table OPTIONAL,
188 IN BOOLEAN Checksum,
189 IN EFI_ACPI_TABLE_VERSION Version,
190 IN OUT UINTN *Handle
191 )
192 {
193 EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance;
194 UINTN SavedHandle;
195 EFI_STATUS Status;
196
197 //
198 // Check for invalid input parameters
199 //
200 ASSERT (This);
201 ASSERT (Handle != NULL);
202
203 //
204 // Get the instance of the protocol
205 //
206 AcpiSupportInstance = EFI_ACPI_SUPPORT_INSTANCE_FROM_ACPI_SUPPORT_THIS (This);
207
208 //
209 // Initialize locals
210 //
211 //
212 // Determine desired action
213 //
214 if (*Handle == 0) {
215 if (Table == NULL) {
216 //
217 // Invalid parameter combination
218 //
219 return EFI_INVALID_PARAMETER;
220 } else {
221 //
222 // Add table
223 //
224 Status = AddTableToList (AcpiSupportInstance, Table, Checksum, Version, Handle);
225 }
226 } else {
227 if (Table != NULL) {
228 //
229 // Update table
230 //
231 //
232 // Delete the table list entry
233 //
234 Status = RemoveTableFromList (AcpiSupportInstance, Version, *Handle);
235 if (EFI_ERROR (Status)) {
236 //
237 // Should not get an error here ever, but abort if we do.
238 //
239 return EFI_ABORTED;
240 }
241 //
242 // Set the handle to replace the table at the same handle
243 //
244 SavedHandle = AcpiSupportInstance->CurrentHandle;
245 AcpiSupportInstance->CurrentHandle = *Handle;
246
247 //
248 // Add the table
249 //
250 Status = AddTableToList (AcpiSupportInstance, Table, Checksum, Version, Handle);
251
252 //
253 // Restore the saved current handle
254 //
255 AcpiSupportInstance->CurrentHandle = SavedHandle;
256 } else {
257 //
258 // Delete table
259 //
260 Status = RemoveTableFromList (AcpiSupportInstance, Version, *Handle);
261 }
262 }
263
264 if (EFI_ERROR (Status)) {
265 //
266 // Should not get an error here ever, but abort if we do.
267 //
268 return EFI_ABORTED;
269 }
270 //
271 // Done
272 //
273 return EFI_SUCCESS;
274 }
275 /**
276 This function publishes the specified versions of the ACPI tables by
277 installing EFI configuration table entries for them. Any combination of
278 table versions can be published.
279
280 @param This Pointer of the protocol.
281 @param Version Version(s) to publish.
282
283 @return EFI_SUCCESS The function completed successfully.
284 @return EFI_ABORTED The function could not complete successfully.
285
286 **/
287 EFI_STATUS
288 EFIAPI
289 PublishTables (
290 IN EFI_ACPI_SUPPORT_PROTOCOL *This,
291 IN EFI_ACPI_TABLE_VERSION Version
292 )
293 {
294 EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance;
295 EFI_STATUS Status;
296 UINT32 *CurrentRsdtEntry;
297 VOID *CurrentXsdtEntry;
298 UINT64 Buffer64;
299
300 //
301 // Get the instance of the protocol
302 //
303 AcpiSupportInstance = EFI_ACPI_SUPPORT_INSTANCE_FROM_ACPI_SUPPORT_THIS (This);
304
305 //
306 // Reorder tables as some operating systems don't seem to find the
307 // FADT correctly if it is not in the first few entries
308 //
309
310 //
311 // Add FADT as the first entry
312 //
313 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
314 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) AcpiSupportInstance->Rsdt1 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
315 *CurrentRsdtEntry = (UINT32) (UINTN) AcpiSupportInstance->Fadt1;
316 }
317 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 || (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
318 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) AcpiSupportInstance->Rsdt3 + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
319 *CurrentRsdtEntry = (UINT32) (UINTN) AcpiSupportInstance->Fadt3;
320 CurrentXsdtEntry = (VOID *) ((UINT8 *) AcpiSupportInstance->Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER));
321 //
322 // Add entry to XSDT, XSDT expects 64 bit pointers, but
323 // the table pointers in XSDT are not aligned on 8 byte boundary.
324 //
325 Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Fadt3;
326 CopyMem (
327 CurrentXsdtEntry,
328 &Buffer64,
329 sizeof (UINT64)
330 );
331 }
332
333 //
334 // Do checksum again because Dsdt/Xsdt is updated.
335 //
336 ChecksumCommonTables (AcpiSupportInstance);
337
338 //
339 // Add the RSD_PTR to the system table and store that we have installed the
340 // tables.
341 //
342 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && !AcpiSupportInstance->TablesInstalled1) {
343 Status = gBS->InstallConfigurationTable (&gEfiAcpi10TableGuid, AcpiSupportInstance->Rsdp1);
344 if (EFI_ERROR (Status)) {
345 return EFI_ABORTED;
346 }
347
348 AcpiSupportInstance->TablesInstalled1 = TRUE;
349 }
350
351 if (((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 || (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) &&
352 !AcpiSupportInstance->TablesInstalled3) {
353 Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, AcpiSupportInstance->Rsdp3);
354 if (EFI_ERROR (Status)) {
355 return EFI_ABORTED;
356 }
357
358 AcpiSupportInstance->TablesInstalled3= TRUE;
359 }
360
361 return EFI_SUCCESS;
362 }
363 /**
364 Installs an ACPI table into the RSDT/XSDT.
365 Note that the ACPI table should be checksumed before installing it.
366 Otherwise it will assert.
367
368 @param This Protocol instance pointer.
369 @param AcpiTableBuffer A pointer to a buffer containing the ACPI table to be installed.
370 @param AcpiTableBufferSize Specifies the size, in bytes, of the AcpiTableBuffer buffer.
371 @param TableKey Reurns a key to refer to the ACPI table.
372
373 @return EFI_SUCCESS The table was successfully inserted.
374 @return EFI_INVALID_PARAMETER Either AcpiTableBuffer is NULL, TableKey is NULL, or AcpiTableBufferSize
375 and the size field embedded in the ACPI table pointed to by AcpiTableBuffer
376 are not in sync.
377 @return EFI_OUT_OF_RESOURCES Insufficient resources exist to complete the request.
378
379 **/
380 EFI_STATUS
381 EFIAPI
382 InstallAcpiTable (
383 IN EFI_ACPI_TABLE_PROTOCOL *This,
384 IN VOID *AcpiTableBuffer,
385 IN UINTN AcpiTableBufferSize,
386 OUT UINTN *TableKey
387 )
388 {
389 EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance;
390 EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;
391 EFI_STATUS Status;
392 VOID *AcpiTableBufferConst;
393
394 //
395 // Check for invalid input parameters
396 //
397 if ((AcpiTableBuffer == NULL) || (TableKey == NULL)
398 || (((EFI_ACPI_DESCRIPTION_HEADER *) AcpiTableBuffer)->Length != AcpiTableBufferSize)) {
399 return EFI_INVALID_PARAMETER;
400 }
401
402 //
403 // Get the instance of the ACPI support protocol
404 //
405 AcpiSupportInstance = EFI_ACPI_TABLE_INSTANCE_FROM_ACPI_SUPPORT_THIS (This);
406 AcpiSupport = &AcpiSupportInstance->AcpiSupport;
407
408 //
409 // Install the ACPI table by using ACPI support protocol
410 //
411 AcpiTableBufferConst = AllocateCopyPool (AcpiTableBufferSize, AcpiTableBuffer);
412 *TableKey = 0;
413 Status = AcpiSupport->SetAcpiTable (
414 AcpiSupport,
415 AcpiTableBufferConst,
416 TRUE,
417 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,
418 TableKey
419 );
420 if (!EFI_ERROR (Status)) {
421 Status = AcpiSupport->PublishTables (
422 AcpiSupport,
423 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0
424 );
425 }
426 FreePool (AcpiTableBufferConst);
427
428 return Status;
429 }
430 /**
431 Removes an ACPI table from the RSDT/XSDT.
432
433 @param This Protocol instance pointer.
434 @param TableKey Specifies the table to uninstall. The key was returned from InstallAcpiTable().
435
436 @return EFI_SUCCESS The table was successfully uninstalled.
437 @return EFI_NOT_FOUND TableKey does not refer to a valid key for a table entry.
438
439 **/
440 EFI_STATUS
441 EFIAPI
442 UninstallAcpiTable (
443 IN EFI_ACPI_TABLE_PROTOCOL *This,
444 IN UINTN TableKey
445 )
446 {
447 EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance;
448 EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;
449 EFI_STATUS Status;
450
451 //
452 // Get the instance of the ACPI support protocol
453 //
454 AcpiSupportInstance = EFI_ACPI_TABLE_INSTANCE_FROM_ACPI_SUPPORT_THIS (This);
455 AcpiSupport = &AcpiSupportInstance->AcpiSupport;
456
457 //
458 // Uninstall the ACPI table by using ACPI support protocol
459 //
460 Status = AcpiSupport->SetAcpiTable (
461 AcpiSupport,
462 NULL,
463 FALSE,
464 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0,
465 &TableKey
466 );
467 if (!EFI_ERROR (Status)) {
468 Status = AcpiSupport->PublishTables (
469 AcpiSupport,
470 EFI_ACPI_TABLE_VERSION_1_0B | EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0
471 );
472 }
473
474 if (EFI_ERROR (Status)) {
475 return EFI_NOT_FOUND;
476 } else {
477 return EFI_SUCCESS;
478 }
479 }
480 /**
481 If the number of APCI tables exceeds the preallocated max table number, enlarge the table buffer.
482
483 @param AcpiSupportInstance ACPI support protocol instance data structure
484
485 @return EFI_SUCCESS reallocate the table beffer successfully.
486 @return EFI_OUT_OF_RESOURCES Unable to allocate required resources.
487
488 **/
489 EFI_STATUS
490 ReallocateAcpiTableBuffer (
491 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance
492 )
493 {
494 UINTN NewMaxTableNumber;
495 UINTN TotalSize;
496 UINT8 *Pointer;
497 EFI_PHYSICAL_ADDRESS PageAddress;
498 EFI_ACPI_SUPPORT_INSTANCE TempPrivateData;
499 EFI_STATUS Status;
500 UINT64 CurrentData;
501
502 CopyMem (&TempPrivateData, AcpiSupportInstance, sizeof (EFI_ACPI_SUPPORT_INSTANCE));
503 //
504 // Enlarge the max table number from mEfiAcpiMaxNumTables to mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES
505 //
506 NewMaxTableNumber = mEfiAcpiMaxNumTables + EFI_ACPI_MAX_NUM_TABLES;
507 //
508 // Create RSDT, XSDT structures and allocate buffers.
509 //
510 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
511 NewMaxTableNumber * sizeof (UINT32) +
512 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
513 NewMaxTableNumber * sizeof (UINT32) +
514 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
515 NewMaxTableNumber * sizeof (UINT64);
516
517 //
518 // Allocate memory in the lower 32 bit of address range for
519 // compatibility with ACPI 1.0 OS.
520 //
521 // This is done because ACPI 1.0 pointers are 32 bit values.
522 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
523 // There is no architectural reason these should be below 4GB, it is purely
524 // for convenience of implementation that we force memory below 4GB.
525 //
526 PageAddress = 0xFFFFFFFF;
527 Status = gBS->AllocatePages (
528 AllocateMaxAddress,
529 EfiACPIReclaimMemory,
530 EFI_SIZE_TO_PAGES (TotalSize),
531 &PageAddress
532 );
533
534 if (EFI_ERROR (Status)) {
535 return EFI_OUT_OF_RESOURCES;
536 }
537
538 Pointer = (UINT8 *) (UINTN) PageAddress;
539 ZeroMem (Pointer, TotalSize);
540
541 AcpiSupportInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
542 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));
543 AcpiSupportInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
544 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + NewMaxTableNumber * sizeof (UINT32));
545 AcpiSupportInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
546
547 //
548 // Update RSDP to point to the new Rsdt and Xsdt address.
549 //
550 AcpiSupportInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiSupportInstance->Rsdt1;
551 AcpiSupportInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiSupportInstance->Rsdt3;
552 CurrentData = (UINT64) (UINTN) AcpiSupportInstance->Xsdt;
553 CopyMem (&AcpiSupportInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));
554
555 //
556 // copy the original Rsdt1, Rsdt3 and Xsdt structure to new buffer
557 //
558 CopyMem (AcpiSupportInstance->Rsdt1, TempPrivateData.Rsdt1, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));
559 CopyMem (AcpiSupportInstance->Rsdt3, TempPrivateData.Rsdt3, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT32)));
560 CopyMem (AcpiSupportInstance->Xsdt, TempPrivateData.Xsdt, (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + mEfiAcpiMaxNumTables * sizeof (UINT64)));
561
562 //
563 // Calculate orignal ACPI table buffer size
564 //
565 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
566 mEfiAcpiMaxNumTables * sizeof (UINT32) +
567 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
568 mEfiAcpiMaxNumTables * sizeof (UINT32) +
569 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
570 mEfiAcpiMaxNumTables * sizeof (UINT64);
571 gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TempPrivateData.Rsdt1, EFI_SIZE_TO_PAGES (TotalSize));
572
573 //
574 // Update the Max ACPI table number
575 //
576 mEfiAcpiMaxNumTables = NewMaxTableNumber;
577 return EFI_SUCCESS;
578 }
579 /**
580 This function adds an ACPI table to the table list. It will detect FACS and
581 allocate the correct type of memory and properly align the table.
582
583 @param AcpiSupportInstance Instance of the protocol.
584 @param Table Table to add.
585 @param Checksum Does the table require checksumming.
586 @param Version The version of the list to add the table to.
587 @param Handle Pointer for returning the handle.
588
589 @return EFI_SUCCESS The function completed successfully.
590 @return EFI_OUT_OF_RESOURCES Could not allocate a required resource.
591 @return EFI_ABORTED The table is a duplicate of a table that is required
592 to be unique.
593 **/
594 EFI_STATUS
595 AddTableToList (
596 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance,
597 IN VOID *Table,
598 IN BOOLEAN Checksum,
599 IN EFI_ACPI_TABLE_VERSION Version,
600 OUT UINTN *Handle
601 )
602 {
603 EFI_STATUS Status;
604 EFI_ACPI_TABLE_LIST *CurrentTableList;
605 UINT32 CurrentTableSignature;
606 UINT32 CurrentTableSize;
607 UINT32 *CurrentRsdtEntry;
608 VOID *CurrentXsdtEntry;
609 UINT64 Buffer64;
610 BOOLEAN AddToRsdt;
611
612 //
613 // Check for invalid input parameters
614 //
615 ASSERT (AcpiSupportInstance);
616 ASSERT (Table);
617 ASSERT (Handle);
618
619 //
620 // Init locals
621 //
622 AddToRsdt = TRUE;
623
624 //
625 // Create a new list entry
626 //
627 CurrentTableList = AllocatePool (sizeof (EFI_ACPI_TABLE_LIST));
628 ASSERT (CurrentTableList);
629
630 //
631 // Determine table type and size
632 //
633 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table)->Signature;
634 CurrentTableSize = ((EFI_ACPI_COMMON_HEADER *) Table)->Length;
635
636 //
637 // Allocate a buffer for the table. All tables are allocated in the lower 32 bits of address space
638 // for backwards compatibility with ACPI 1.0 OS.
639 //
640 // This is done because ACPI 1.0 pointers are 32 bit values.
641 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
642 // There is no architectural reason these should be below 4GB, it is purely
643 // for convenience of implementation that we force memory below 4GB.
644 //
645 CurrentTableList->PageAddress = 0xFFFFFFFF;
646 CurrentTableList->NumberOfPages = EFI_SIZE_TO_PAGES (CurrentTableSize);
647
648 //
649 // Allocation memory type depends on the type of the table
650 //
651 if ((CurrentTableSignature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
652 (CurrentTableSignature == EFI_ACPI_4_0_UEFI_ACPI_DATA_TABLE_SIGNATURE)) {
653 //
654 // Allocate memory for the FACS. This structure must be aligned
655 // on a 64 byte boundary and must be ACPI NVS memory.
656 // Using AllocatePages should ensure that it is always aligned.
657 // Do not change signature for new ACPI version because they are same.
658 //
659 // UEFI table also need to be in ACPI NVS memory, because some data field
660 // could be updated by OS present agent. For example, BufferPtrAddress in
661 // SMM communication ACPI table.
662 //
663 ASSERT ((EFI_PAGE_SIZE % 64) == 0);
664 Status = gBS->AllocatePages (
665 AllocateMaxAddress,
666 EfiACPIMemoryNVS,
667 CurrentTableList->NumberOfPages,
668 &CurrentTableList->PageAddress
669 );
670 } else {
671 //
672 // All other tables are ACPI reclaim memory, no alignment requirements.
673 //
674 Status = gBS->AllocatePages (
675 AllocateMaxAddress,
676 EfiACPIReclaimMemory,
677 CurrentTableList->NumberOfPages,
678 &CurrentTableList->PageAddress
679 );
680 }
681 //
682 // Check return value from memory alloc.
683 //
684 if (EFI_ERROR (Status)) {
685 gBS->FreePool (CurrentTableList);
686 return EFI_OUT_OF_RESOURCES;
687 }
688 //
689 // Update the table pointer with the allocated memory start
690 //
691 CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *) (UINTN) CurrentTableList->PageAddress;
692
693 //
694 // Initialize the table contents
695 //
696 CurrentTableList->Signature = EFI_ACPI_TABLE_LIST_SIGNATURE;
697 CopyMem (CurrentTableList->Table, Table, CurrentTableSize);
698 CurrentTableList->Handle = AcpiSupportInstance->CurrentHandle++;
699 *Handle = CurrentTableList->Handle;
700 CurrentTableList->Version = Version;
701
702 //
703 // Update internal pointers if this is a required table. If it is a required
704 // table and a table of that type already exists, return an error.
705 //
706 // Calculate the checksum if the table is not FACS.
707 //
708 switch (CurrentTableSignature) {
709
710 case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
711 //
712 // We don't add the FADT in the standard way because some
713 // OS expect the FADT to be early in the table list.
714 // So we always add it as the first element in the list.
715 //
716 AddToRsdt = FALSE;
717
718 //
719 // Check that the table has not been previously added.
720 //
721 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiSupportInstance->Fadt1 != NULL) ||
722 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiSupportInstance->Fadt3 != NULL) ||
723 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiSupportInstance->Fadt3 != NULL)
724 ) {
725 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);
726 gBS->FreePool (CurrentTableList);
727 return EFI_ABORTED;
728 }
729 //
730 // Add the table to the appropriate table version
731 //
732 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
733 //
734 // Save a pointer to the table
735 //
736 AcpiSupportInstance->Fadt1 = (EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE *) CurrentTableList->Table;
737
738 //
739 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
740 //
741 AcpiSupportInstance->Fadt1->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs1;
742 AcpiSupportInstance->Fadt1->Dsdt = (UINT32) (UINTN) AcpiSupportInstance->Dsdt1;
743
744 //
745 // RSDP OEM information is updated to match the FADT OEM information
746 //
747 CopyMem (
748 &AcpiSupportInstance->Rsdp1->OemId,
749 &AcpiSupportInstance->Fadt1->Header.OemId,
750 6
751 );
752
753 //
754 // RSDT OEM information is updated to match the FADT OEM information.
755 //
756 CopyMem (
757 &AcpiSupportInstance->Rsdt1->OemId,
758 &AcpiSupportInstance->Fadt1->Header.OemId,
759 6
760 );
761
762 CopyMem (
763 &AcpiSupportInstance->Rsdt1->OemTableId,
764 &AcpiSupportInstance->Fadt1->Header.OemTableId,
765 sizeof (UINT64)
766 );
767 AcpiSupportInstance->Rsdt1->OemRevision = AcpiSupportInstance->Fadt1->Header.OemRevision;
768 }
769
770 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
771 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
772 //
773 // Save a pointer to the table
774 //
775 AcpiSupportInstance->Fadt3 = (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) CurrentTableList->Table;
776
777 //
778 // Update pointers in FADT. If tables don't exist this will put NULL pointers there.
779 //
780 AcpiSupportInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs3;
781 Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Facs3;
782 CopyMem (
783 &AcpiSupportInstance->Fadt3->XFirmwareCtrl,
784 &Buffer64,
785 sizeof (UINT64)
786 );
787 AcpiSupportInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiSupportInstance->Dsdt3;
788 Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Dsdt3;
789 CopyMem (
790 &AcpiSupportInstance->Fadt3->XDsdt,
791 &Buffer64,
792 sizeof (UINT64)
793 );
794
795 //
796 // RSDP OEM information is updated to match the FADT OEM information
797 //
798 CopyMem (
799 &AcpiSupportInstance->Rsdp3->OemId,
800 &AcpiSupportInstance->Fadt3->Header.OemId,
801 6
802 );
803
804 //
805 // RSDT OEM information is updated to match FADT OEM information.
806 //
807 CopyMem (
808 &AcpiSupportInstance->Rsdt3->OemId,
809 &AcpiSupportInstance->Fadt3->Header.OemId,
810 6
811 );
812 CopyMem (
813 &AcpiSupportInstance->Rsdt3->OemTableId,
814 &AcpiSupportInstance->Fadt3->Header.OemTableId,
815 sizeof (UINT64)
816 );
817 AcpiSupportInstance->Rsdt3->OemRevision = AcpiSupportInstance->Fadt3->Header.OemRevision;
818
819 //
820 // XSDT OEM information is updated to match FADT OEM information.
821 //
822 CopyMem (
823 &AcpiSupportInstance->Xsdt->OemId,
824 &AcpiSupportInstance->Fadt3->Header.OemId,
825 6
826 );
827 CopyMem (
828 &AcpiSupportInstance->Xsdt->OemTableId,
829 &AcpiSupportInstance->Fadt3->Header.OemTableId,
830 sizeof (UINT64)
831 );
832 AcpiSupportInstance->Xsdt->OemRevision = AcpiSupportInstance->Fadt3->Header.OemRevision;
833 }
834
835 //
836 // Checksum the table
837 //
838 if (Checksum) {
839 AcpiPlatformChecksum (
840 CurrentTableList->Table,
841 CurrentTableList->Table->Length,
842 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
843 Checksum)
844 );
845 }
846 break;
847
848 case EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
849 //
850 // Check that the table has not been previously added.
851 //
852 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiSupportInstance->Facs1 != NULL) ||
853 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiSupportInstance->Facs3 != NULL) ||
854 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiSupportInstance->Facs3 != NULL)
855 ) {
856 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);
857 gBS->FreePool (CurrentTableList);
858 return EFI_ABORTED;
859 }
860 //
861 // FACS is referenced by FADT and is not part of RSDT
862 //
863 AddToRsdt = FALSE;
864
865 //
866 // Add the table to the appropriate table version
867 //
868 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
869 //
870 // Save a pointer to the table
871 //
872 AcpiSupportInstance->Facs1 = (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;
873
874 //
875 // If FADT already exists, update table pointers.
876 //
877 if (AcpiSupportInstance->Fadt1 != NULL) {
878 AcpiSupportInstance->Fadt1->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs1;
879
880 //
881 // Checksum FADT table
882 //
883 AcpiPlatformChecksum (
884 AcpiSupportInstance->Fadt1,
885 AcpiSupportInstance->Fadt1->Header.Length,
886 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
887 Checksum)
888 );
889 }
890 }
891
892 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
893 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
894 //
895 // Save a pointer to the table
896 //
897 AcpiSupportInstance->Facs3 = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *) CurrentTableList->Table;
898
899 //
900 // If FADT already exists, update table pointers.
901 //
902 if (AcpiSupportInstance->Fadt3 != NULL) {
903 AcpiSupportInstance->Fadt3->FirmwareCtrl = (UINT32) (UINTN) AcpiSupportInstance->Facs3;
904 Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Facs3;
905 CopyMem (
906 &AcpiSupportInstance->Fadt3->XFirmwareCtrl,
907 &Buffer64,
908 sizeof (UINT64)
909 );
910
911 //
912 // Checksum FADT table
913 //
914 AcpiPlatformChecksum (
915 AcpiSupportInstance->Fadt3,
916 AcpiSupportInstance->Fadt3->Header.Length,
917 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
918 Checksum)
919 );
920 }
921 }
922
923 break;
924
925 case EFI_ACPI_1_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
926 //
927 // Check that the table has not been previously added.
928 //
929 if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiSupportInstance->Dsdt1 != NULL) ||
930 ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 && AcpiSupportInstance->Dsdt3 != NULL) ||
931 ((Version & EFI_ACPI_TABLE_VERSION_3_0) != 0 && AcpiSupportInstance->Dsdt3 != NULL)
932 ) {
933 gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);
934 gBS->FreePool (CurrentTableList);
935 return EFI_ABORTED;
936 }
937 //
938 // DSDT is referenced by FADT and is not part of RSDT
939 //
940 AddToRsdt = FALSE;
941
942 //
943 // Add the table to the appropriate table version
944 //
945 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
946 //
947 // Save a pointer to the table
948 //
949 AcpiSupportInstance->Dsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;
950
951 //
952 // If FADT already exists, update table pointers.
953 //
954 if (AcpiSupportInstance->Fadt1 != NULL) {
955 AcpiSupportInstance->Fadt1->Dsdt = (UINT32) (UINTN) AcpiSupportInstance->Dsdt1;
956
957 //
958 // Checksum FADT table
959 //
960 AcpiPlatformChecksum (
961 AcpiSupportInstance->Fadt1,
962 AcpiSupportInstance->Fadt1->Header.Length,
963 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
964 Checksum)
965 );
966 }
967 }
968
969 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
970 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
971 //
972 // Save a pointer to the table
973 //
974 AcpiSupportInstance->Dsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) CurrentTableList->Table;
975
976 //
977 // If FADT already exists, update table pointers.
978 //
979 if (AcpiSupportInstance->Fadt3 != NULL) {
980 AcpiSupportInstance->Fadt3->Dsdt = (UINT32) (UINTN) AcpiSupportInstance->Dsdt3;
981 Buffer64 = (UINT64) (UINTN) AcpiSupportInstance->Dsdt3;
982 CopyMem (
983 &AcpiSupportInstance->Fadt3->XDsdt,
984 &Buffer64,
985 sizeof (UINT64)
986 );
987
988 //
989 // Checksum FADT table
990 //
991 AcpiPlatformChecksum (
992 AcpiSupportInstance->Fadt3,
993 AcpiSupportInstance->Fadt3->Header.Length,
994 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
995 Checksum)
996 );
997 }
998 }
999 //
1000 // Checksum the table
1001 //
1002 if (Checksum) {
1003 AcpiPlatformChecksum (
1004 CurrentTableList->Table,
1005 CurrentTableList->Table->Length,
1006 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1007 Checksum)
1008 );
1009 }
1010 break;
1011
1012 default:
1013 //
1014 // Checksum the table
1015 //
1016 if (Checksum) {
1017 AcpiPlatformChecksum (
1018 CurrentTableList->Table,
1019 CurrentTableList->Table->Length,
1020 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1021 Checksum)
1022 );
1023 }
1024 break;
1025 }
1026 //
1027 // Add the table to the current list of tables
1028 //
1029 InsertTailList (&AcpiSupportInstance->TableList, &CurrentTableList->Link);
1030
1031 //
1032 // Add the table to RSDT and/or XSDT table entry lists.
1033 //
1034 //
1035 // Add to ACPI 1.0b table tree
1036 //
1037 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1038 if (AddToRsdt) {
1039 //
1040 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1041 //
1042 if (AcpiSupportInstance->NumberOfTableEntries1 >= mEfiAcpiMaxNumTables) {
1043 Status = ReallocateAcpiTableBuffer (AcpiSupportInstance);
1044 ASSERT_EFI_ERROR (Status);
1045 }
1046 CurrentRsdtEntry = (UINT32 *)
1047 (
1048 (UINT8 *) AcpiSupportInstance->Rsdt1 +
1049 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
1050 AcpiSupportInstance->NumberOfTableEntries1 *
1051 sizeof (UINT32)
1052 );
1053
1054 //
1055 // Add entry to the RSDT unless its the FACS or DSDT
1056 //
1057 *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;
1058
1059 //
1060 // Update RSDT length
1061 //
1062 AcpiSupportInstance->Rsdt1->Length = AcpiSupportInstance->Rsdt1->Length + sizeof (UINT32);
1063
1064 AcpiSupportInstance->NumberOfTableEntries1++;
1065 }
1066 }
1067 //
1068 // Add to ACPI 2.0/3.0 table tree
1069 //
1070 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 || (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1071 if (AddToRsdt) {
1072 //
1073 // If the table number exceed the gEfiAcpiMaxNumTables, enlarge the table buffer
1074 //
1075 if (AcpiSupportInstance->NumberOfTableEntries3 >= mEfiAcpiMaxNumTables) {
1076 Status = ReallocateAcpiTableBuffer (AcpiSupportInstance);
1077 ASSERT_EFI_ERROR (Status);
1078 }
1079 //
1080 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1081 // If it becomes necessary to maintain separate table lists, changes will be required.
1082 //
1083 CurrentRsdtEntry = (UINT32 *)
1084 (
1085 (UINT8 *) AcpiSupportInstance->Rsdt3 +
1086 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
1087 AcpiSupportInstance->NumberOfTableEntries3 *
1088 sizeof (UINT32)
1089 );
1090
1091 //
1092 // This pointer must not be directly dereferenced as the XSDT entries may not
1093 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1094 //
1095 CurrentXsdtEntry = (VOID *)
1096 (
1097 (UINT8 *) AcpiSupportInstance->Xsdt +
1098 sizeof (EFI_ACPI_DESCRIPTION_HEADER) +
1099 AcpiSupportInstance->NumberOfTableEntries3 *
1100 sizeof (UINT64)
1101 );
1102
1103 //
1104 // Add entry to the RSDT
1105 //
1106 *CurrentRsdtEntry = (UINT32) (UINTN) CurrentTableList->Table;
1107
1108 //
1109 // Update RSDT length
1110 //
1111 AcpiSupportInstance->Rsdt3->Length = AcpiSupportInstance->Rsdt3->Length + sizeof (UINT32);
1112
1113 //
1114 // Add entry to XSDT, XSDT expects 64 bit pointers, but
1115 // the table pointers in XSDT are not aligned on 8 byte boundary.
1116 //
1117 Buffer64 = (UINT64) (UINTN) CurrentTableList->Table;
1118 CopyMem (
1119 CurrentXsdtEntry,
1120 &Buffer64,
1121 sizeof (UINT64)
1122 );
1123
1124 //
1125 // Update length
1126 //
1127 AcpiSupportInstance->Xsdt->Length = AcpiSupportInstance->Xsdt->Length + sizeof (UINT64);
1128
1129 AcpiSupportInstance->NumberOfTableEntries3++;
1130 }
1131 }
1132
1133 ChecksumCommonTables (AcpiSupportInstance);
1134 return EFI_SUCCESS;
1135 }
1136 /**
1137 This function finds the table specified by the handle and returns a pointer to it.
1138 If the handle is not found, EFI_NOT_FOUND is returned and the contents of Table are
1139 undefined.
1140
1141 @param Handle Table to find.
1142 @param TableList Table list to search
1143 @param Table Pointer to table found.
1144
1145 @return EFI_SUCCESS The function completed successfully.
1146 @return EFI_NOT_FOUND No table found matching the handle specified.
1147
1148 **/
1149 EFI_STATUS
1150 FindTableByHandle (
1151 IN UINTN Handle,
1152 IN LIST_ENTRY *TableList,
1153 OUT EFI_ACPI_TABLE_LIST **Table
1154 )
1155 {
1156 LIST_ENTRY *CurrentLink;
1157 EFI_ACPI_TABLE_LIST *CurrentTable;
1158
1159 //
1160 // Check for invalid input parameters
1161 //
1162 ASSERT (Table);
1163
1164 //
1165 // Find the table
1166 //
1167 CurrentLink = TableList->ForwardLink;
1168
1169 while (CurrentLink != TableList) {
1170 CurrentTable = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);
1171 if (CurrentTable->Handle == Handle) {
1172 //
1173 // Found handle, so return this table.
1174 //
1175 *Table = CurrentTable;
1176 return EFI_SUCCESS;
1177 }
1178
1179 CurrentLink = CurrentLink->ForwardLink;
1180 }
1181 //
1182 // Table not found
1183 //
1184 return EFI_NOT_FOUND;
1185 }
1186 /**
1187 This function removes a basic table from the RSDT and/or XSDT.
1188 For Acpi 1.0 tables, pass in the Rsdt.
1189 For Acpi 2.0 tables, pass in both Rsdt and Xsdt.
1190
1191 @param Table Pointer to table found.
1192 @param NumberOfTableEntries Current number of table entries in the RSDT/XSDT
1193 @param Rsdt Pointer to the RSDT to remove from
1194 @param Xsdt Pointer to the Xsdt to remove from
1195
1196 @return EFI_SUCCESS The function completed successfully.
1197 @return EFI_INVALID_PARAMETER The table was not found in both Rsdt and Xsdt.
1198
1199 **/
1200 EFI_STATUS
1201 RemoveTableFromRsdt (
1202 IN OUT EFI_ACPI_TABLE_LIST * Table,
1203 IN OUT UINTN *NumberOfTableEntries,
1204 IN OUT EFI_ACPI_DESCRIPTION_HEADER * Rsdt,
1205 IN OUT EFI_ACPI_DESCRIPTION_HEADER * Xsdt OPTIONAL
1206 )
1207 {
1208 UINT32 *CurrentRsdtEntry;
1209 VOID *CurrentXsdtEntry;
1210 UINT64 CurrentTablePointer64;
1211 UINTN TempIndex;
1212
1213 //
1214 // Check for invalid input parameters
1215 //
1216 ASSERT (Table);
1217 ASSERT (NumberOfTableEntries);
1218 ASSERT (Rsdt);
1219
1220 //
1221 // Find the table entry in the RSDT and XSDT
1222 //
1223 for (TempIndex = 0; TempIndex < *NumberOfTableEntries; TempIndex++) {
1224 //
1225 // At this time, it is assumed that RSDT and XSDT maintain parallel lists of tables.
1226 // If it becomes necessary to maintain separate table lists, changes will be required.
1227 //
1228 CurrentRsdtEntry = (UINT32 *) ((UINT8 *) Rsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + TempIndex * sizeof (UINT32));
1229 if (Xsdt != NULL) {
1230 //
1231 // This pointer must not be directly dereferenced as the XSDT entries may not
1232 // be 64 bit aligned resulting in a possible fault. Use CopyMem to update.
1233 //
1234 CurrentXsdtEntry = (VOID *) ((UINT8 *) Xsdt + sizeof (EFI_ACPI_DESCRIPTION_HEADER) + TempIndex * sizeof (UINT64));
1235
1236 //
1237 // Read the entry value out of the XSDT
1238 //
1239 CopyMem (&CurrentTablePointer64, CurrentXsdtEntry, sizeof (UINT64));
1240 } else {
1241 //
1242 // Initialize to NULL
1243 //
1244 CurrentXsdtEntry = 0;
1245 CurrentTablePointer64 = 0;
1246 }
1247 //
1248 // Check if we have found the corresponding entry in both RSDT and XSDT
1249 //
1250 if (*CurrentRsdtEntry == (UINT32) (UINTN) Table->Table &&
1251 ((Xsdt == NULL) || CurrentTablePointer64 == (UINT64) (UINTN) Table->Table)
1252 ) {
1253 //
1254 // Found entry, so copy all following entries and shrink table
1255 // We actually copy all + 1 to copy the initialized value of memory over
1256 // the last entry.
1257 //
1258 CopyMem (CurrentRsdtEntry, CurrentRsdtEntry + 1, (*NumberOfTableEntries - TempIndex) * sizeof (UINT32));
1259 Rsdt->Length = Rsdt->Length - sizeof (UINT32);
1260 if (Xsdt != NULL) {
1261 CopyMem (CurrentXsdtEntry, ((UINT64 *) CurrentXsdtEntry) + 1, (*NumberOfTableEntries - TempIndex) * sizeof (UINT64));
1262 Xsdt->Length = Xsdt->Length - sizeof (UINT64);
1263 }
1264 break;
1265 } else if (TempIndex + 1 == *NumberOfTableEntries) {
1266 //
1267 // At the last entry, and table not found
1268 //
1269 return EFI_INVALID_PARAMETER;
1270 }
1271 }
1272 //
1273 // Checksum the tables
1274 //
1275 AcpiPlatformChecksum (
1276 Rsdt,
1277 Rsdt->Length,
1278 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1279 Checksum)
1280 );
1281
1282 if (Xsdt != NULL) {
1283 AcpiPlatformChecksum (
1284 Xsdt,
1285 Xsdt->Length,
1286 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1287 Checksum)
1288 );
1289 }
1290 //
1291 // Decrement the number of tables
1292 //
1293 (*NumberOfTableEntries)--;
1294
1295 return EFI_SUCCESS;
1296 }
1297 /**
1298 This function removes a table and frees any associated memory.
1299
1300 @param AcpiSupportInstance Instance of the protocol.
1301 @param Version Version(s) to delete.
1302 @param Table Pointer to table found.
1303
1304 @return EFI_SUCCESS The function completed successfully.
1305
1306 **/
1307 EFI_STATUS
1308 DeleteTable (
1309 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance,
1310 IN EFI_ACPI_TABLE_VERSION Version,
1311 IN OUT EFI_ACPI_TABLE_LIST *Table
1312 )
1313 {
1314 UINT32 CurrentTableSignature;
1315 BOOLEAN RemoveFromRsdt;
1316
1317 //
1318 // Check for invalid input parameters
1319 //
1320 ASSERT (AcpiSupportInstance);
1321 ASSERT (Table);
1322
1323 //
1324 // Init locals
1325 //
1326 RemoveFromRsdt = TRUE;
1327
1328 if (Table->Table != NULL) {
1329 CurrentTableSignature = ((EFI_ACPI_COMMON_HEADER *) Table->Table)->Signature;
1330
1331 //
1332 // Basic tasks to accomplish delete are:
1333 // Determine removal requirements (in RSDT/XSDT or not)
1334 // Remove entry from RSDT/XSDT
1335 // Remove any table references to the table
1336 // If no one is using the table
1337 // Free the table (removing pointers from private data and tables)
1338 // Remove from list
1339 // Free list structure
1340 //
1341 //
1342 // Determine if this table is in the RSDT or XSDT
1343 //
1344 if ((CurrentTableSignature == EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) ||
1345 (CurrentTableSignature == EFI_ACPI_2_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) ||
1346 (CurrentTableSignature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)
1347 ) {
1348 RemoveFromRsdt = FALSE;
1349 }
1350 //
1351 // We don't remove the FADT in the standard way because some
1352 // OS expect the FADT to be early in the table list.
1353 // So we always put it as the first element in the list.
1354 //
1355 if (CurrentTableSignature == EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
1356 RemoveFromRsdt = FALSE;
1357 }
1358
1359 //
1360 // Remove the table from RSDT and XSDT
1361 //
1362
1363 //
1364 // This is a basic table, remove it from any lists and the Rsdt and/or Xsdt
1365 //
1366 if (Version & EFI_ACPI_TABLE_VERSION_NONE & Table->Version) {
1367 //
1368 // Remove this version from the table
1369 //
1370 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_NONE;
1371 }
1372
1373 if (Version & EFI_ACPI_TABLE_VERSION_1_0B & Table->Version) {
1374 //
1375 // Remove this version from the table
1376 //
1377 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_1_0B;
1378
1379 //
1380 // Remove from Rsdt. We don't care about the return value because it is
1381 // acceptable for the table to not exist in Rsdt.
1382 // We didn't add some tables so we don't remove them.
1383 //
1384 if (RemoveFromRsdt) {
1385 RemoveTableFromRsdt (
1386 Table,
1387 &AcpiSupportInstance->NumberOfTableEntries1,
1388 AcpiSupportInstance->Rsdt1,
1389 NULL
1390 );
1391 }
1392 }
1393
1394 if ((Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) ||
1395 (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version)) {
1396 //
1397 // Remove this version from the table
1398 //
1399 if (Version & EFI_ACPI_TABLE_VERSION_2_0 & Table->Version) {
1400 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_2_0;
1401 }
1402 if (Version & EFI_ACPI_TABLE_VERSION_3_0 & Table->Version) {
1403 Table->Version = Table->Version &~EFI_ACPI_TABLE_VERSION_3_0;
1404 }
1405
1406 //
1407 // Remove from Rsdt and Xsdt. We don't care about the return value
1408 // because it is acceptable for the table to not exist in Rsdt/Xsdt.
1409 // We didn't add some tables so we don't remove them.
1410 //
1411 if (RemoveFromRsdt) {
1412 RemoveTableFromRsdt (
1413 Table,
1414 &AcpiSupportInstance->NumberOfTableEntries3,
1415 AcpiSupportInstance->Rsdt3,
1416 AcpiSupportInstance->Xsdt
1417 );
1418 }
1419 }
1420 //
1421 // Free the table, clean up any dependent tables and our private data pointers.
1422 //
1423 switch (Table->Table->Signature) {
1424
1425 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:
1426 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1427 AcpiSupportInstance->Fadt1 = NULL;
1428 }
1429
1430 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
1431 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1432 AcpiSupportInstance->Fadt3 = NULL;
1433 }
1434 break;
1435
1436 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:
1437 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1438 AcpiSupportInstance->Facs1 = NULL;
1439
1440 //
1441 // Update FADT table pointers
1442 //
1443 if (AcpiSupportInstance->Fadt1 != NULL) {
1444 AcpiSupportInstance->Fadt1->FirmwareCtrl = 0;
1445
1446 //
1447 // Checksum table
1448 //
1449 AcpiPlatformChecksum (
1450 AcpiSupportInstance->Fadt1,
1451 AcpiSupportInstance->Fadt1->Header.Length,
1452 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1453 Checksum)
1454 );
1455 }
1456 }
1457
1458 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
1459 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1460 AcpiSupportInstance->Facs3 = NULL;
1461
1462 //
1463 // Update FADT table pointers
1464 //
1465 if (AcpiSupportInstance->Fadt3 != NULL) {
1466 AcpiSupportInstance->Fadt3->FirmwareCtrl = 0;
1467 ZeroMem (&AcpiSupportInstance->Fadt3->XFirmwareCtrl, sizeof (UINT64));
1468
1469 //
1470 // Checksum table
1471 //
1472 AcpiPlatformChecksum (
1473 AcpiSupportInstance->Fadt3,
1474 AcpiSupportInstance->Fadt3->Header.Length,
1475 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1476 Checksum)
1477 );
1478 }
1479 }
1480 break;
1481
1482 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:
1483 if ((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0) {
1484 AcpiSupportInstance->Dsdt1 = NULL;
1485
1486 //
1487 // Update FADT table pointers
1488 //
1489 if (AcpiSupportInstance->Fadt1 != NULL) {
1490 AcpiSupportInstance->Fadt1->Dsdt = 0;
1491
1492 //
1493 // Checksum table
1494 //
1495 AcpiPlatformChecksum (
1496 AcpiSupportInstance->Fadt1,
1497 AcpiSupportInstance->Fadt1->Header.Length,
1498 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1499 Checksum)
1500 );
1501 }
1502 }
1503
1504
1505 if ((Version & EFI_ACPI_TABLE_VERSION_2_0) != 0 ||
1506 (Version & EFI_ACPI_TABLE_VERSION_3_0) != 0) {
1507 AcpiSupportInstance->Dsdt3 = NULL;
1508
1509 //
1510 // Update FADT table pointers
1511 //
1512 if (AcpiSupportInstance->Fadt3 != NULL) {
1513 AcpiSupportInstance->Fadt3->Dsdt = 0;
1514 ZeroMem (&AcpiSupportInstance->Fadt3->XDsdt, sizeof (UINT64));
1515
1516 //
1517 // Checksum table
1518 //
1519 AcpiPlatformChecksum (
1520 AcpiSupportInstance->Fadt3,
1521 AcpiSupportInstance->Fadt3->Header.Length,
1522 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1523 Checksum)
1524 );
1525 }
1526 }
1527 break;
1528
1529 default:
1530 //
1531 // Do nothing
1532 //
1533 break;
1534 }
1535 }
1536 //
1537 // If no version is using this table anymore, remove and free list entry.
1538 //
1539 if (Table->Version == 0) {
1540 //
1541 // Free the Table
1542 //
1543 gBS->FreePages (Table->PageAddress, Table->NumberOfPages);
1544 RemoveEntryList (&(Table->Link));
1545 gBS->FreePool (Table);
1546 }
1547 //
1548 // Done
1549 //
1550 return EFI_SUCCESS;
1551 }
1552 /**
1553 This function finds and removes the table specified by the handle.
1554
1555 @param AcpiSupportInstance Instance of the protocol.
1556 @param Version Bitmask of which versions to remove.
1557 @param Handle Table to remove.
1558
1559 @return EFI_SUCCESS The function completed successfully.
1560 @return EFI_ABORTED An error occurred.
1561 @return EFI_NOT_FOUND Handle not found in table list.
1562 **/
1563 EFI_STATUS
1564 RemoveTableFromList (
1565 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance,
1566 IN EFI_ACPI_TABLE_VERSION Version,
1567 IN UINTN Handle
1568 )
1569 {
1570 EFI_ACPI_TABLE_LIST *Table;
1571 EFI_STATUS Status;
1572
1573 Table = NULL;
1574
1575 //
1576 // Check for invalid input parameters
1577 //
1578 ASSERT (AcpiSupportInstance);
1579
1580 //
1581 // Find the table
1582 //
1583 Status = FindTableByHandle (
1584 Handle,
1585 &AcpiSupportInstance->TableList,
1586 &Table
1587 );
1588 if (EFI_ERROR (Status)) {
1589 return EFI_NOT_FOUND;
1590 }
1591 //
1592 // Remove the table
1593 //
1594 Status = DeleteTable (AcpiSupportInstance, Version, Table);
1595 if (EFI_ERROR (Status)) {
1596 return EFI_ABORTED;
1597 }
1598 //
1599 // Completed successfully
1600 //
1601 return EFI_SUCCESS;
1602 }
1603 /**
1604 This function calculates and updates an UINT8 checksum.
1605
1606 @param Buffer Pointer to buffer to checksum
1607 @param Size Number of bytes to checksum
1608 @param ChecksumOffset Offset to place the checksum result in
1609
1610 @return EFI_SUCCESS The function completed successfully.
1611
1612 **/
1613 EFI_STATUS
1614 AcpiPlatformChecksum (
1615 IN VOID *Buffer,
1616 IN UINTN Size,
1617 IN UINTN ChecksumOffset
1618 )
1619 {
1620 UINT8 Sum;
1621 UINT8 *Ptr;
1622
1623 Sum = 0;
1624 //
1625 // Initialize pointer
1626 //
1627 Ptr = Buffer;
1628
1629 //
1630 // set checksum to 0 first
1631 //
1632 Ptr[ChecksumOffset] = 0;
1633
1634 //
1635 // add all content of buffer
1636 //
1637 while ((Size--) != 0) {
1638 Sum = (UINT8) (Sum + (*Ptr++));
1639 }
1640 //
1641 // set checksum
1642 //
1643 Ptr = Buffer;
1644 Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
1645
1646 return EFI_SUCCESS;
1647 }
1648 /**
1649 Checksum all versions of the common tables, RSDP, RSDT, XSDT.
1650
1651 @param AcpiSupportInstance Protocol instance private data.
1652
1653 @return EFI_SUCCESS The function completed successfully.
1654
1655 **/
1656 EFI_STATUS
1657 ChecksumCommonTables (
1658 IN OUT EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance
1659 )
1660 {
1661 //
1662 // RSDP ACPI 1.0 checksum for 1.0 table. This is only the first 20 bytes of the structure
1663 //
1664 AcpiPlatformChecksum (
1665 AcpiSupportInstance->Rsdp1,
1666 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
1667 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
1668 Checksum)
1669 );
1670
1671 //
1672 // RSDP ACPI 1.0 checksum for 2.0/3.0 table. This is only the first 20 bytes of the structure
1673 //
1674 AcpiPlatformChecksum (
1675 AcpiSupportInstance->Rsdp3,
1676 sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
1677 OFFSET_OF (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
1678 Checksum)
1679 );
1680
1681 //
1682 // RSDP ACPI 2.0/3.0 checksum, this is the entire table
1683 //
1684 AcpiPlatformChecksum (
1685 AcpiSupportInstance->Rsdp3,
1686 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER),
1687 OFFSET_OF (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER,
1688 ExtendedChecksum)
1689 );
1690
1691 //
1692 // RSDT checksums
1693 //
1694 AcpiPlatformChecksum (
1695 AcpiSupportInstance->Rsdt1,
1696 AcpiSupportInstance->Rsdt1->Length,
1697 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1698 Checksum)
1699 );
1700
1701 AcpiPlatformChecksum (
1702 AcpiSupportInstance->Rsdt3,
1703 AcpiSupportInstance->Rsdt3->Length,
1704 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1705 Checksum)
1706 );
1707
1708 //
1709 // XSDT checksum
1710 //
1711 AcpiPlatformChecksum (
1712 AcpiSupportInstance->Xsdt,
1713 AcpiSupportInstance->Xsdt->Length,
1714 OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
1715 Checksum)
1716 );
1717
1718 return EFI_SUCCESS;
1719 }
1720 /**
1721 Constructor for the ACPI support protocol to initializes instance data.
1722
1723 @param AcpiSupportInstance Instance to construct
1724
1725 @retval EFI_SUCCESS Instance initialized.
1726 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
1727 **/
1728 EFI_STATUS
1729 AcpiSupportAcpiSupportConstructor (
1730 IN EFI_ACPI_SUPPORT_INSTANCE *AcpiSupportInstance
1731 )
1732 {
1733 EFI_STATUS Status;
1734 UINT64 CurrentData;
1735 UINTN TotalSize;
1736 UINTN RsdpTableSize;
1737 UINT8 *Pointer;
1738 EFI_PHYSICAL_ADDRESS PageAddress;
1739
1740 //
1741 // Check for invalid input parameters
1742 //
1743 ASSERT (AcpiSupportInstance);
1744
1745 InitializeListHead (&AcpiSupportInstance->TableList);
1746 AcpiSupportInstance->CurrentHandle = 1;
1747 AcpiSupportInstance->AcpiSupport.GetAcpiTable = GetAcpiTable;
1748 AcpiSupportInstance->AcpiSupport.SetAcpiTable = SetAcpiTable;
1749 AcpiSupportInstance->AcpiSupport.PublishTables = PublishTables;
1750
1751 AcpiSupportInstance->AcpiTableProtocol.InstallAcpiTable = InstallAcpiTable;
1752 AcpiSupportInstance->AcpiTableProtocol.UninstallAcpiTable = UninstallAcpiTable;
1753
1754 //
1755 // Create RSDP table
1756 //
1757 RsdpTableSize = sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER) +
1758 sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
1759
1760 PageAddress = 0xFFFFFFFF;
1761 Status = gBS->AllocatePages (
1762 AllocateMaxAddress,
1763 EfiACPIReclaimMemory,
1764 EFI_SIZE_TO_PAGES (RsdpTableSize),
1765 &PageAddress
1766 );
1767
1768 if (EFI_ERROR (Status)) {
1769 return EFI_OUT_OF_RESOURCES;
1770 }
1771
1772 Pointer = (UINT8 *) (UINTN) PageAddress;
1773 ZeroMem (Pointer, RsdpTableSize);
1774
1775 AcpiSupportInstance->Rsdp1 = (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
1776 Pointer += sizeof (EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
1777 AcpiSupportInstance->Rsdp3 = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) Pointer;
1778
1779 //
1780 // Create RSDT, XSDT structures
1781 //
1782 TotalSize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 1.0 RSDT
1783 mEfiAcpiMaxNumTables * sizeof (UINT32) +
1784 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 RSDT
1785 mEfiAcpiMaxNumTables * sizeof (UINT32) +
1786 sizeof (EFI_ACPI_DESCRIPTION_HEADER) + // for ACPI 2.0/3.0 XSDT
1787 mEfiAcpiMaxNumTables * sizeof (UINT64);
1788
1789 //
1790 // Allocate memory in the lower 32 bit of address range for
1791 // compatibility with ACPI 1.0 OS.
1792 //
1793 // This is done because ACPI 1.0 pointers are 32 bit values.
1794 // ACPI 2.0 OS and all 64 bit OS must use the 64 bit ACPI table addresses.
1795 // There is no architectural reason these should be below 4GB, it is purely
1796 // for convenience of implementation that we force memory below 4GB.
1797 //
1798 PageAddress = 0xFFFFFFFF;
1799 Status = gBS->AllocatePages (
1800 AllocateMaxAddress,
1801 EfiACPIReclaimMemory,
1802 EFI_SIZE_TO_PAGES (TotalSize),
1803 &PageAddress
1804 );
1805
1806 if (EFI_ERROR (Status)) {
1807 gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)AcpiSupportInstance->Rsdp1, EFI_SIZE_TO_PAGES (RsdpTableSize));
1808 return EFI_OUT_OF_RESOURCES;
1809 }
1810
1811 Pointer = (UINT8 *) (UINTN) PageAddress;
1812 ZeroMem (Pointer, TotalSize);
1813
1814 AcpiSupportInstance->Rsdt1 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
1815 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
1816 AcpiSupportInstance->Rsdt3 = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
1817 Pointer += (sizeof (EFI_ACPI_DESCRIPTION_HEADER) + EFI_ACPI_MAX_NUM_TABLES * sizeof (UINT32));
1818 AcpiSupportInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *) Pointer;
1819
1820 //
1821 // Initialize RSDP
1822 //
1823 CurrentData = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;
1824 CopyMem (&AcpiSupportInstance->Rsdp1->Signature, &CurrentData, sizeof (UINT64));
1825 CopyMem (AcpiSupportInstance->Rsdp1->OemId, EFI_ACPI_OEM_ID, 6);
1826 AcpiSupportInstance->Rsdp1->Reserved = EFI_ACPI_RESERVED_BYTE;
1827 AcpiSupportInstance->Rsdp1->RsdtAddress = (UINT32) (UINTN) AcpiSupportInstance->Rsdt1;
1828
1829 CurrentData = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE;
1830 CopyMem (&AcpiSupportInstance->Rsdp3->Signature, &CurrentData, sizeof (UINT64));
1831 CopyMem (AcpiSupportInstance->Rsdp3->OemId, EFI_ACPI_OEM_ID, 6);
1832 AcpiSupportInstance->Rsdp3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION;
1833 AcpiSupportInstance->Rsdp3->RsdtAddress = (UINT32) (UINTN) AcpiSupportInstance->Rsdt3;
1834 AcpiSupportInstance->Rsdp3->Length = sizeof (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER);
1835 CurrentData = (UINT64) (UINTN) AcpiSupportInstance->Xsdt;
1836 CopyMem (&AcpiSupportInstance->Rsdp3->XsdtAddress, &CurrentData, sizeof (UINT64));
1837 SetMem (AcpiSupportInstance->Rsdp3->Reserved, 3, EFI_ACPI_RESERVED_BYTE);
1838
1839 //
1840 // Initialize Rsdt
1841 //
1842 // Note that we "reserve" one entry for the FADT so it can always be
1843 // at the beginning of the list of tables. Some OS don't seem
1844 // to find it correctly if it is too far down the list.
1845 //
1846 AcpiSupportInstance->Rsdt1->Signature = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
1847 AcpiSupportInstance->Rsdt1->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
1848 AcpiSupportInstance->Rsdt1->Revision = EFI_ACPI_1_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
1849 CopyMem (AcpiSupportInstance->Rsdt1->OemId, EFI_ACPI_OEM_ID, 6);
1850 CurrentData = EFI_ACPI_OEM_TABLE_ID;
1851 CopyMem (&AcpiSupportInstance->Rsdt1->OemTableId, &CurrentData, sizeof (UINT64));
1852 AcpiSupportInstance->Rsdt1->OemRevision = EFI_ACPI_OEM_REVISION;
1853 AcpiSupportInstance->Rsdt1->CreatorId = EFI_ACPI_CREATOR_ID;
1854 AcpiSupportInstance->Rsdt1->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
1855 //
1856 // We always reserve first one for FADT
1857 //
1858 AcpiSupportInstance->NumberOfTableEntries1 = 1;
1859 AcpiSupportInstance->Rsdt1->Length = AcpiSupportInstance->Rsdt1->Length + sizeof(UINT32);
1860
1861 AcpiSupportInstance->Rsdt3->Signature = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
1862 AcpiSupportInstance->Rsdt3->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
1863 AcpiSupportInstance->Rsdt3->Revision = EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION;
1864 CopyMem (AcpiSupportInstance->Rsdt3->OemId, EFI_ACPI_OEM_ID, 6);
1865 CurrentData = EFI_ACPI_OEM_TABLE_ID;
1866 CopyMem (&AcpiSupportInstance->Rsdt3->OemTableId, &CurrentData, sizeof (UINT64));
1867 AcpiSupportInstance->Rsdt3->OemRevision = EFI_ACPI_OEM_REVISION;
1868 AcpiSupportInstance->Rsdt3->CreatorId = EFI_ACPI_CREATOR_ID;
1869 AcpiSupportInstance->Rsdt3->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
1870 //
1871 // We always reserve first one for FADT
1872 //
1873 AcpiSupportInstance->NumberOfTableEntries3 = 1;
1874 AcpiSupportInstance->Rsdt3->Length = AcpiSupportInstance->Rsdt3->Length + sizeof(UINT32);
1875
1876 //
1877 // Initialize Xsdt
1878 //
1879 AcpiSupportInstance->Xsdt->Signature = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE;
1880 AcpiSupportInstance->Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
1881 AcpiSupportInstance->Xsdt->Revision = EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION;
1882 CopyMem (AcpiSupportInstance->Xsdt->OemId, EFI_ACPI_OEM_ID, 6);
1883 CurrentData = EFI_ACPI_OEM_TABLE_ID;
1884 CopyMem (&AcpiSupportInstance->Xsdt->OemTableId, &CurrentData, sizeof (UINT64));
1885 AcpiSupportInstance->Xsdt->OemRevision = EFI_ACPI_OEM_REVISION;
1886 AcpiSupportInstance->Xsdt->CreatorId = EFI_ACPI_CREATOR_ID;
1887 AcpiSupportInstance->Xsdt->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
1888 //
1889 // We always reserve first one for FADT
1890 //
1891 AcpiSupportInstance->Xsdt->Length = AcpiSupportInstance->Xsdt->Length + sizeof(UINT64);
1892
1893 ChecksumCommonTables (AcpiSupportInstance);
1894
1895 //
1896 // Completed successfully
1897 //
1898 return EFI_SUCCESS;
1899 }