From patchwork Mon Jan 27 05:05:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 240185 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Jan 2020 22:05:42 -0700 Subject: [PATCH 035/108] acpi: Record the items added to SSDT In-Reply-To: <20200127050655.170614-1-sjg@chromium.org> References: <20200127050655.170614-1-sjg@chromium.org> Message-ID: <20200126220508.35.I1f119e7a847da3e0b2b1791e6f48acaeaf25a223@changeid> It is useful to be able to control the order of data written to the SSDT so that we can compare the output against known-good kernel dumps. Add code to record each item that is added along with the device that added it. That allows us to reorder things later if needed. Signed-off-by: Simon Glass --- drivers/core/acpi.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c index 18567682f2..d7ab906757 100644 --- a/drivers/core/acpi.c +++ b/drivers/core/acpi.c @@ -14,6 +14,32 @@ #include #include +#define MAX_ITEMS 100 + +/* Type of table that we collected */ +enum gen_type_t { + TYPE_SSDT, +}; + +/** + * struct acpi_item - Holds info about ACPI data generated by a driver method + * + * @dev: Device that generated this data + * @type: Table type it refers to + * @buf: Buffer containing the data + * @size: Size of the data in bytes + */ +struct acpi_item { + struct udevice *dev; + enum gen_type_t type; + char *buf; + int size; +}; + +/* List of ACPI items collected */ +static struct acpi_item acpi_item[MAX_ITEMS]; +static int item_count; + int acpi_return_name(char *out_name, const char *name) { strcpy(out_name, name); @@ -32,6 +58,43 @@ int acpi_get_name(const struct udevice *dev, char *out_name) return -ENOSYS; } +/** + * acpi_add_item() - Add a new item to the list of data collected + * + * @ctx: ACPI context + * @dev: Device that generated the data + * @type: Table type it refers to + * @start: The start of the data (the end is obtained from ctx->current) + * @return 0 if OK, -ENOSPC if too many items, -ENOMEM if out of memory + */ +static int acpi_add_item(struct acpi_ctx *ctx, struct udevice *dev, + enum gen_type_t type, void *start) +{ + struct acpi_item *item; + void *end = ctx->current; + + if (item_count == MAX_ITEMS) { + log_err("Too many items\n"); + return log_msg_ret("mem", -ENOSPC); + } + + item = &acpi_item[item_count]; + item->dev = dev; + item->type = type; + item->size = end - start; + if (!item->size) + return 0; + item->buf = malloc(item->size); + if (!item->buf) + return log_msg_ret("mem", -ENOMEM); + memcpy(item->buf, start, item->size); + item_count++; + log_debug("* %s: Added type %d, %p, size %x\n", dev->name, type, start, + item->size); + + return 0; +} + int _acpi_fill_ssdt(struct acpi_ctx *ctx, struct udevice *parent) { struct acpi_ops *aops; @@ -40,6 +103,8 @@ int _acpi_fill_ssdt(struct acpi_ctx *ctx, struct udevice *parent) aops = device_get_acpi_ops(parent); if (aops && aops->fill_ssdt) { + void *start = ctx->current; + log_debug("\n- %s %p\n", parent->name, aops->fill_ssdt); ret = device_ofdata_to_platdata(parent); @@ -48,6 +113,11 @@ int _acpi_fill_ssdt(struct acpi_ctx *ctx, struct udevice *parent) ret = aops->fill_ssdt(parent, ctx); if (ret) return log_msg_ret("ssdt", ret); + + /* Add the item to the internal list */ + ret = acpi_add_item(ctx, parent, TYPE_SSDT, start); + if (ret) + return log_msg_ret("add", ret); } device_foreach_child(dev, parent) { ret = _acpi_fill_ssdt(ctx, dev);