summaryrefslogtreecommitdiffstats
path: root/DynamicTablesPkg/Library/FdtHwInfoParserLib/FdtHwInfoParser.c
blob: 376de078bcb11e6a989cf4c3e97666a41a6a47c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/** @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;
}