summaryrefslogtreecommitdiff
path: root/src/northbridge/amd/agesa
diff options
context:
space:
mode:
authorMichał Żygowski <michal.zygowski@3mdeb.com>2020-03-20 13:56:46 +0100
committerPatrick Georgi <pgeorgi@google.com>2020-03-25 10:43:37 +0000
commit9550e97304ecc1c1b6271d50ea089c82b9a82946 (patch)
tree47d39123eae170fe1a014b8bdde8d96a17f7943c /src/northbridge/amd/agesa
parenta956063e5f9c19179e4bacd145e26e159f1982b2 (diff)
acpi: correct the processor devices scope
The ACPI Spec 2.0 states, that Processor declarations should be made within the ACPI namespace \_SB and not \_PR anymore. \_PR is deprecated and is removed here. Additionally add processor scope patching for P-State SSDT created by AGESA, becasue AGESA creates the tables with processors in \_PR scope. TEST=boot Debian Linux on PC Engines apu2, check dmesg that there are no errors, decompile ACPI tables with acpica to check whether the processor scope is correct and if IASL does not complain on wrong checksum, run FWTS Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com> Change-Id: I35f112e9f9f15f06ddb83b4192f082f9e51a969c Reviewed-on: https://review.coreboot.org/c/coreboot/+/39698 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: HAOUAS Elyes <ehaouas@noos.fr> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/northbridge/amd/agesa')
-rw-r--r--src/northbridge/amd/agesa/family14/northbridge.c18
-rw-r--r--src/northbridge/amd/agesa/family15tn/northbridge.c16
-rw-r--r--src/northbridge/amd/agesa/family16kb/northbridge.c16
3 files changed, 50 insertions, 0 deletions
diff --git a/src/northbridge/amd/agesa/family14/northbridge.c b/src/northbridge/amd/agesa/family14/northbridge.c
index 4086173d7e..1ac5a69cf9 100644
--- a/src/northbridge/amd/agesa/family14/northbridge.c
+++ b/src/northbridge/amd/agesa/family14/northbridge.c
@@ -710,6 +710,21 @@ static unsigned long acpi_fill_hest(acpi_hest_t *hest)
return (unsigned long)current;
}
+static void patch_ssdt_processor_scope(acpi_header_t *ssdt)
+{
+ unsigned int len = ssdt->length - sizeof(acpi_header_t);
+ unsigned int i;
+
+ for (i = sizeof(acpi_header_t); i < len; i++) {
+ /* Search for _PR_ scope and replace it with _SB_ */
+ if (*(uint32_t *)((unsigned long)ssdt + i) == 0x5f52505f)
+ *(uint32_t *)((unsigned long)ssdt + i) = 0x5f42535f;
+ }
+ /* Recalculate checksum */
+ ssdt->checksum = 0;
+ ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);
+}
+
static unsigned long agesa_write_acpi_tables(struct device *device,
unsigned long current,
acpi_rsdp_t *rsdp)
@@ -774,6 +789,9 @@ static unsigned long agesa_write_acpi_tables(struct device *device,
printk(BIOS_DEBUG, "ACPI: * AGESA SSDT Pstate at %lx\n", current);
ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
if (ssdt != NULL) {
+ hexdump(ssdt, ssdt->length);
+ patch_ssdt_processor_scope(ssdt);
+ hexdump(ssdt, ssdt->length);
memcpy((void *)current, ssdt, ssdt->length);
ssdt = (acpi_header_t *) current;
current += ssdt->length;
diff --git a/src/northbridge/amd/agesa/family15tn/northbridge.c b/src/northbridge/amd/agesa/family15tn/northbridge.c
index 642fc150e1..a62e12e772 100644
--- a/src/northbridge/amd/agesa/family15tn/northbridge.c
+++ b/src/northbridge/amd/agesa/family15tn/northbridge.c
@@ -449,6 +449,21 @@ static void northbridge_fill_ssdt_generator(struct device *device)
acpigen_pop_len();
}
+static void patch_ssdt_processor_scope(acpi_header_t *ssdt)
+{
+ unsigned int len = ssdt->length - sizeof(acpi_header_t);
+ unsigned int i;
+
+ for (i = sizeof(acpi_header_t); i < len; i++) {
+ /* Search for _PR_ scope and replace it with _SB_ */
+ if (*(uint32_t *)((unsigned long)ssdt + i) == 0x5f52505f)
+ *(uint32_t *)((unsigned long)ssdt + i) = 0x5f42535f;
+ }
+ /* Recalculate checksum */
+ ssdt->checksum = 0;
+ ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);
+}
+
static unsigned long agesa_write_acpi_tables(struct device *device,
unsigned long current,
acpi_rsdp_t *rsdp)
@@ -525,6 +540,7 @@ static unsigned long agesa_write_acpi_tables(struct device *device,
printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
if (ssdt != NULL) {
+ patch_ssdt_processor_scope(ssdt);
memcpy((void *)current, ssdt, ssdt->length);
ssdt = (acpi_header_t *) current;
current += ssdt->length;
diff --git a/src/northbridge/amd/agesa/family16kb/northbridge.c b/src/northbridge/amd/agesa/family16kb/northbridge.c
index fcd7ec1fe6..2cdcb58023 100644
--- a/src/northbridge/amd/agesa/family16kb/northbridge.c
+++ b/src/northbridge/amd/agesa/family16kb/northbridge.c
@@ -449,6 +449,21 @@ static void northbridge_fill_ssdt_generator(struct device *device)
acpigen_pop_len();
}
+static void patch_ssdt_processor_scope(acpi_header_t *ssdt)
+{
+ unsigned int len = ssdt->length - sizeof(acpi_header_t);
+ unsigned int i;
+
+ for (i = sizeof(acpi_header_t); i < len; i++) {
+ /* Search for _PR_ scope and replace it with _SB_ */
+ if (*(uint32_t *)((unsigned long)ssdt + i) == 0x5f52505f)
+ *(uint32_t *)((unsigned long)ssdt + i) = 0x5f42535f;
+ }
+ /* Recalculate checksum */
+ ssdt->checksum = 0;
+ ssdt->checksum = acpi_checksum((void *)ssdt, ssdt->length);
+}
+
static unsigned long agesa_write_acpi_tables(struct device *device,
unsigned long current,
acpi_rsdp_t *rsdp)
@@ -525,6 +540,7 @@ static unsigned long agesa_write_acpi_tables(struct device *device,
printk(BIOS_DEBUG, "ACPI: * SSDT at %lx\n", current);
ssdt = (acpi_header_t *)agesawrapper_getlateinitptr (PICK_PSTATE);
if (ssdt != NULL) {
+ patch_ssdt_processor_scope(ssdt);
memcpy((void *)current, ssdt, ssdt->length);
ssdt = (acpi_header_t *) current;
current += ssdt->length;