<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Consolas, Courier, monospace; font-size: 12pt; color: rgb(0, 0, 0);">
This is really cool. Can be useful in a number of other places down the line (e.g. MAC address via device properties).</div>
<div style="font-family: Consolas, Courier, monospace; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Consolas, Courier, monospace; font-size: 12pt; color: rgb(0, 0, 0);">
Reviewed-by: Andrei Warkentin <andrey.warkentin@gmail.com></div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Jeremy Linton <jeremy.linton@arm.com><br>
<b>Sent:</b> Monday, August 31, 2020 12:25 PM<br>
<b>To:</b> devel@edk2.groups.io <devel@edk2.groups.io><br>
<b>Cc:</b> Jeremy Linton <jeremy.linton@arm.com>; Leif Lindholm <leif@nuviainc.com>; Pete Batard <pete@akeo.ie>; Andrei Warkentin <awarkentin@vmware.com>; Ard Biesheuvel <ard.biesheuvel@arm.com>; Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com><br>
<b>Subject:</b> [PATCH v4 2/6] Platform/RaspberryPi: Monitor ACPI Table installs</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hook the ACPI table install sequence and add some<br>
basic conditional and AML NameOp update logic. If<br>
a table has a non-zero PCD declared that pcd is<br>
checked for a non-zero value before allowing the table<br>
to be installed. We also add a table of NameOp to<br>
PCD's which will be written into a DSDT/SSDT table<br>
as part of its install process.<br>
<br>
With this change we can declare something in<br>
ASL like:<br>
<br>
Name (VARN, 0x1234)<br>
<br>
and then add a table entry like:<br>
<br>
{"VARN", PcdToken(PcdVarn)}<br>
<br>
and the value of PcdVarn will replace the<br>
0x1234 declared in the ASL above.<br>
<br>
Cc: Leif Lindholm <leif@nuviainc.com><br>
Cc: Pete Batard <pete@akeo.ie><br>
Cc: Andrei Warkentin <awarkentin@vmware.com><br>
Cc: Ard Biesheuvel <ard.biesheuvel@arm.com><br>
Cc: Samer El-Haj-Mahmoud <Samer.El-Haj-Mahmoud@arm.com><br>
Signed-off-by: Jeremy Linton <jeremy.linton@arm.com><br>
Reviewed-by: Pete Batard <@pbatard><br>
---<br>
 Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c | 153 ++++++++++++++++++++-<br>
 1 file changed, 152 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c<br>
index af54136ade..9e5d9734ca 100644<br>
--- a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c<br>
+++ b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c<br>
@@ -568,6 +568,156 @@ ApplyVariables (<br>
 }<br>
<br>
 <br>
<br>
 <br>
<br>
+typedef struct {<br>
<br>
+  CHAR8 Name[4];<br>
<br>
+  UINTN PcdToken;<br>
<br>
+} AML_NAME_OP_REPLACE;<br>
<br>
+<br>
<br>
+typedef struct {<br>
<br>
+  UINT64              OemTableId;<br>
<br>
+  UINTN               PcdToken;<br>
<br>
+  AML_NAME_OP_REPLACE *SdtNameOpReplace;<br>
<br>
+} NAMESPACE_TABLES;<br>
<br>
+<br>
<br>
+#define SSDT_PATTERN_LEN 5<br>
<br>
+#define AML_NAMEOP_8   0x0A<br>
<br>
+#define AML_NAMEOP_16  0x0B<br>
<br>
+#define AML_NAMEOP_32  0x0C<br>
<br>
+#define AML_NAMEOP_STR 0x0D<br>
<br>
+/*<br>
<br>
+ * Scan the given namespace table (DSDT/SSDT) for AML NameOps<br>
<br>
+ * listed in the NameOpReplace structure. If one is found then<br>
<br>
+ * update the value in the table from the specified Pcd<br>
<br>
+ *<br>
<br>
+ * This allows us to have conditionals in AML controlled<br>
<br>
+ * by options in the BDS or detected during firmware bootstrap.<br>
<br>
+ * We could extend this concept for strings/etc but due to len<br>
<br>
+ * variations its probably easier to encode the strings<br>
<br>
+ * in the ASL and pick the correct one based off a variable.<br>
<br>
+ */<br>
<br>
+STATIC VOID<br>
<br>
+UpdateSdtNameOps(<br>
<br>
+  EFI_ACPI_DESCRIPTION_HEADER  *AcpiTable,<br>
<br>
+  AML_NAME_OP_REPLACE          *NameOpReplace<br>
<br>
+  )<br>
<br>
+{<br>
<br>
+  UINTN  Idx;<br>
<br>
+  UINTN  Index;<br>
<br>
+  CHAR8  Pattern[SSDT_PATTERN_LEN];<br>
<br>
+  UINTN  PcdVal;<br>
<br>
+  UINT8  *SdtPtr;<br>
<br>
+  UINT32 SdtSize;<br>
<br>
+<br>
<br>
+  SdtSize = AcpiTable->Length;<br>
<br>
+<br>
<br>
+  if (SdtSize > 0) {<br>
<br>
+    SdtPtr = (UINT8*)AcpiTable;<br>
<br>
+<br>
<br>
+    for (Idx = 0; NameOpReplace && NameOpReplace[Idx].PcdToken; Idx++) {<br>
<br>
+      /*<br>
<br>
+       * Do a single NameOp variable replacement these are of the<br>
<br>
+       * form 08 XXXX SIZE VAL, where SIZE is 0A=byte, 0B=word, 0C=dword<br>
<br>
+       * and XXXX is the name and VAL is the value<br>
<br>
+      */<br>
<br>
+      Pattern[0] = 0x08;<br>
<br>
+      Pattern[1] = NameOpReplace[Idx].Name[0];<br>
<br>
+      Pattern[2] = NameOpReplace[Idx].Name[1];<br>
<br>
+      Pattern[3] = NameOpReplace[Idx].Name[2];<br>
<br>
+      Pattern[4] = NameOpReplace[Idx].Name[3];<br>
<br>
+<br>
<br>
+      for (Index = 0; Index < (SdtSize - SSDT_PATTERN_LEN); Index++) {<br>
<br>
+        if (CompareMem (SdtPtr + Index, Pattern, SSDT_PATTERN_LEN) == 0) {<br>
<br>
+          PcdVal = LibPcdGet32 (NameOpReplace[Idx].PcdToken);<br>
<br>
+          switch (SdtPtr[Index + SSDT_PATTERN_LEN]) {<br>
<br>
+          case AML_NAMEOP_32:<br>
<br>
+            SdtPtr[Index + SSDT_PATTERN_LEN + 4] = (PcdVal >> 24) & 0xFF;<br>
<br>
+            SdtPtr[Index + SSDT_PATTERN_LEN + 3] = (PcdVal >> 16) & 0xFF;<br>
<br>
+            // Fallthrough<br>
<br>
+          case AML_NAMEOP_16:<br>
<br>
+            SdtPtr[Index + SSDT_PATTERN_LEN + 2] = (PcdVal >> 8) & 0xFF;<br>
<br>
+            // Fallthrough<br>
<br>
+          case AML_NAMEOP_8:<br>
<br>
+            SdtPtr[Index + SSDT_PATTERN_LEN + 1] = PcdVal & 0xFF;<br>
<br>
+            break;<br>
<br>
+          case 0:<br>
<br>
+          case 1:<br>
<br>
+            SdtPtr[Index + SSDT_PATTERN_LEN + 1] = !!PcdVal;<br>
<br>
+            break;<br>
<br>
+          case AML_NAMEOP_STR:<br>
<br>
+            /*<br>
<br>
+             * If the string val is added to the NameOpReplace, we can<br>
<br>
+             * dynamically update things like _HID too as long as the<br>
<br>
+             * string length matches.<br>
<br>
+             */<br>
<br>
+            break;<br>
<br>
+          }<br>
<br>
+          break;<br>
<br>
+        }<br>
<br>
+      }<br>
<br>
+    }<br>
<br>
+  }<br>
<br>
+}<br>
<br>
+<br>
<br>
+<br>
<br>
+STATIC BOOLEAN<br>
<br>
+VerifyUpdateTable(<br>
<br>
+  IN  EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,<br>
<br>
+  IN  NAMESPACE_TABLES *SdtTable<br>
<br>
+  )<br>
<br>
+{<br>
<br>
+  BOOLEAN ret;<br>
<br>
+<br>
<br>
+  ret = TRUE;<br>
<br>
+  if (SdtTable->PcdToken && !LibPcdGet32 (SdtTable->PcdToken)) {<br>
<br>
+    ret = FALSE;<br>
<br>
+  }<br>
<br>
+  if (ret && SdtTable->SdtNameOpReplace) {<br>
<br>
+    UpdateSdtNameOps (AcpiHeader, SdtTable->SdtNameOpReplace);<br>
<br>
+  }<br>
<br>
+<br>
<br>
+  return ret;<br>
<br>
+}<br>
<br>
+<br>
<br>
+<br>
<br>
+STATIC NAMESPACE_TABLES SdtTables[] = {<br>
<br>
+  {<br>
<br>
+    SIGNATURE_64 ('R', 'P', 'I', 0, 0, 0, 0, 0),<br>
<br>
+    0,<br>
<br>
+    NULL<br>
<br>
+  },<br>
<br>
+  { }<br>
<br>
+};<br>
<br>
+<br>
<br>
+/*<br>
<br>
+ * Monitor the ACPI tables being installed and when<br>
<br>
+ * a DSDT/SSDT is detected validate that we want to<br>
<br>
+ * install it, and if so update any "NameOp" defined<br>
<br>
+ * variables contained in the table from PCD values<br>
<br>
+ */<br>
<br>
+STATIC BOOLEAN<br>
<br>
+HandleDynamicNamespace (<br>
<br>
+  IN  EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader<br>
<br>
+  )<br>
<br>
+{<br>
<br>
+  UINTN Tables;<br>
<br>
+<br>
<br>
+  switch (AcpiHeader->Signature) {<br>
<br>
+  case SIGNATURE_32 ('D', 'S', 'D', 'T'):<br>
<br>
+  case SIGNATURE_32 ('S', 'S', 'D', 'T'):<br>
<br>
+    for (Tables = 0; SdtTables[Tables].OemTableId; Tables++) {<br>
<br>
+      if (AcpiHeader->OemTableId == SdtTables[Tables].OemTableId) {<br>
<br>
+        return VerifyUpdateTable (AcpiHeader, &SdtTables[Tables]);<br>
<br>
+      }<br>
<br>
+    }<br>
<br>
+    DEBUG ((DEBUG_ERROR, "Found namespace table not in table list.\n"));<br>
<br>
+<br>
<br>
+    return FALSE;<br>
<br>
+  }<br>
<br>
+<br>
<br>
+  return TRUE;<br>
<br>
+}<br>
<br>
+<br>
<br>
+<br>
<br>
 EFI_STATUS<br>
<br>
 EFIAPI<br>
<br>
 ConfigInitialize (<br>
<br>
@@ -618,7 +768,8 @@ ConfigInitialize (<br>
 <br>
<br>
   if (PcdGet32 (PcdSystemTableMode) == SYSTEM_TABLE_MODE_ACPI ||<br>
<br>
       PcdGet32 (PcdSystemTableMode) == SYSTEM_TABLE_MODE_BOTH) {<br>
<br>
-     Status = LocateAndInstallAcpiFromFv (&mAcpiTableFile);<br>
<br>
+     Status = LocateAndInstallAcpiFromFvConditional (&mAcpiTableFile,<br>
<br>
+                                                     &HandleDynamicNamespace);<br>
<br>
      ASSERT_EFI_ERROR (Status);<br>
<br>
   }<br>
<br>
 <br>
<br>
-- <br>
2.13.7<br>
<br>
</div>
</span></font></div>
</body>
</html>

<div width="1" style="color:white;clear:both">_._,_._,_</div>
<hr>
Groups.io Links:<p>


You receive all messages sent to this group.



<p>

<a target="_blank" href="https://edk2.groups.io/g/devel/message/64857">View/Reply Online (#64857)</a> |


  


|


  
    <a target="_blank" href="https://groups.io/mt/76538744/1813853">Mute This Topic</a>
  

| <a href="https://edk2.groups.io/g/devel/post">New Topic</a><br>



<br>

<a href="https://edk2.groups.io/g/devel/editsub/1813853">Your Subscription</a> |
<a href="mailto:devel+owner@edk2.groups.io">Contact Group Owner</a> |

<a href="https://edk2.groups.io/g/devel/unsub">Unsubscribe</a>

 [edk2-devel-archive@redhat.com]<br>
<div width="1" style="color:white;clear:both">_._,_._,_</div>