-
Notifications
You must be signed in to change notification settings - Fork 2.9k
RIMT parser for acpiview command #11541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
RIMT parser for acpiview command #11541
Conversation
c68e3f3
to
3cbb7ee
Compare
) | ||
{ | ||
PrintRimtNodeHeader ((EFI_ACPI_6_6_RIMT_NODE_HEADER_STRUCTURE *)Node); | ||
HardwareIdToString (&Node->HardwareId, HardwareIdStr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could replace with call to AsciiStrnCpyS instead of custom function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
Show resolved
Hide resolved
RimtNodeIommuTypeName[GET_BIT (0, Node->Flags)], | ||
RimtNodeIommuProximityDomainTypeName[GET_BIT (1, Node->Flags)] | ||
); | ||
Print (L"\tProximity Domain : %d\n", Node->ProximityDomain); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello Krzysztof,
Would it be possible to follow the table-based approach as the other parsers do ?
The Mcfg Parser should provide a good example:
ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c
and there are also wrappers to print bitfields, cf., the ParseAcpiBitFields()
function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Pierre,
I could but the issue I see with table approach is that it respects ACPI structures from MdePkg/Include/IndustryStandard/
only partially (only generic ACPI header from Acpi.h
in fact)
I looked at MdePkg/Include/IndustryStandard/IoRemappingTable.h
and ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
for instance.
IortParser
duplicates most of IORT structures in a way of offset definitions in parser tables.
There is no sync point between state of IndustryStandard
headers and parser tables in IORT acpiview
for example. Do you recommend rewriting to table-based
approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is effectively no synchronization between the MdePkg definitions and the AcpiView definitions, however using the table-based approach:
- allows to have a uniform way to display the information. Modifying
ParseAcpi()
would allow to update the way to print all tables without applying changes to each parser individually - does some additional checking. In the RIMT parser, there doesn't seem to be any check regarding the size of the table: if the table contains an error, the parser will try to access data outside of the table.
- allows to have cross-table validation. This is not present right now, but there was an idea of keeping track of some field values of some tables in order to validate the fields of some other tables. If the parser just prints the fields, this is not possible to do anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pierregondois Ok What about something like
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c
index 5cdd34f442..5410355548 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rimt/RimtParser.c
@@ -29,9 +29,9 @@ STATIC EFI_ACPI_6_6_RIMT_STRUCTURE RimtHdrInfo;
**/
STATIC CONST ACPI_PARSER RimtParser[] = {
PARSE_ACPI_HEADER (&RimtHdrInfo.Header),
- { L"Number of RIMT Nodes", 4, 36, L"%d", NULL, NULL, NULL, NULL },
- { L"Offset to RIMT Node Array", 4, 40, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL }
+ { L"Number of RIMT Nodes", sizeof(RimtHdrInfo.NumberOfRimtNodes), OFFSET_OF(EFI_ACPI_6_6_RIMT_STRUCTURE, NumberOfRimtNodes), L"%d", NULL, NULL, NULL, NULL },^M
+ { L"Offset to RIMT Node Array", sizeof(RimtHdrInfo.OffsetToRimtNodeArray), OFFSET_OF(EFI_ACPI_6_6_RIMT_STRUCTURE, OffsetToRimtNodeArray), L"0x%x", NULL, NULL, NULL, NULL },^M
+ { L"Reserved", sizeof(RimtHdrInfo.Reserved), OFFSET_OF(EFI_ACPI_6_6_RIMT_STRUCTURE, Reserved), L"0x%x", NULL, NULL, NULL, NULL }^M
This way acpiview could validate IndustrialStandard table header for real.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way acpiview could validate IndustrialStandard table header for real.
Yeah, that looks like something we would want to do across the board. So would be good to do start doing it at least for new additions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes nice, it is better to avoid hard coded value. (+ tables are used for parsing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@leiflindholm the original intent behind the current approach in acpiview was that the first three fields of the ACPI_PARSER—Field, Byte Length, and Byte Offset—would be taken directly from the ACPI table specification. For example, these correspond to the first three columns in the MADT table definition: https://uefi.org/specs/ACPI/6.6/05_ACPI_Software_Programming_Model.html#multiple-apic-description-table-madt
This approach helps verify that the offsets in the specification are correct, since the parser would flag an error if there were any mismatches.
I’m not sure if this is still considered useful, but it has definitely helped in the past to catch issues.
Personally, I’d be inclined to keep this scheme if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@samimujawar I'm not sure I understand.
Are you saing it's beneficial to hard-code the values instead of using the core definitions because people would be unlikely to get it wrong in the same way twice when manually transcribing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it again it is a maintenance overhead as one has to review that the first 3 fields have been populated correctly. If the field definitions from the structure are used, those definitions would need to reflect the spec, and if the size and offset mismatch it will get flagged by the parser.
So we can go with the proposed approach rather that hardcoding the values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pierregondois Switched to ACPI_PARSERs
Introduce RIMT (RISC-V IO Mapping Table) structures as specified in [1]. RIMT was introduced as part of ACPI in version 6.6 [2]. [1] RISC-V IO Mapping Table (RIMT) Specification, Version v1.0, 2025-03-31 https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v1.0/rimt-spec.pdf [2] Advanced Configuration and Power Interface specification, Version 6.6 https://uefi.org/specs/ACPI/6.6/ Signed-off-by: Krzysztof Drobiński <krzysztof@plasteli.net>
Implementation tested on Qemu-10.1 virt machine with IOMMU enabled. Signed-off-by: Krzysztof Drobiński <krzysztof@plasteli.net>
3cbb7ee
to
8af2978
Compare
|
(https://uefi.org/specs/ACPI/6.6/) | ||
**/ | ||
|
||
#ifndef __RISCV_IO_MAPPING_TABLE_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Symbol names with leading underscore are reserved for toolchain use. (Please drop leading __).
VOID *Context | ||
) | ||
{ | ||
UINT32 data; // "Number of RIMT Nodes" field is 4 byte long in spec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'Data', not 'data'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although if this is a variable to hold specifically the number of nodes, it probably ought to be called NumNodes or something more descriptive.
PCIERC, | ||
PLATFORM, | ||
UNSUPPORTED | ||
} RimtNodeTypes; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this should go in the MdePkg as these values are spec-related
UINT8 NodeType; | ||
|
||
NodeType = *(UINT8 *)Ptr; | ||
if (NodeType == IOMMU) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be easier to use an array of strings, cf. the ErstActionTable
for instance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pierregondois Not sure about that. It will make reading this simple code harder (by need of jumping to array of strings to see what's behind the Str
). Additionally, we will loose relation to RimtNodeTypes
here in favor of array index. Those strings are not used anywhere except this routine. What's the benefit?
Every RIMT Node (IOMMU, PCIe Root Complex, PLatform Device) has this header | ||
common | ||
**/ | ||
STATIC UINT8 *RimtNodeType; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, static variables should be prefixed by m
: mRimtNodeType
And also ideally be placed at the beginning of the file.
Same comment at other places
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, static variables should be prefixed by m: mRimtNodeType
Ok
And also ideally be placed at the beginning of the file.
Is that approach required by EDK2? IMHO, It makes code harder to read. Declaring (if possible) variables in places where they are going to be used for the first time simplifies reading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a general rule, yeah. Each variant has its own benefits, we picked this one.
RIMT_PARSE_NODE_HEADER | ||
}; | ||
|
||
#define RIMT_MINIMAL_NUMBER_OF_NODES_ALLOWED 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, might move the definition to the MdePkg.
Please move all the possible RIMT definitions to the MdePkg
@param [in] Active String to display if interpreted bit is active. | ||
@param [in] Inactive String to display if interpreted bit is inactive. | ||
**/ | ||
#define RIMT_DECLARE_FLAGS_BIT_PARSER_FUNC(Parser, Active, Inactive) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems quite complex to have a mapping:
0 -> Inactive
1 -> Active
Would it be ok to just print the bit value ?
If no, would it possible instead to define an generic abstraction in:
ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
using a similar logic as in the MadtParser.c::DumpValue()
so that other parsers can re-use it ?
Tagging @leiflindholm just in case as what I m suggesting is slightly questionable.
@param [in] Parser An ACPI_PARSER for tracing the data. | ||
**/ | ||
#define RIMT_DECLARE_NODE_FLAGS_PARSER_FUNC(Parser) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be a bit over-engineering. I don't know what other people think
Description
RISC-V IO Mapping Table (RIMT) is the ACPI table describing relations between IOMMU and other devices on RISC-V architecture.
See https://github.com/riscv-non-isa/riscv-acpi-rimt for details.
This PR extends acpiview command by adding RIMT parser
How This Was Tested
Tested on qemu-10.1 with RISC-V IOMMU enabled configured as SYS as well as PCIe device
Then in UEFI Shell
Integration Instructions
N/A