/** @file | |
Flattened Device Tree parser library for KvmTool. | |
Copyright (c) 2021, ARM Limited. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "FdtHwInfoParser.h" | |
#include "BootArch/ArmBootArchParser.h" | |
#include "GenericTimer/ArmGenericTimerParser.h" | |
#include "Gic/ArmGicDispatcher.h" | |
#include "Pci/ArmPciConfigSpaceParser.h" | |
#include "Serial/ArmSerialPortParser.h" | |
/** Ordered table of parsers/dispatchers. | |
A parser parses a Device Tree to populate a specific CmObj type. None, | |
one or many CmObj can be created by the parser. | |
The created CmObj are then handed to the parser's caller through the | |
HW_INFO_ADD_OBJECT interface. | |
This can also be a dispatcher. I.e. a function that not parsing a | |
Device Tree but calling other parsers. | |
*/ | |
STATIC CONST FDT_HW_INFO_PARSER_FUNC HwInfoParserTable[] = { | |
ArmBootArchInfoParser, | |
ArmGenericTimerInfoParser, | |
ArmGicDispatcher, | |
ArmPciConfigInfoParser, | |
SerialPortDispatcher | |
}; | |
/** Main dispatcher: sequentially call the parsers/dispatchers | |
of the HwInfoParserTable. | |
A parser parses a Device Tree to populate a specific CmObj type. None, | |
one or many CmObj can be created by the parser. | |
The created CmObj are then handed to the parser's caller through the | |
HW_INFO_ADD_OBJECT interface. | |
This can also be a dispatcher. I.e. a function that not parsing a | |
Device Tree but calling other parsers. | |
@param [in] FdtParserHandle A handle to the parser instance. | |
@param [in] FdtBranch When searching for DT node name, restrict | |
the search to this Device Tree branch. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_ABORTED An error occurred. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
@retval EFI_NOT_FOUND Not found. | |
@retval EFI_UNSUPPORTED Unsupported. | |
**/ | |
STATIC | |
EFI_STATUS | |
EFIAPI | |
MainDispatcher ( | |
IN CONST FDT_HW_INFO_PARSER_HANDLE FdtParserHandle, | |
IN INT32 FdtBranch | |
) | |
{ | |
EFI_STATUS Status; | |
UINT32 Index; | |
if (fdt_check_header (FdtParserHandle->Fdt) < 0) { | |
ASSERT (0); | |
return EFI_INVALID_PARAMETER; | |
} | |
for (Index = 0; Index < ARRAY_SIZE (HwInfoParserTable); Index++) { | |
Status = HwInfoParserTable[Index]( | |
FdtParserHandle, | |
FdtBranch | |
); | |
if (EFI_ERROR (Status) && | |
(Status != EFI_NOT_FOUND)) | |
{ | |
// If EFI_NOT_FOUND, the parser didn't find information in the DT. | |
// Don't trigger an error. | |
ASSERT (0); | |
return Status; | |
} | |
} // for | |
return EFI_SUCCESS; | |
} | |
/** Initialise the HwInfoParser. | |
The HwInfoParser shall use the information provided by the HwDataSource | |
to initialise the internal state of the parser or to index the data. This | |
internal state shall be linked to the ParserHandle using an implementation | |
defined mechanism. | |
@param [in] HwDataSource Pointer to the blob containing the hardware | |
information. It can be a pointer to a Device | |
Tree, an XML file, etc. or any other data | |
structure defined by the HwInfoParser. | |
@param [in] Context A pointer to the caller's context. | |
@param [in] HwInfoAdd Function pointer called by the parser when | |
adding information. | |
@param [out] ParserHandle A handle to the parser instance. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
HwInfoParserInit ( | |
IN VOID *HwDataSource, | |
IN VOID *Context, | |
IN HW_INFO_ADD_OBJECT HwInfoAdd, | |
OUT HW_INFO_PARSER_HANDLE *ParserHandle | |
) | |
{ | |
FDT_HW_INFO_PARSER *FdtParserHandle; | |
if ((ParserHandle == NULL) || | |
(HwInfoAdd == NULL) || | |
(HwDataSource == NULL) || | |
(fdt_check_header (HwDataSource) < 0)) | |
{ | |
ASSERT (0); | |
return EFI_INVALID_PARAMETER; | |
} | |
FdtParserHandle = AllocateZeroPool (sizeof (FDT_HW_INFO_PARSER)); | |
if (FdtParserHandle == NULL) { | |
*ParserHandle = NULL; | |
return EFI_OUT_OF_RESOURCES; | |
} | |
// The HwDataSource is a pointer to the FDT data. | |
FdtParserHandle->Fdt = HwDataSource; | |
FdtParserHandle->Context = Context; | |
FdtParserHandle->HwInfoAdd = HwInfoAdd; | |
*ParserHandle = (HW_INFO_PARSER_HANDLE)FdtParserHandle; | |
return EFI_SUCCESS; | |
} | |
/** Parse the data provided by the HwDataSource. | |
@param [in] ParserHandle A handle to the parser instance. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
@retval EFI_OUT_OF_RESOURCES An allocation has failed. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
HwInfoParse ( | |
IN HW_INFO_PARSER_HANDLE ParserHandle | |
) | |
{ | |
EFI_STATUS Status; | |
if (ParserHandle == NULL) { | |
ASSERT (0); | |
return EFI_INVALID_PARAMETER; | |
} | |
// Call all the parsers from the root node (-1). | |
Status = MainDispatcher ( | |
(FDT_HW_INFO_PARSER_HANDLE)ParserHandle, | |
-1 | |
); | |
ASSERT_EFI_ERROR (Status); | |
return Status; | |
} | |
/** Cleanup any internal state and resources that were allocated | |
by the HwInfoParser. | |
@param [in] ParserHandle A handle to the parser instance. | |
@retval EFI_SUCCESS The function completed successfully. | |
@retval EFI_INVALID_PARAMETER Invalid parameter. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
HwInfoParserShutdown ( | |
IN HW_INFO_PARSER_HANDLE ParserHandle | |
) | |
{ | |
if (ParserHandle == NULL) { | |
ASSERT (0); | |
return EFI_INVALID_PARAMETER; | |
} | |
FreePool (ParserHandle); | |
return EFI_SUCCESS; | |
} |