From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web12.58531.1598894764022881729 for ; Mon, 31 Aug 2020 10:26:04 -0700 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: arm.com, ip: 217.140.110.172, mailfrom: jeremy.linton@arm.com) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BBB9030E; Mon, 31 Aug 2020 10:26:03 -0700 (PDT) Received: from mammon-tx2.austin.arm.com (mammon-tx2.austin.arm.com [10.118.28.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B3EA93F66F; Mon, 31 Aug 2020 10:26:03 -0700 (PDT) From: "Jeremy Linton" To: devel@edk2.groups.io Cc: Jeremy Linton , Leif Lindholm , Pete Batard , Andrei Warkentin , Ard Biesheuvel , Samer El-Haj-Mahmoud Subject: [PATCH v4 2/6] Platform/RaspberryPi: Monitor ACPI Table installs Date: Mon, 31 Aug 2020 12:25:45 -0500 Message-Id: <20200831172549.24079-3-jeremy.linton@arm.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: <20200831172549.24079-1-jeremy.linton@arm.com> References: <20200831172549.24079-1-jeremy.linton@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Hook the ACPI table install sequence and add some basic conditional and AML NameOp update logic. If a table has a non-zero PCD declared that pcd is checked for a non-zero value before allowing the table to be installed. We also add a table of NameOp to PCD's which will be written into a DSDT/SSDT table as part of its install process. With this change we can declare something in ASL like: Name (VARN, 0x1234) and then add a table entry like: {"VARN", PcdToken(PcdVarn)} and the value of PcdVarn will replace the 0x1234 declared in the ASL above. Cc: Leif Lindholm Cc: Pete Batard Cc: Andrei Warkentin Cc: Ard Biesheuvel Cc: Samer El-Haj-Mahmoud Signed-off-by: Jeremy Linton Reviewed-by: Pete Batard <@pbatard> --- Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c | 153 +++++++++++++++++= +++- 1 file changed, 152 insertions(+), 1 deletion(-) diff --git a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c b/Platform/= RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c index af54136ade..9e5d9734ca 100644 --- a/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c +++ b/Platform/RaspberryPi/Drivers/ConfigDxe/ConfigDxe.c @@ -568,6 +568,156 @@ ApplyVariables ( }=0D =0D =0D +typedef struct {=0D + CHAR8 Name[4];=0D + UINTN PcdToken;=0D +} AML_NAME_OP_REPLACE;=0D +=0D +typedef struct {=0D + UINT64 OemTableId;=0D + UINTN PcdToken;=0D + AML_NAME_OP_REPLACE *SdtNameOpReplace;=0D +} NAMESPACE_TABLES;=0D +=0D +#define SSDT_PATTERN_LEN 5=0D +#define AML_NAMEOP_8 0x0A=0D +#define AML_NAMEOP_16 0x0B=0D +#define AML_NAMEOP_32 0x0C=0D +#define AML_NAMEOP_STR 0x0D=0D +/*=0D + * Scan the given namespace table (DSDT/SSDT) for AML NameOps=0D + * listed in the NameOpReplace structure. If one is found then=0D + * update the value in the table from the specified Pcd=0D + *=0D + * This allows us to have conditionals in AML controlled=0D + * by options in the BDS or detected during firmware bootstrap.=0D + * We could extend this concept for strings/etc but due to len=0D + * variations its probably easier to encode the strings=0D + * in the ASL and pick the correct one based off a variable.=0D + */=0D +STATIC VOID=0D +UpdateSdtNameOps(=0D + EFI_ACPI_DESCRIPTION_HEADER *AcpiTable,=0D + AML_NAME_OP_REPLACE *NameOpReplace=0D + )=0D +{=0D + UINTN Idx;=0D + UINTN Index;=0D + CHAR8 Pattern[SSDT_PATTERN_LEN];=0D + UINTN PcdVal;=0D + UINT8 *SdtPtr;=0D + UINT32 SdtSize;=0D +=0D + SdtSize =3D AcpiTable->Length;=0D +=0D + if (SdtSize > 0) {=0D + SdtPtr =3D (UINT8*)AcpiTable;=0D +=0D + for (Idx =3D 0; NameOpReplace && NameOpReplace[Idx].PcdToken; Idx++) {= =0D + /*=0D + * Do a single NameOp variable replacement these are of the=0D + * form 08 XXXX SIZE VAL, where SIZE is 0A=3Dbyte, 0B=3Dword, 0C=3Dd= word=0D + * and XXXX is the name and VAL is the value=0D + */=0D + Pattern[0] =3D 0x08;=0D + Pattern[1] =3D NameOpReplace[Idx].Name[0];=0D + Pattern[2] =3D NameOpReplace[Idx].Name[1];=0D + Pattern[3] =3D NameOpReplace[Idx].Name[2];=0D + Pattern[4] =3D NameOpReplace[Idx].Name[3];=0D +=0D + for (Index =3D 0; Index < (SdtSize - SSDT_PATTERN_LEN); Index++) {=0D + if (CompareMem (SdtPtr + Index, Pattern, SSDT_PATTERN_LEN) =3D=3D = 0) {=0D + PcdVal =3D LibPcdGet32 (NameOpReplace[Idx].PcdToken);=0D + switch (SdtPtr[Index + SSDT_PATTERN_LEN]) {=0D + case AML_NAMEOP_32:=0D + SdtPtr[Index + SSDT_PATTERN_LEN + 4] =3D (PcdVal >> 24) & 0xFF= ;=0D + SdtPtr[Index + SSDT_PATTERN_LEN + 3] =3D (PcdVal >> 16) & 0xFF= ;=0D + // Fallthrough=0D + case AML_NAMEOP_16:=0D + SdtPtr[Index + SSDT_PATTERN_LEN + 2] =3D (PcdVal >> 8) & 0xFF;= =0D + // Fallthrough=0D + case AML_NAMEOP_8:=0D + SdtPtr[Index + SSDT_PATTERN_LEN + 1] =3D PcdVal & 0xFF;=0D + break;=0D + case 0:=0D + case 1:=0D + SdtPtr[Index + SSDT_PATTERN_LEN + 1] =3D !!PcdVal;=0D + break;=0D + case AML_NAMEOP_STR:=0D + /*=0D + * If the string val is added to the NameOpReplace, we can=0D + * dynamically update things like _HID too as long as the=0D + * string length matches.=0D + */=0D + break;=0D + }=0D + break;=0D + }=0D + }=0D + }=0D + }=0D +}=0D +=0D +=0D +STATIC BOOLEAN=0D +VerifyUpdateTable(=0D + IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader,=0D + IN NAMESPACE_TABLES *SdtTable=0D + )=0D +{=0D + BOOLEAN ret;=0D +=0D + ret =3D TRUE;=0D + if (SdtTable->PcdToken && !LibPcdGet32 (SdtTable->PcdToken)) {=0D + ret =3D FALSE;=0D + }=0D + if (ret && SdtTable->SdtNameOpReplace) {=0D + UpdateSdtNameOps (AcpiHeader, SdtTable->SdtNameOpReplace);=0D + }=0D +=0D + return ret;=0D +}=0D +=0D +=0D +STATIC NAMESPACE_TABLES SdtTables[] =3D {=0D + {=0D + SIGNATURE_64 ('R', 'P', 'I', 0, 0, 0, 0, 0),=0D + 0,=0D + NULL=0D + },=0D + { }=0D +};=0D +=0D +/*=0D + * Monitor the ACPI tables being installed and when=0D + * a DSDT/SSDT is detected validate that we want to=0D + * install it, and if so update any "NameOp" defined=0D + * variables contained in the table from PCD values=0D + */=0D +STATIC BOOLEAN=0D +HandleDynamicNamespace (=0D + IN EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader=0D + )=0D +{=0D + UINTN Tables;=0D +=0D + switch (AcpiHeader->Signature) {=0D + case SIGNATURE_32 ('D', 'S', 'D', 'T'):=0D + case SIGNATURE_32 ('S', 'S', 'D', 'T'):=0D + for (Tables =3D 0; SdtTables[Tables].OemTableId; Tables++) {=0D + if (AcpiHeader->OemTableId =3D=3D SdtTables[Tables].OemTableId) {=0D + return VerifyUpdateTable (AcpiHeader, &SdtTables[Tables]);=0D + }=0D + }=0D + DEBUG ((DEBUG_ERROR, "Found namespace table not in table list.\n"));=0D +=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +=0D EFI_STATUS=0D EFIAPI=0D ConfigInitialize (=0D @@ -618,7 +768,8 @@ ConfigInitialize ( =0D if (PcdGet32 (PcdSystemTableMode) =3D=3D SYSTEM_TABLE_MODE_ACPI ||=0D PcdGet32 (PcdSystemTableMode) =3D=3D SYSTEM_TABLE_MODE_BOTH) {=0D - Status =3D LocateAndInstallAcpiFromFv (&mAcpiTableFile);=0D + Status =3D LocateAndInstallAcpiFromFvConditional (&mAcpiTableFile,=0D + &HandleDynamicNamespa= ce);=0D ASSERT_EFI_ERROR (Status);=0D }=0D =0D --=20 2.13.7