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