Matt DeVillier has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/84192?usp=email )
Change subject: acpi/acpigen: Increase max package length for acpigen_pop_len() ......................................................................
acpi/acpigen: Increase max package length for acpigen_pop_len()
The AML spec allows for up to 4 bytes to be used to encode the package length, so adjust acpigen_pop_len() to accommodate that now that we're running up against the packaged size limit available when only 3 bytes are used to encode the length.
Change-Id: I8f72fa84cfdae480fec42b0968bd7cefcdb96bdc Signed-off-by: Matt DeVillier matt.devillier@gmail.com --- M src/acpi/acpigen.c 1 file changed, 35 insertions(+), 16 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/84192/1
diff --git a/src/acpi/acpigen.c b/src/acpi/acpigen.c index 4049df0..d6b652e 100644 --- a/src/acpi/acpigen.c +++ b/src/acpi/acpigen.c @@ -4,7 +4,7 @@ #define ACPIGEN_LENSTACK_SIZE 10
/* If you need to change this, change acpigen_pop_len too */ -#define ACPIGEN_RSVD_PKGLEN_BYTES 3 +#define ACPIGEN_RSVD_PKGLEN_BYTES 4
#include <lib.h> #include <string.h> @@ -42,13 +42,13 @@
if (len <= 0x3f + 2) { /* PkgLength of up to 0x3f can be encoded in one PkgLength byte instead of the - reserved 3 bytes. Since only 1 PkgLength byte will be written, the payload - data needs to be moved by 2 bytes */ - memmove(&p[ACPIGEN_RSVD_PKGLEN_BYTES - 2], + reserved 4 bytes. Since only 1 PkgLength byte will be written, the payload + data needs to be moved by 3 bytes */ + memmove(&p[ACPIGEN_RSVD_PKGLEN_BYTES - 3], &p[ACPIGEN_RSVD_PKGLEN_BYTES], payload_len); - /* Adjust the PkgLength to take into account that we only use 1 of the 3 + /* Adjust the PkgLength to take into account that we only use 1 of the 4 reserved bytes */ - len -= 2; + len -= 3; /* The two most significant bits of PkgLength get the value of 0 to indicate there are no additional PkgLength bytes. In this case the single PkgLength byte encodes the length in its lower 6 bits */ @@ -57,13 +57,13 @@ acpigen_set_current(p + len); } else if (len <= 0xfff + 1) { /* PkgLength of up to 0xfff can be encoded in 2 PkgLength bytes instead of the - reserved 3 bytes. Since only 2 PkgLength bytes will be written, the payload - data needs to be moved by 1 byte */ - memmove(&p[ACPIGEN_RSVD_PKGLEN_BYTES - 1], + reserved 4 bytes. Since only 2 PkgLength bytes will be written, the payload + data needs to be moved by 2 bytes */ + memmove(&p[ACPIGEN_RSVD_PKGLEN_BYTES - 2], &p[ACPIGEN_RSVD_PKGLEN_BYTES], payload_len); - /* Adjust the PkgLength to take into account that we only use 2 of the 3 + /* Adjust the PkgLength to take into account that we only use 2 of the 4 reserved bytes */ - len -= 1; + len -= 2; /* The two most significant bits of PkgLength get the value of 1 to indicate there's a second PkgLength byte. The lower 4 bits of the first PkgLength byte and the second PkgLength byte encode the length */ @@ -72,19 +72,38 @@ /* Adjust pointer for next ACPI bytecode byte */ acpigen_set_current(p + len); } else if (len <= 0xfffff) { - /* PkgLength of up to 0xfffff can be encoded in 3 PkgLength bytes. Since this - is the amount of reserved bytes, no need to move the payload in this case */ - /* The two most significant bits of PkgLength get the value of 2 to indicate - there are two more PkgLength bytes following the first one. The lower 4 bits + /* PkgLength of up to 0xfffff can be encoded in 3 PkgLength bytes instead of the + reserved 4 bytes. Since only 3 PkgLength bytes will be written, the payload + data needs to be moved by 1 byte */ + memmove(&p[ACPIGEN_RSVD_PKGLEN_BYTES - 1], + &p[ACPIGEN_RSVD_PKGLEN_BYTES], payload_len); + /* Adjust the PkgLength to take into account that we only use 3 of the 4 + reserved bytes */ + len -= 1; + /* The two most significant bits of PkgLength get the value of 3 to indicate + there are three more PkgLength bytes following the first one. The lower 4 bits of the first PkgLength byte and the two following PkgLength bytes encode the length */ p[0] = (0x2 << 6 | (len & 0xf)); p[1] = (len >> 4 & 0xff); p[2] = (len >> 12 & 0xff); + /* Adjust pointer for next ACPI bytecode byte */ + acpigen_set_current(p + len); + } else if (len <= 0xfffffff) { + /* PkgLength of up to 0xfffffff can be encoded in 3 PkgLength bytes. Since this + is the amount of reserved bytes, no need to move the payload in this case */ + /* The two most significant bits of PkgLength get the value of 2 to indicate + there are two more PkgLength bytes following the first one. The lower 4 bits + of the first PkgLength byte and the two following PkgLength bytes encode the + length */ + p[0] = (0x3 << 6 | (len & 0xf)); + p[1] = (len >> 4 & 0xff); + p[2] = (len >> 12 & 0xff); + p[3] = (len >> 20 & 0xff); /* No need to adjust pointer for next ACPI bytecode byte */ } else { /* The case of PkgLength up to 0xfffffff isn't supported at the moment */ - printk(BIOS_ERR, "%s: package length exceeds maximum of 0xfffff.\n", __func__); + printk(BIOS_ERR, "%s: package length exceeds maximum of 0xfffffff.\n", __func__); } }