Duncan Laurie has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/31668
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
vendorcode/google/chromeos: Add support for reading VPD in ACPI
This ACPI device presents an interface that allows other ACPI devices or methods to read VPD strings. The VPDF() method is provided the VPD partition to look in, and the name of the VPD key to find and it will return the VPD string if it exists.
For example: VPD.VPDF ("RO", "serial_number")
BUG=b:123925776 TEST=this was tested on a sarien platform by adding ACPI code that searches for a VPD key and returns the value it finds, and then setting that VPD string from the OS with the Chrome OS 'vpd' utility to ensure the ACPI method returns the correct value.
Change-Id: I4668f66d7f7f364ac8c3b064d406b24135abb0f6 Signed-off-by: Duncan Laurie dlaurie@google.com --- A src/vendorcode/google/chromeos/acpi/vpd.asl 1 file changed, 226 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/31668/1
diff --git a/src/vendorcode/google/chromeos/acpi/vpd.asl b/src/vendorcode/google/chromeos/acpi/vpd.asl new file mode 100644 index 0000000..bd77cb7 --- /dev/null +++ b/src/vendorcode/google/chromeos/acpi/vpd.asl @@ -0,0 +1,226 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * This device provides an ACPI interface to read VPD keys from either + * the RO_VPD or RW_VPD region. For example: + * + * VPD.VPDF ("RO", "ro_key_name") + * VPD.VPDF ("RW", "rw_key_name") + */ + +Device (VPD) +{ + Name (_HID, "GOOG000F") + Name (_UID, 1) + Name (_STA, 0xf) + + Name (VOFS, 0x600) /* Start of VPD header in VPD region */ + Name (VIHL, 0x10) /* Length of VPD info header */ + Name (VPET, 0x00) /* VPD Entry Type: Terminator */ + Name (VPES, 0x01) /* VPD Entry Type: String */ + Name (VPEI, 0xfe) /* VPD Entry Type: Info (header) */ + Name (MORE, 0x80) /* Bit to indicate more length bytes */ + + Name (VPTR, Zero) /* Pointer to current byte in VPD for parser */ + Name (VEND, Zero) /* End of VPD region */ + + /* + * VLOC() - Return location and length of VPD region in memory. + * These values must be initialized in GNVS by coreboot. + * + * Returns: Package indicating start and length of region: + * [0] = Address of the start of VPD region. + * [1] = Length of the VPD region. + */ + Method (VLOC, 1, Serialized) + { + Switch (ToString (Arg0)) + { + Case ("RO") { + Return (Package () { \ROVP, \ROVL }) + } + Case ("RW") { + Return (Package () { \RWVP, \RWVL }) + } + Default { + Return (Package () { Zero, Zero }) + } + } + } + + /* + * VVPD() - Verify VPD info header. + * Arg0: VPD partition base address. + * Returns: VPD length or Zero if VPD header is not valid. + */ + Method (VVPD, 1, Serialized) + { + Local0 = Arg0 + ^VOFS + + OperationRegion (VPDH, SystemMemory, Local0, ^VIHL) + Field (VPDH, DWordAcc, NoLock, Preserve) + { + TYPE, 8, /* VPD Header Tag (=0xfe) */ + KLEN, 8, /* Key length (=9) */ + IVER, 8, /* Info version (=1) */ + SIGN, 64, /* Signature (="gVpdInfo") */ + VLEN, 8, /* Value length (=4) */ + SIZE, 32, /* VPD length */ + } + + If (TYPE != ^VPEI) { + Return (Zero) + } + If (KLEN != 9) { + Return (Zero) + } + If (IVER != 1) { + Return (Zero) + } + If (ToString (SIGN) != "gVpdInfo") { + Return (Zero) + } + If (VLEN != 4) { + Return (Zero) + } + + Return (SIZE) + } + + /* Return next byte from VPD at pointer VPTR, and increment VPTR. */ + Method (VPRB, 0, Serialized) + { + If (^VPTR > ^VEND) { + Printf ("Access beyond end of VPD region") + Return (Zero) + } + + Local0 = ^VPTR + OperationRegion (VPDR, SystemMemory, Local0, One) + Field (VPDR, DWordAcc, NoLock, Preserve) + { + BYTE, 8, + } + + /* Increment address pointer */ + ^VPTR++ + Return (BYTE) + } + + /* Extract and return next string from VPD. */ + Method (VPDE, 0, Serialized) + { + Local0 = One /* Indicates if there are more bytes */ + Local1 = Zero /* Length */ + + /* Decode the string length */ + While (Local0) { + /* Read the next byte at indicated address */ + Local2 = ^VPRB () + + /* Update the more bit from the byte in Local2 */ + Local0 = Local2 >> 7 + + /* Save the length bits from Local2 */ + Local1 <<= 7 + Local1 |= Local2 & 0x7f + } + If (!Local1) { + Return (Zero) + } + + /* Extract the string */ + Local3 = Zero + Local4 = "" + While (Local3 < Local1) { + Concatenate (Local4, ToString (^VPRB ()), Local4) + Local3++ + } + + Return (Local4) + } + + /* + * VPDS() - Find next VPD key and value. + * Returns: Package containing key and value: + * [0] = VPD key string + * [1] = VPD value string + */ + Method (VPDS, 0, Serialized) + { + Name (VPKV, Package () { Zero, Zero }) + + /* Read the VPD type and ensure it is a string */ + If (^VPRB () != ^VPES) { + Printf ("VPDS: Type is not a string") + Return (VPKV) + } + + /* Extract the key string and value */ + VPKV[0] = VPDE () + VPKV[1] = VPDE () + + Return (VPKV) + } + + /* + * VPDF() - Find VPD key with matching name. + * Arg0: VPD Partition, either "RO" or "RW". + * Arg1: VPD key name to search for. + * Returns: VPD string corresponding to VPD key, or Zero if not found. + */ + Method (VPDF, 2, Serialized) + { + Local0 = VLOC (Arg0) + + /* Start of VPD region */ + ^VPTR = DeRefOf (Local0[0]) + + /* End address of VPD region */ + ^VEND = ^VPTR + DeRefOf (Local0[1]) + + If (!^VPTR || !^VEND) { + Printf ("Unable to find VPD region") + Return (Zero) + } + + /* Verify VPD info header and save size */ + Local0 = VVPD (^VPTR) + If (!Local0) { + Printf ("VPD region %o did not verify", Arg0) + Return (Zero) + } + + /* Set VPD pointer to start of VPD entries */ + ^VPTR += ^VOFS + ^VIHL + + /* Search through VPD entries until key is found */ + Local1 = "" + While (Local1 != ToString (Arg1)) { + Local2 = VPDS () + Local1 = DeRefOf (Local2[0]) + If (!Local1) { + Printf ("VPD KEY %o not found", Arg1) + Return (Zero) + } + } + Local3 = DeRefOf (Local2[1]) + + Printf ("Found VPD KEY %o = %o", Local1, Local3) + Return (Local3) + } +}
Paul Menzel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31668 )
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
Patch Set 1: Code-Review+1
(1 comment)
https://review.coreboot.org/#/c/31668/1//COMMIT_MSG Commit Message:
https://review.coreboot.org/#/c/31668/1//COMMIT_MSG@10 PS1, Line 10: provided providing?
Lijian Zhao has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31668 )
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
Patch Set 1:
(2 comments)
https://review.coreboot.org/#/c/31668/1/src/vendorcode/google/chromeos/acpi/... File src/vendorcode/google/chromeos/acpi/vpd.asl:
https://review.coreboot.org/#/c/31668/1/src/vendorcode/google/chromeos/acpi/... PS1, Line 191: DeRefOf DerefOf
https://review.coreboot.org/#/c/31668/1/src/vendorcode/google/chromeos/acpi/... PS1, Line 215: DeRefOf DerefOf
Hello Paul Menzel, build bot (Jenkins),
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/31668
to look at the new patch set (#2).
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
vendorcode/google/chromeos: Add support for reading VPD in ACPI
This ACPI device presents an interface that allows other ACPI devices or methods to read VPD strings. The VPDF() method is provided the VPD partition to look in, and the name of the VPD key to find and it will return the VPD string if it exists.
For example: VPD.VPDF ("RO", "serial_number")
BUG=b:123925776 TEST=this was tested on a sarien platform by adding ACPI code that searches for a VPD key and returns the value it finds, and then setting that VPD string from the OS with the Chrome OS 'vpd' utility to ensure the ACPI method returns the correct value.
Change-Id: I4668f66d7f7f364ac8c3b064d406b24135abb0f6 Signed-off-by: Duncan Laurie dlaurie@google.com --- A src/vendorcode/google/chromeos/acpi/vpd.asl 1 file changed, 226 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/31668/2
Duncan Laurie has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31668 )
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
Patch Set 2:
(2 comments)
https://review.coreboot.org/#/c/31668/1/src/vendorcode/google/chromeos/acpi/... File src/vendorcode/google/chromeos/acpi/vpd.asl:
https://review.coreboot.org/#/c/31668/1/src/vendorcode/google/chromeos/acpi/... PS1, Line 191: DeRefOf
DerefOf
Done
https://review.coreboot.org/#/c/31668/1/src/vendorcode/google/chromeos/acpi/... PS1, Line 215: DeRefOf
DerefOf
Done
Lijian Zhao has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/31668 )
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
Patch Set 2: Code-Review+2
Patrick Georgi has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/31668 )
Change subject: vendorcode/google/chromeos: Add support for reading VPD in ACPI ......................................................................
vendorcode/google/chromeos: Add support for reading VPD in ACPI
This ACPI device presents an interface that allows other ACPI devices or methods to read VPD strings. The VPDF() method is provided the VPD partition to look in, and the name of the VPD key to find and it will return the VPD string if it exists.
For example: VPD.VPDF ("RO", "serial_number")
BUG=b:123925776 TEST=this was tested on a sarien platform by adding ACPI code that searches for a VPD key and returns the value it finds, and then setting that VPD string from the OS with the Chrome OS 'vpd' utility to ensure the ACPI method returns the correct value.
Change-Id: I4668f66d7f7f364ac8c3b064d406b24135abb0f6 Signed-off-by: Duncan Laurie dlaurie@google.com Reviewed-on: https://review.coreboot.org/c/31668 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Lijian Zhao lijian.zhao@intel.com --- A src/vendorcode/google/chromeos/acpi/vpd.asl 1 file changed, 226 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Lijian Zhao: Looks good to me, approved
diff --git a/src/vendorcode/google/chromeos/acpi/vpd.asl b/src/vendorcode/google/chromeos/acpi/vpd.asl new file mode 100644 index 0000000..3b262f7 --- /dev/null +++ b/src/vendorcode/google/chromeos/acpi/vpd.asl @@ -0,0 +1,226 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * This device provides an ACPI interface to read VPD keys from either + * the RO_VPD or RW_VPD region. For example: + * + * VPD.VPDF ("RO", "ro_key_name") + * VPD.VPDF ("RW", "rw_key_name") + */ + +Device (VPD) +{ + Name (_HID, "GOOG000F") + Name (_UID, 1) + Name (_STA, 0xf) + + Name (VOFS, 0x600) /* Start of VPD header in VPD region */ + Name (VIHL, 0x10) /* Length of VPD info header */ + Name (VPET, 0x00) /* VPD Entry Type: Terminator */ + Name (VPES, 0x01) /* VPD Entry Type: String */ + Name (VPEI, 0xfe) /* VPD Entry Type: Info (header) */ + Name (MORE, 0x80) /* Bit to indicate more length bytes */ + + Name (VPTR, Zero) /* Pointer to current byte in VPD for parser */ + Name (VEND, Zero) /* End of VPD region */ + + /* + * VLOC() - Return location and length of VPD region in memory. + * These values must be initialized in GNVS by coreboot. + * + * Returns: Package indicating start and length of region: + * [0] = Address of the start of VPD region. + * [1] = Length of the VPD region. + */ + Method (VLOC, 1, Serialized) + { + Switch (ToString (Arg0)) + { + Case ("RO") { + Return (Package () { \ROVP, \ROVL }) + } + Case ("RW") { + Return (Package () { \RWVP, \RWVL }) + } + Default { + Return (Package () { Zero, Zero }) + } + } + } + + /* + * VVPD() - Verify VPD info header. + * Arg0: VPD partition base address. + * Returns: VPD length or Zero if VPD header is not valid. + */ + Method (VVPD, 1, Serialized) + { + Local0 = Arg0 + ^VOFS + + OperationRegion (VPDH, SystemMemory, Local0, ^VIHL) + Field (VPDH, DWordAcc, NoLock, Preserve) + { + TYPE, 8, /* VPD Header Tag (=0xfe) */ + KLEN, 8, /* Key length (=9) */ + IVER, 8, /* Info version (=1) */ + SIGN, 64, /* Signature (="gVpdInfo") */ + VLEN, 8, /* Value length (=4) */ + SIZE, 32, /* VPD length */ + } + + If (TYPE != ^VPEI) { + Return (Zero) + } + If (KLEN != 9) { + Return (Zero) + } + If (IVER != 1) { + Return (Zero) + } + If (ToString (SIGN) != "gVpdInfo") { + Return (Zero) + } + If (VLEN != 4) { + Return (Zero) + } + + Return (SIZE) + } + + /* Return next byte from VPD at pointer VPTR, and increment VPTR. */ + Method (VPRB, 0, Serialized) + { + If (^VPTR > ^VEND) { + Printf ("Access beyond end of VPD region") + Return (Zero) + } + + Local0 = ^VPTR + OperationRegion (VPDR, SystemMemory, Local0, One) + Field (VPDR, DWordAcc, NoLock, Preserve) + { + BYTE, 8, + } + + /* Increment address pointer */ + ^VPTR++ + Return (BYTE) + } + + /* Extract and return next string from VPD. */ + Method (VPDE, 0, Serialized) + { + Local0 = One /* Indicates if there are more bytes */ + Local1 = Zero /* Length */ + + /* Decode the string length */ + While (Local0) { + /* Read the next byte at indicated address */ + Local2 = ^VPRB () + + /* Update the more bit from the byte in Local2 */ + Local0 = Local2 >> 7 + + /* Save the length bits from Local2 */ + Local1 <<= 7 + Local1 |= Local2 & 0x7f + } + If (!Local1) { + Return (Zero) + } + + /* Extract the string */ + Local3 = Zero + Local4 = "" + While (Local3 < Local1) { + Concatenate (Local4, ToString (^VPRB ()), Local4) + Local3++ + } + + Return (Local4) + } + + /* + * VPDS() - Find next VPD key and value. + * Returns: Package containing key and value: + * [0] = VPD key string + * [1] = VPD value string + */ + Method (VPDS, 0, Serialized) + { + Name (VPKV, Package () { Zero, Zero }) + + /* Read the VPD type and ensure it is a string */ + If (^VPRB () != ^VPES) { + Printf ("VPDS: Type is not a string") + Return (VPKV) + } + + /* Extract the key string and value */ + VPKV[0] = VPDE () + VPKV[1] = VPDE () + + Return (VPKV) + } + + /* + * VPDF() - Find VPD key with matching name. + * Arg0: VPD Partition, either "RO" or "RW". + * Arg1: VPD key name to search for. + * Returns: VPD string corresponding to VPD key, or Zero if not found. + */ + Method (VPDF, 2, Serialized) + { + Local0 = VLOC (Arg0) + + /* Start of VPD region */ + ^VPTR = DerefOf (Local0[0]) + + /* End address of VPD region */ + ^VEND = ^VPTR + DerefOf (Local0[1]) + + If (!^VPTR || !^VEND) { + Printf ("Unable to find VPD region") + Return (Zero) + } + + /* Verify VPD info header and save size */ + Local0 = VVPD (^VPTR) + If (!Local0) { + Printf ("VPD region %o did not verify", Arg0) + Return (Zero) + } + + /* Set VPD pointer to start of VPD entries */ + ^VPTR += ^VOFS + ^VIHL + + /* Search through VPD entries until key is found */ + Local1 = "" + While (Local1 != ToString (Arg1)) { + Local2 = VPDS () + Local1 = DerefOf (Local2[0]) + If (!Local1) { + Printf ("VPD KEY %o not found", Arg1) + Return (Zero) + } + } + Local3 = DerefOf (Local2[1]) + + Printf ("Found VPD KEY %o = %o", Local1, Local3) + Return (Local3) + } +}