You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.7 KiB
157 lines
3.7 KiB
4 years ago
|
/** @file
|
||
|
XSDT table parser
|
||
|
|
||
|
Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
|
||
|
This program and the accompanying materials
|
||
|
are licensed and made available under the terms and conditions of the BSD License
|
||
|
which accompanies this distribution. The full text of the license may be found at
|
||
|
http://opensource.org/licenses/bsd-license.php
|
||
|
|
||
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||
|
|
||
|
@par Reference(s):
|
||
|
- ACPI 6.2 Specification - Errata A, September 2017
|
||
|
**/
|
||
|
|
||
|
#include <IndustryStandard/Acpi.h>
|
||
|
#include <Library/UefiLib.h>
|
||
|
#include <Library/PrintLib.h>
|
||
|
#include "AcpiParser.h"
|
||
|
#include "AcpiTableParser.h"
|
||
|
|
||
|
// Local variables
|
||
|
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
|
||
|
|
||
|
/** An ACPI_PARSER array describing the ACPI XSDT table.
|
||
|
*/
|
||
|
STATIC CONST ACPI_PARSER XsdtParser[] = {
|
||
|
PARSE_ACPI_HEADER (&AcpiHdrInfo)
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
Get the ACPI XSDT header info.
|
||
|
**/
|
||
|
CONST ACPI_DESCRIPTION_HEADER_INFO *
|
||
|
EFIAPI
|
||
|
GetAcpiXsdtHeaderInfo (
|
||
|
VOID
|
||
|
)
|
||
|
{
|
||
|
return &AcpiHdrInfo;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
This function parses the ACPI XSDT table and optionally traces the ACPI table fields.
|
||
|
|
||
|
This function also performs validation of the XSDT table.
|
||
|
|
||
|
@param [in] Trace If TRUE, trace the ACPI fields.
|
||
|
@param [in] Ptr Pointer to the start of the buffer.
|
||
|
@param [in] AcpiTableLength Length of the ACPI table.
|
||
|
@param [in] AcpiTableRevision Revision of the ACPI table.
|
||
|
**/
|
||
|
VOID
|
||
|
EFIAPI
|
||
|
ParseAcpiXsdt (
|
||
|
IN BOOLEAN Trace,
|
||
|
IN UINT8* Ptr,
|
||
|
IN UINT32 AcpiTableLength,
|
||
|
IN UINT8 AcpiTableRevision
|
||
|
)
|
||
|
{
|
||
|
UINT32 Offset;
|
||
|
UINT32 TableOffset;
|
||
|
UINT64* TablePointer;
|
||
|
UINTN EntryIndex;
|
||
|
CHAR16 Buffer[32];
|
||
|
|
||
|
// Parse the ACPI header to get the length
|
||
|
ParseAcpi (
|
||
|
FALSE,
|
||
|
0,
|
||
|
"XSDT",
|
||
|
Ptr,
|
||
|
ACPI_DESCRIPTION_HEADER_LENGTH,
|
||
|
PARSER_PARAMS (XsdtParser)
|
||
|
);
|
||
|
|
||
|
Offset = ParseAcpi (
|
||
|
Trace,
|
||
|
0,
|
||
|
"XSDT",
|
||
|
Ptr,
|
||
|
*AcpiHdrInfo.Length,
|
||
|
PARSER_PARAMS (XsdtParser)
|
||
|
);
|
||
|
|
||
|
TableOffset = Offset;
|
||
|
|
||
|
if (Trace) {
|
||
|
EntryIndex = 0;
|
||
|
TablePointer = (UINT64*)(Ptr + TableOffset);
|
||
|
while (Offset < (*AcpiHdrInfo.Length)) {
|
||
|
CONST UINT32* Signature;
|
||
|
CONST UINT32* Length;
|
||
|
CONST UINT8* Revision;
|
||
|
|
||
|
if ((UINT64*)(UINTN)(*TablePointer) != NULL) {
|
||
|
UINT8* SignaturePtr;
|
||
|
|
||
|
ParseAcpiHeader (
|
||
|
(UINT8*)(UINTN)(*TablePointer),
|
||
|
&Signature,
|
||
|
&Length,
|
||
|
&Revision
|
||
|
);
|
||
|
|
||
|
SignaturePtr = (UINT8*)Signature;
|
||
|
|
||
|
UnicodeSPrint (
|
||
|
Buffer,
|
||
|
sizeof (Buffer),
|
||
|
L"Entry[%d] - %c%c%c%c",
|
||
|
EntryIndex++,
|
||
|
SignaturePtr[0],
|
||
|
SignaturePtr[1],
|
||
|
SignaturePtr[2],
|
||
|
SignaturePtr[3]
|
||
|
);
|
||
|
} else {
|
||
|
UnicodeSPrint (
|
||
|
Buffer,
|
||
|
sizeof (Buffer),
|
||
|
L"Entry[%d]",
|
||
|
EntryIndex++
|
||
|
);
|
||
|
}
|
||
|
|
||
|
PrintFieldName (2, Buffer);
|
||
|
Print (L"0x%lx\n", *TablePointer);
|
||
|
|
||
|
// Validate the table pointers are not NULL
|
||
|
if ((UINT64*)(UINTN)(*TablePointer) == NULL) {
|
||
|
IncrementErrorCount ();
|
||
|
Print (
|
||
|
L"ERROR: Invalid table entry at 0x%lx, table address is 0x%lx\n",
|
||
|
TablePointer,
|
||
|
*TablePointer
|
||
|
);
|
||
|
}
|
||
|
Offset += sizeof (UINT64);
|
||
|
TablePointer++;
|
||
|
} // while
|
||
|
}
|
||
|
|
||
|
// Process the tables
|
||
|
Offset = TableOffset;
|
||
|
TablePointer = (UINT64*)(Ptr + TableOffset);
|
||
|
while (Offset < (*AcpiHdrInfo.Length)) {
|
||
|
if ((UINT64*)(UINTN)(*TablePointer) != NULL) {
|
||
|
ProcessAcpiTable ((UINT8*)(UINTN)(*TablePointer));
|
||
|
}
|
||
|
Offset += sizeof (UINT64);
|
||
|
TablePointer++;
|
||
|
} // while
|
||
|
}
|