Hi Simon,

On Sun, Jun 14, 2020 at 10:55 AM Simon Glass <s...@chromium.org> wrote:
>
> Add a /chosen property to control the order in which the data appears
> in the SSDT. This allows matching up U-Boot's output from a dump of the
> known-good data obtained from within Linux.
>
> Signed-off-by: Simon Glass <s...@chromium.org>
> ---
>
> Changes in v3:
> - Make find_item() static and rename to find_acpi_item()
> - Rename build_type() and add a comment
>
> Changes in v1:
> - Generalise the ACPI function recursion with acpi_recurse_method()
>
>  arch/sandbox/dts/test.dts           |  5 +-
>  doc/device-tree-bindings/chosen.txt |  9 ++++
>  drivers/core/acpi.c                 | 75 +++++++++++++++++++++++++++++
>  test/dm/acpi.c                      | 15 +++---
>  4 files changed, 96 insertions(+), 8 deletions(-)
>
> diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
> index 30394946f8..993082763d 100644
> --- a/arch/sandbox/dts/test.dts
> +++ b/arch/sandbox/dts/test.dts
> @@ -254,7 +254,7 @@
>                 compatible = "denx,u-boot-devres-test";
>         };
>
> -       acpi-test {
> +       acpi_test1: acpi-test {
>                 compatible = "denx,u-boot-acpi-test";
>                 acpi-ssdt-test-data = "ab";
>                 child {
> @@ -262,7 +262,7 @@
>                 };
>         };
>
> -       acpi-test2 {
> +       acpi_test2: acpi-test2 {
>                 compatible = "denx,u-boot-acpi-test";
>                 acpi-ssdt-test-data = "cd";
>         };
> @@ -895,6 +895,7 @@
>                 setting = "sunrise ohoka";
>                 other-node = "/some-bus/c-test@5";
>                 int-values = <0x1937 72993>;
> +               u-boot,acpi-ssdt-order = <&acpi_test2 &acpi_test1>;
>                 chosen-test {
>                         compatible = "denx,u-boot-fdt-test";
>                         reg = <9 1>;
> diff --git a/doc/device-tree-bindings/chosen.txt 
> b/doc/device-tree-bindings/chosen.txt
> index 395c9501e3..d4dfc05847 100644
> --- a/doc/device-tree-bindings/chosen.txt
> +++ b/doc/device-tree-bindings/chosen.txt
> @@ -134,3 +134,12 @@ Example
>                 phandlepart = <&mmc 1>;
>         };
>  };
> +
> +u-boot,acpi-ssdt-order
> +----------------------
> +
> +This provides the ordering to use when writing device data to the ACPI SSDT
> +(Secondary System Descriptor Table). Each cell is a phandle pointer to a 
> device
> +node to add. The ACPI information is written in this order.
> +
> +If the ordering does not include all nodes, an error is generated.
> diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
> index df3d7ba417..4719a5c4e4 100644
> --- a/drivers/core/acpi.c
> +++ b/drivers/core/acpi.c
> @@ -108,6 +108,76 @@ static int acpi_add_item(struct acpi_ctx *ctx, struct 
> udevice *dev,
>         return 0;
>  }
>
> +static struct acpi_item *find_acpi_item(const char *devname)
> +{
> +       int i;
> +
> +       for (i = 0; i < item_count; i++) {
> +               struct acpi_item *item = &acpi_item[i];
> +
> +               if (!strcmp(devname, item->dev->name))
> +                       return item;
> +       }
> +
> +       return NULL;
> +}
> +
> +/**
> + * sort_acpi_item_type - Sort the ACPI items into the desired order
> + *
> + * This looks up the ordering in the device tree and then adds each item one 
> by
> + * one into the supplied buffer
> + *
> + * @ctx: ACPI context
> + * @start: Start position to put the sorted items. The items will follow each
> + *     other in sorted order
> + * @type: Type of items to sort
> + * @return 0 if OK, -ve on error
> + */
> +static int sort_acpi_item_type(struct acpi_ctx *ctx, void *start,
> +                              enum gen_type_t type)
> +{
> +       const u32 *order;
> +       int size;
> +       int count;
> +       void *ptr;
> +       void *end = ctx->current;
> +
> +       ptr = start;
> +       order = ofnode_read_chosen_prop("u-boot,acpi-ssdt-order", &size);
> +       if (!order) {
> +               log_warning("Failed to find ordering, leaving as is\n");
> +               return 0;
> +       }
> +
> +       count = size / sizeof(u32);
> +       while (count--) {
> +               struct acpi_item *item;
> +               const char *name;
> +               ofnode node;
> +
> +               node = ofnode_get_by_phandle(fdt32_to_cpu(*order++));
> +               name = ofnode_get_name(node);
> +               item = find_acpi_item(name);
> +               if (!item) {
> +                       log_err("Failed to find item '%s'\n", name);
> +                       return log_msg_ret("find", -ENOENT);
> +               }
> +               if (item->type == type) {
> +                       log_debug("   - add %s\n", item->dev->name);
> +                       memcpy(ptr, item->buf, item->size);
> +                       ptr += item->size;

Should ctx->current be updated?

> +               }
> +       }
> +
> +       if (ptr != end) {
> +               log_warning("*** Missing bytes: ptr=%p, end=%p\n", ptr, end);
> +               return -ENXIO;
> +       }
> +
> +       return 0;
> +}
> +
>  acpi_method acpi_get_method(struct udevice *dev, enum method_t method)
>  {
>         struct acpi_ops *aops;
> @@ -163,11 +233,16 @@ int acpi_recurse_method(struct acpi_ctx *ctx, struct 
> udevice *parent,
>
>  int acpi_fill_ssdt(struct acpi_ctx *ctx)
>  {
> +       void *start = ctx->current;
>         int ret;
>
>         log_debug("Writing SSDT tables\n");
> +       item_count = 0;
>         ret = acpi_recurse_method(ctx, dm_root(), METHOD_FILL_SSDT, 
> TYPE_SSDT);
>         log_debug("Writing SSDT finished, err=%d\n", ret);
> +       ret = sort_acpi_item_type(ctx, start, TYPE_SSDT);
> +       if (ret)
> +               return log_msg_ret("build", ret);
>
>         return ret;
>  }
> diff --git a/test/dm/acpi.c b/test/dm/acpi.c
> index d46d1fbe66..4e1d401e0d 100644
> --- a/test/dm/acpi.c
> +++ b/test/dm/acpi.c
> @@ -425,13 +425,16 @@ static int dm_test_acpi_fill_ssdt(struct 
> unit_test_state *uts)
>         buf[4] = 'z';   /* sentinel */
>         ut_assertok(acpi_fill_ssdt(&ctx));
>
> -       /* These values come from acpi-test's acpi-ssdt-test-data property */
> -       ut_asserteq('a', buf[0]);
> -       ut_asserteq('b', buf[1]);
> +       /*
> +        * These values come from acpi-test2's acpi-ssdt-test-data property.
> +        * This device comes first because of u-boot,acpi-ssdt-order
> +        */
> +       ut_asserteq('c', buf[0]);
> +       ut_asserteq('d', buf[1]);
>
> -       /* These values come from acpi-test2's acpi-ssdt-test-data property */
> -       ut_asserteq('c', buf[2]);
> -       ut_asserteq('d', buf[3]);
> +       /* These values come from acpi-test's acpi-ssdt-test-data property */
> +       ut_asserteq('a', buf[2]);
> +       ut_asserteq('b', buf[3]);
>
>         ut_asserteq('z', buf[4]);
>

Regards,
Bin

Reply via email to