diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2016-07-02 19:56:06 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-07-08 17:21:26 +0200 |
commit | ffc9990ece4c6a2148ba0a43de85f1b8ac9343ee (patch) | |
tree | 62472776e98aca78ef393348e61836e8fb1368e7 /src/arch/x86/include | |
parent | 9217f9def0fa1282fc2b510ac143c751a055dee2 (diff) |
acpi: Change device properties to work as a tree
There is a second ACPI _DSD document from the UEFI Forum that details
how _DSD style tables can be nested, creating a tree of similarly
formatted tables. This document is linked from acpi_device.h.
In order to support this the device property interface needs to be
more flexible and build up a tree of properties to write all entries
at once instead of writing each entry as it is generated.
In the end this is a more flexible solution that can support drivers
that need child tables like the DA7219 codec, while only requiring
minor changes to the existing drivers that use the device property
interface.
This was tested on reef (apollolake) and chell (skylake) boards to
ensure that there was no change in the generated SSDT AML.
Change-Id: Ia22e3a5fd3982ffa7c324bee1a8d190d49f853dd
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://review.coreboot.org/15537
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/arch/x86/include')
-rw-r--r-- | src/arch/x86/include/arch/acpi_device.h | 114 |
1 files changed, 68 insertions, 46 deletions
diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h index 65f49b2cb0..4b3a469199 100644 --- a/src/arch/x86/include/arch/acpi_device.h +++ b/src/arch/x86/include/arch/acpi_device.h @@ -229,63 +229,85 @@ struct acpi_spi { void acpi_device_write_spi(const struct acpi_spi *spi); /* - * Device Properties with _DSD - * http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf - */ - -#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" - -enum acpi_dp_type { - ACPI_DP_TYPE_INTEGER, - ACPI_DP_TYPE_STRING, - ACPI_DP_TYPE_REFERENCE, -}; - -struct acpi_dp { - enum acpi_dp_type type; - union { - uint64_t integer; - const char *string; - }; -}; - -#define ACPI_DP_INTEGER(x) { .type = ACPI_DP_TYPE_INTEGER, .integer = x } -#define ACPI_DP_STRING(x) { .type = ACPI_DP_TYPE_STRING, .string = x } -#define ACPI_DP_REFERENCE(x) { .type = ACPI_DP_TYPE_REFERENCE, .string = x } - -/* * Writing Device Properties objects via _DSD + * + * http://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf + * http://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf + * + * The Device Property Hierarchy can be multiple levels deep with multiple + * children possible in each level. In order to support this flexibility + * the device property hierarchy must be built up before being written out. + * + * For example: + * + * // Child table with string and integer + * struct acpi_dp *child = acpi_dp_new_table("CHLD"); + * acpi_dp_add_string(child, "childstring", "CHILD"); + * acpi_dp_add_integer(child, "childint", 100); + * + * // _DSD table with integer and gpio and child pointer + * struct acpi_dp *dsd = acpi_dp_new_table("_DSD"); + * acpi_dp_add_integer(dsd, "number1", 1); + * acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1); + * acpi_dp_add_child(dsd, "child", child); + * + * // Write entries into SSDT and clean up resources + * acpi_dp_write(dsd); + * + * Name(_DSD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } } + * Package() { "number1", 1 } + * } + * ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b") + * Package() { + * Package() { "child", CHLD } + * } + * } + * Name(CHLD, Package() { + * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") + * Package() { + * Package() { "childstring", "CHILD" } + * Package() { "childint", 100 } + * } + * } */ -/* Start a set of Device Properties with _DSD and UUID */ -void acpi_dp_write_header(void); +struct acpi_dp; -/* End the Device Properties set and fill in length values */ -void acpi_dp_write_footer(void); +/* Start a new Device Property table with provided ACPI reference */ +struct acpi_dp *acpi_dp_new_table(const char *ref); -/* Write a Device Property value, but not the key */ -void acpi_dp_write_value(const struct acpi_dp *prop); +/* Add integer Device Property */ +struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, + uint64_t value); -/* Write a Device Property, both key and value */ -void acpi_dp_write_keyval(const char *key, const struct acpi_dp *prop); +/* Add string Device Property */ +struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, + const char *string); -/* Write an integer as a Device Property */ -void acpi_dp_write_integer(const char *key, uint64_t value); +/* Add ACPI reference Device Property */ +struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, + const char *reference); -/* Write a string as a Device Property */ -void acpi_dp_write_string(const char *key, const char *value); +/* Add an array of Device Properties */ +struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array); -/* Write an ACPI reference as a Device Property */ -void acpi_dp_write_reference(const char *key, const char *value); +/* Add an array of integers Device Property */ +struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, + uint64_t *array, int len); -/* Write an array of Device Properties */ -void acpi_dp_write_array(const char *key, const struct acpi_dp *array, int len); +/* Add a GPIO binding Device Property */ +struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, + const char *ref, int index, int pin, + int active_low); -/* Write an array of integers as Device Properties */ -void acpi_dp_write_integer_array(const char *key, uint64_t *array, int len); +/* Add a child table of Device Properties */ +struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, + struct acpi_dp *child); -/* Write a GPIO binding Device Property */ -void acpi_dp_write_gpio(const char *key, const char *ref, int index, - int pin, int active_low); +/* Write Device Property hierarchy and clean up resources */ +void acpi_dp_write(struct acpi_dp *table); #endif |