1 | # Dynamic Tables Framework
|
---|
2 |
|
---|
3 | Dynamic Tables Framework provides mechanisms to reduce the amount
|
---|
4 | of effort required in porting firmware to new platforms. The aim is
|
---|
5 | to provide an implementation capable of generating the firmware
|
---|
6 | tables from an external source. This is potentially a management
|
---|
7 | node, either local or remote, or, where suitable, a file that might
|
---|
8 | be generated from the system construction. This initial release
|
---|
9 | does not fully implement that - the configuration is held in local
|
---|
10 | UEFI modules.
|
---|
11 |
|
---|
12 | # Feature Summary
|
---|
13 |
|
---|
14 | The dynamic tables framework is designed to generate standardised
|
---|
15 | firmware tables that describe the hardware information at
|
---|
16 | run-time. A goal of standardised firmware is to have a common
|
---|
17 | firmware for a platform capable of booting both Windows and Linux
|
---|
18 | operating systems.
|
---|
19 |
|
---|
20 | Traditionally the firmware tables are handcrafted using ACPI
|
---|
21 | Source Language (ASL), Table Definition Language (TDL) and
|
---|
22 | C-code. This approach can be error prone and involves time
|
---|
23 | consuming debugging. In addition, it may be desirable to configure
|
---|
24 | platform hardware at runtime such as: configuring the number of
|
---|
25 | cores available for use by the OS, or turning SoC features ON or
|
---|
26 | OFF.
|
---|
27 |
|
---|
28 | The dynamic tables framework simplifies this by providing a set
|
---|
29 | of standard table generators, that are implemented as libraries.
|
---|
30 | These generators query a platform specific component, the
|
---|
31 | 'Configuration Manager', to collate the information required
|
---|
32 | for generating the tables at run-time.
|
---|
33 |
|
---|
34 | The framework also provides the ability to implement custom/OEM
|
---|
35 | generators; thereby facilitating support for custom tables. The
|
---|
36 | custom generators can also utilize the existing standard generators
|
---|
37 | and override any functionality if needed.
|
---|
38 |
|
---|
39 | The framework currently implements a set of standard ACPI table
|
---|
40 | generators for ARM architecture, that can generate Server Base Boot
|
---|
41 | Requirement (SBBR) compliant tables. Although, the set of standard
|
---|
42 | generators implement the functionality required for ARM architecture;
|
---|
43 | the framework is extensible, and support for other architectures can
|
---|
44 | be added easily.
|
---|
45 |
|
---|
46 | The framework currently supports the following table generators for ARM:
|
---|
47 | * DBG2 - Debug Port Table 2
|
---|
48 | * DSDT - Differentiated system description table. This is essentially
|
---|
49 | a RAW table generator.
|
---|
50 | * FADT - Fixed ACPI Description Table
|
---|
51 | * GTDT - Generic Timer Description Table
|
---|
52 | * IORT - IO Remapping Table
|
---|
53 | * MADT - Multiple APIC Description Table
|
---|
54 | * MCFG - PCI Express memory mapped configuration space base address
|
---|
55 | Description Table
|
---|
56 | * PCCT - Platform Communications Channel Table
|
---|
57 | * PPTT - Processor Properties Topology Table
|
---|
58 | * SPCR - Serial Port Console Redirection Table
|
---|
59 | * SRAT - System Resource Affinity Table
|
---|
60 | * SSDT - Secondary System Description Table. This is essentially
|
---|
61 | a RAW table generator.
|
---|
62 |
|
---|
63 | ## Dynamic AML
|
---|
64 |
|
---|
65 | ACPI Definition block (e.g. DSDT or SSDT) tables are used to describe system
|
---|
66 | devices along with other control and power management information. These tables
|
---|
67 | are written using ACPI Source Language (ASL). The ASL code is compiled using an
|
---|
68 | ASL compiler (e.g. Intel iASL compiler) to generate ACPI Machine Language (AML)
|
---|
69 | bytecode.
|
---|
70 |
|
---|
71 | Since, definition blocks are represented using AML grammar, run-time generation
|
---|
72 | of definition blocks is complex. Dynamic AML is a feature of Dynamic Tables
|
---|
73 | framework that provides a solution for dynamic generation of ACPI Definition
|
---|
74 | block tables.
|
---|
75 |
|
---|
76 | Dynamic AML introduces the following techniques:
|
---|
77 | * AML Fixup
|
---|
78 | * AML Codegen
|
---|
79 | * AML Fixup + Codegen
|
---|
80 |
|
---|
81 | ### AML Fixup
|
---|
82 | AML fixup is a technique that involves compiling an ASL template file to
|
---|
83 | generate AML bytecode. This template AML bytecode can be parsed at run-time
|
---|
84 | and a fixup code can update the required fields in the AML template.
|
---|
85 |
|
---|
86 | To simplify AML Fixup, the Dynamic Tables Framework provides an *AmlLib*
|
---|
87 | library with a rich set of APIs that can be used to fixup the AML code.
|
---|
88 |
|
---|
89 | ### AML Codegen
|
---|
90 | AML Codegen employs generating small segments of AML code. The *AmlLib*
|
---|
91 | library provides AML Codegen APIs that generate the AML code segments.
|
---|
92 |
|
---|
93 | Example: The following table depicts the AML Codegen APIs and the
|
---|
94 | corresponding ASL code that would be generated.
|
---|
95 |
|
---|
96 | | AML Codegen API | ASL Code |
|
---|
97 | |--------------------------------|--------------------------------|
|
---|
98 | | AmlCodeGenDefinitionBlock ( | DefinitionBlock ( |
|
---|
99 | | .., | ... |
|
---|
100 | | &RootNode); | ) { |
|
---|
101 | | AmlCodeGenScope ( | Scope (_SB) { |
|
---|
102 | | "\_SB", | |
|
---|
103 | | RootNode, | |
|
---|
104 | | &ScopeNode); | |
|
---|
105 | | AmlCodeGenDevice ( | Device (CPU0) { |
|
---|
106 | | "CPU0", | |
|
---|
107 | | ScopeNode, | |
|
---|
108 | | &CpuNode); | |
|
---|
109 | | AmlCodeGenNameString ( | Name (_HID, "ACPI0007") |
|
---|
110 | | "_HID", | |
|
---|
111 | | "ACPI0007", | |
|
---|
112 | | CpuNode, | |
|
---|
113 | | &HidNode); | |
|
---|
114 | | AmlCodeGenNameInteger ( | Name (_UID, Zero) |
|
---|
115 | | "_UID", | |
|
---|
116 | | 0, | |
|
---|
117 | | CpuNode, | |
|
---|
118 | | &UidNode); | |
|
---|
119 | | | } // Device |
|
---|
120 | | | } // Scope |
|
---|
121 | | | } // DefinitionBlock |
|
---|
122 |
|
---|
123 | ### AML Fixup + Codegen
|
---|
124 | A combination of AML Fixup and AML Codegen could be used for generating
|
---|
125 | Definition Blocks. For example the AML Fixup could be used to fixup certain
|
---|
126 | parts of the AML template while the AML Codegen APIs could be used to inserted
|
---|
127 | small fragments of AML code in the AML template.
|
---|
128 |
|
---|
129 | ### AmlLib Library
|
---|
130 | Since, AML bytecode represents complex AML grammar, an **AmlLib** library is
|
---|
131 | introduced to assist parsing and traversing of the AML bytecode at run-time.
|
---|
132 |
|
---|
133 | The AmlLib library parses a definition block and represents it as an AML
|
---|
134 | tree. This tree representation is based on the AML grammar defined by the
|
---|
135 | ACPI 6.3 specification, section - 20 'ACPI Machine Language (AML)
|
---|
136 | Specification'.
|
---|
137 |
|
---|
138 | AML objects, methods and data are represented as tree nodes. Since the AML
|
---|
139 | data is represented as tree nodes, it is possible to traverse the tree, locate
|
---|
140 | a node and modify the node data. The tree can then be serialized to a buffer
|
---|
141 | (that represents the definition block). This definition block containing
|
---|
142 | the fixed up AML code can then be installed as an ACPI table (DSDT/SSDT).
|
---|
143 |
|
---|
144 | AmlLib provides a rich API to operate on AML data. For example it provides
|
---|
145 | APIs to update a device's name, the value of a "_UID" object, and the memory
|
---|
146 | and interrupt number stored in a "_CRS" node.
|
---|
147 |
|
---|
148 | Although the AmlLib performs checks to a reasonable extent while modifying a
|
---|
149 | definition block, these checks may not cover all aspects due to the complexity
|
---|
150 | of the ASL/AML language. It is therefore recommended to review any operation
|
---|
151 | performed, and validate the generated output.
|
---|
152 |
|
---|
153 | Example: The serialized AML code could be validated by
|
---|
154 | - Saving the generated AML to a file and comparing with
|
---|
155 | a reference output.
|
---|
156 | or
|
---|
157 | - Disassemble the generated AML using the iASL compiler
|
---|
158 | and verifying the output.
|
---|
159 |
|
---|
160 | ### Bespoke ACPI tables
|
---|
161 |
|
---|
162 | The Dynamic Tables framework supports the creation of several tables using
|
---|
163 | standard generators, see Feature Summary Section for a list of such tables.
|
---|
164 |
|
---|
165 | The supported platforms already contain several tables.
|
---|
166 | If a table is not present for the platform, two alternative processes can be followed:
|
---|
167 |
|
---|
168 | - define the table in using ASL,
|
---|
169 | - define the table in packed C structures (also known as RAW).
|
---|
170 |
|
---|
171 | The two approaches are detailed below.
|
---|
172 |
|
---|
173 | #### Adding an ASL table for which the Dynamic Tables Framework does not provide a standard generator
|
---|
174 |
|
---|
175 | This method creates the SSDT table from the ASL source, using a standard generator.
|
---|
176 | Perform the following steps:
|
---|
177 |
|
---|
178 | 1. Create the table source file, placing it within the ConfigurationManager source tree, e.g.:
|
---|
179 |
|
---|
180 | Create a file Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/AslTables/NewTableSource.asl
|
---|
181 | with the following contents:
|
---|
182 |
|
---|
183 | ```
|
---|
184 | DefinitionBlock ("", "SSDT", 2, "XXXXXX", "XXXXXXXX", 1) {
|
---|
185 | Scope(_SB) {
|
---|
186 | Device(FLA0) {
|
---|
187 | Name(_HID, "XXXX0000")
|
---|
188 | Name(_UID, 0)
|
---|
189 |
|
---|
190 | // _DSM - Device Specific Method
|
---|
191 | Function(_DSM,{IntObj,BuffObj},{BuffObj, IntObj, IntObj, PkgObj})
|
---|
192 | {
|
---|
193 | W0 = 0x1
|
---|
194 | return (W0)
|
---|
195 | }
|
---|
196 | }
|
---|
197 | }
|
---|
198 | }
|
---|
199 | ```
|
---|
200 |
|
---|
201 | 2. Reference the table source file in ConfigurationMangerDxe.inf
|
---|
202 |
|
---|
203 | ```
|
---|
204 | [Sources]
|
---|
205 | AslTables/NewTableSource.asl
|
---|
206 | ```
|
---|
207 |
|
---|
208 | 3. Update the ConfigurationManager.h file
|
---|
209 | Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/ConfigurationManager.h
|
---|
210 |
|
---|
211 | Add an array to hold the AML code:
|
---|
212 | ```
|
---|
213 | extern CHAR8 newtablesource_aml_code[];
|
---|
214 | ```
|
---|
215 |
|
---|
216 | Note: the array name is composed of the ASL source file name all in lower case, followed by the _aml_code postfix.
|
---|
217 |
|
---|
218 | 4. Increment the macro PLAT_ACPI_TABLE_COUNT
|
---|
219 |
|
---|
220 | 5. Add a new CM_STD_OBJ_ACPI_TABLE_INFO structure entry and initialise.
|
---|
221 |
|
---|
222 | - the entry contains:
|
---|
223 | - the table signature,
|
---|
224 | - the table revision (unused in this case),
|
---|
225 | - the ID of the standard generator to be used (the SSDT generator in this case).
|
---|
226 | - a pointer to the AML code,
|
---|
227 |
|
---|
228 | ```
|
---|
229 | // Table defined in the NewTableSource.asl file
|
---|
230 | {
|
---|
231 | EFI_ACPI_6_4_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
|
---|
232 | 0, // Unused
|
---|
233 | CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSsdt),
|
---|
234 | (EFI_ACPI_DESCRIPTION_HEADER*)newtablesource_aml_code
|
---|
235 | },
|
---|
236 | ```
|
---|
237 |
|
---|
238 | #### Add a RAW table for which there is no standard generator
|
---|
239 |
|
---|
240 | An ACPI table can be defined as a packed C struct in the C source code. This is referred to as the "raw" table format.
|
---|
241 | The steps to create a table in raw format are detailed below:
|
---|
242 |
|
---|
243 | 1. Define the table in a C source file and populate the ACPI table structure field with the required values.
|
---|
244 |
|
---|
245 | For example, create the file Platform/ARM/VExpressPkg/ConfigurationManager/ConfigurationManagerDxe/RawTable.c
|
---|
246 |
|
---|
247 | ```
|
---|
248 | // Example creating the HMAT in raw format
|
---|
249 | EFI_ACPI_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE Hmat = {
|
---|
250 | ...
|
---|
251 | };
|
---|
252 | ```
|
---|
253 |
|
---|
254 | 2. Reference the table source file in ConfigurationMangerDxe.inf
|
---|
255 |
|
---|
256 | ```
|
---|
257 | [Sources]
|
---|
258 | RawTable.c
|
---|
259 | ```
|
---|
260 |
|
---|
261 | 2. Increment the macro PLAT_ACPI_TABLE_COUNT
|
---|
262 |
|
---|
263 | 3. Add a new CM_STD_OBJ_ACPI_TABLE_INFO structure entry and initialise.
|
---|
264 |
|
---|
265 | - the entry contains:
|
---|
266 | - the table signature,
|
---|
267 | - the table revision,
|
---|
268 | - the RAW generator ID.
|
---|
269 | - a pointer to the C packed struct that defines the table,
|
---|
270 |
|
---|
271 | ```
|
---|
272 | {
|
---|
273 | EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE,
|
---|
274 | EFI_ACPI_6_3_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_REVISION,
|
---|
275 | CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdRaw),
|
---|
276 | (EFI_ACPI_DESCRIPTION_HEADER*)&Hmat
|
---|
277 | },
|
---|
278 | ```
|
---|
279 |
|
---|
280 | # Roadmap
|
---|
281 |
|
---|
282 | The current implementation of the Configuration Manager populates the
|
---|
283 | platform information statically as a C structure. Further enhancements
|
---|
284 | to introduce runtime loading of platform information from a platform
|
---|
285 | information file is planned.
|
---|
286 |
|
---|
287 | Also support for generating SMBIOS tables is planned and will be added
|
---|
288 | subsequently.
|
---|
289 |
|
---|
290 | # Supported Platforms
|
---|
291 |
|
---|
292 | 1. Juno
|
---|
293 | 2. FVP Models
|
---|
294 |
|
---|
295 | # Build Instructions
|
---|
296 |
|
---|
297 | 1. Set path for the iASL compiler with support for generating a C header
|
---|
298 | file as output.
|
---|
299 |
|
---|
300 | 2. Set PACKAGES_PATH to point to the locations of the following repositories:
|
---|
301 |
|
---|
302 | Example:
|
---|
303 |
|
---|
304 | > set PACKAGES_PATH=%CD%\edk2;%CD%\edk2-platforms;
|
---|
305 |
|
---|
306 | or
|
---|
307 |
|
---|
308 | > export PACKAGES_PATH=$PWD/edk2:$PWD/edk2-platforms
|
---|
309 |
|
---|
310 | 3. To enable Dynamic tables framework the *'DYNAMIC_TABLES_FRAMEWORK'*
|
---|
311 | option must be defined. This can be passed as a command line
|
---|
312 | parameter to the edk2 build system.
|
---|
313 |
|
---|
314 | Example:
|
---|
315 |
|
---|
316 | >build -a AARCH64 -p Platform\ARM\JunoPkg\ArmJuno.dsc
|
---|
317 | -t GCC5 **-D DYNAMIC_TABLES_FRAMEWORK**
|
---|
318 |
|
---|
319 | or
|
---|
320 |
|
---|
321 | >build -a AARCH64 -p Platform\ARM\VExpressPkg\ArmVExpress-FVP-AArch64.dsc
|
---|
322 | -t GCC5 **-D DYNAMIC_TABLES_FRAMEWORK**
|
---|
323 |
|
---|
324 | # Prerequisites
|
---|
325 |
|
---|
326 | Ensure that the latest ACPICA iASL compiler is used for building *Dynamic Tables Framework*.
|
---|
327 | *Dynamic Tables Framework* has been tested using the following iASL compiler version:
|
---|
328 | [Version 20200717](https://www.acpica.org/node/183), dated 17 July, 2020.
|
---|
329 |
|
---|
330 |
|
---|
331 | #Running CI builds locally
|
---|
332 |
|
---|
333 | The TianoCore EDKII project has introduced Core CI infrastructure using TianoCore EDKII Tools PIP modules:
|
---|
334 |
|
---|
335 | - *[edk2-pytool-library](https://pypi.org/project/edk2-pytool-library)*
|
---|
336 |
|
---|
337 | - *[edk2-pytool-extensions](https://pypi.org/project/edk2-pytool-extensions)*
|
---|
338 |
|
---|
339 |
|
---|
340 | The instructions to setup the CI environment are in *'edk2\\.pytool\\Readme.md'*
|
---|
341 |
|
---|
342 | ## Building DynamicTablesPkg with Pytools
|
---|
343 |
|
---|
344 | 1. [Optional] Create a Python Virtual Environment - generally once per workspace
|
---|
345 |
|
---|
346 | ```
|
---|
347 | python -m venv <name of virtual environment>
|
---|
348 |
|
---|
349 | e.g. python -m venv edk2-ci
|
---|
350 | ```
|
---|
351 |
|
---|
352 | 2. [Optional] Activate Virtual Environment - each time new shell/command window is opened
|
---|
353 |
|
---|
354 | ```
|
---|
355 | <name of virtual environment>/Scripts/activate
|
---|
356 |
|
---|
357 | e.g. On a windows host PC run:
|
---|
358 | edk2-ci\Scripts\activate.bat
|
---|
359 | ```
|
---|
360 | 3. Install Pytools - generally once per virtual env or whenever pip-requirements.txt changes
|
---|
361 |
|
---|
362 | ```
|
---|
363 | pip install --upgrade -r pip-requirements.txt
|
---|
364 | ```
|
---|
365 |
|
---|
366 | 4. Initialize & Update Submodules - only when submodules updated
|
---|
367 |
|
---|
368 | ```
|
---|
369 | stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
|
---|
370 |
|
---|
371 | e.g. stuart_setup -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5
|
---|
372 | ```
|
---|
373 |
|
---|
374 | 5. Initialize & Update Dependencies - only as needed when ext_deps change
|
---|
375 |
|
---|
376 | ```
|
---|
377 | stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
|
---|
378 |
|
---|
379 | e.g. stuart_update -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5
|
---|
380 | ```
|
---|
381 |
|
---|
382 | 6. Compile the basetools if necessary - only when basetools C source files change
|
---|
383 |
|
---|
384 | ```
|
---|
385 | python BaseTools/Edk2ToolsBuild.py -t <ToolChainTag>
|
---|
386 | ```
|
---|
387 |
|
---|
388 | 7. Compile DynamicTablesPkg
|
---|
389 |
|
---|
390 | ```
|
---|
391 | stuart_build-c .pytool/CISettings.py TOOL_CHAIN_TAG=<TOOL_CHAIN_TAG> -a <TARGET_ARCH>
|
---|
392 |
|
---|
393 | e.g. stuart_ci_build -c .pytool/CISettings.py TOOL_CHAIN_TAG=GCC5 -p DynamicTablesPkg -a AARCH64 --verbose
|
---|
394 | ```
|
---|
395 |
|
---|
396 | - use `stuart_build -c .pytool/CISettings.py -h` option to see help on additional options.
|
---|
397 |
|
---|
398 |
|
---|
399 | # Documentation
|
---|
400 |
|
---|
401 | Refer to the following presentation from *UEFI Plugfest Seattle 2018*:
|
---|
402 |
|
---|
403 | [Dynamic Tables Framework: A Step Towards Automatic Generation of Advanced Configuration and Power Interface (ACPI) & System Management BIOS (SMBIOS) Tables](http://www.uefi.org/sites/default/files/resources/Arm_Dynamic%20Tables%20Framework%20A%20Step%20Towards%20Automatic%20Generation%20of%20Advanced%20Configuration%20and%20Power%20Interface%20%28ACPI%29%20%26%20System%20Management%20BIOS%20%28SMBIOS%29%20Tables%20_0.pdf)
|
---|
404 |
|
---|