[PATCH v4 35/45] x86: Record the start and end of the tables

Bin Meng bmeng.cn at gmail.com
Thu Jul 13 12:49:38 CEST 2023


Hi Simon,

On Mon, Jun 19, 2023 at 8:02 PM Simon Glass <sjg at chromium.org> wrote:
>
> The ACPI tables are special in that they are passed to EFI as a separate
> piece, independent of other tables.
>
> Also they can be spread over two areas of memory, e.g. with QEMU we end
> up with tables kept in high memory as well.
>
> Add new global_data fields to hold this information and update the bdinfo
> command to show the table areas.
>
> Move the rom_table_end variable into the loop that uses it.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> (no changes since v3)
>
> Changes in v3:
> - Adjust the code to handle qemu writing a pointer to tables in memory
>
> Changes in v2:
> - Handle the case where the tables are in the bloblist
>
>  arch/sandbox/include/asm/global_data.h |  4 ++++
>  arch/x86/include/asm/global_data.h     |  4 ++++
>  arch/x86/lib/bdinfo.c                  |  4 ++++
>  arch/x86/lib/tables.c                  | 18 +++++++++++++++++-
>  drivers/misc/qfw.c                     |  8 ++++++++
>  5 files changed, 37 insertions(+), 1 deletion(-)
>
> diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h
> index f4ce72d56602..f0ab3ba5c146 100644
> --- a/arch/sandbox/include/asm/global_data.h
> +++ b/arch/sandbox/include/asm/global_data.h
> @@ -13,6 +13,10 @@
>  struct arch_global_data {
>         uint8_t         *ram_buf;       /* emulated RAM buffer */
>         void            *text_base;     /* pointer to base of text region */
> +       ulong table_start;              /* Start address of x86 tables */
> +       ulong table_end;                /* End address of x86 tables */
> +       ulong table_start_high;         /* Start address of high x86 tables */
> +       ulong table_end_high;           /* End address of high x86 tables */
>  };
>
>  #include <asm-generic/global_data.h>
> diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
> index 22d103df4ee8..ea58259ad774 100644
> --- a/arch/x86/include/asm/global_data.h
> +++ b/arch/x86/include/asm/global_data.h
> @@ -123,6 +123,10 @@ struct arch_global_data {
>  #endif
>         void *itss_priv;                /* Private ITSS data pointer */
>         ulong coreboot_table;           /* Address of coreboot table */
> +       ulong table_start;              /* Start address of x86 tables */
> +       ulong table_end;                /* End address of x86 tables */
> +       ulong table_start_high;         /* Start address of high x86 tables */
> +       ulong table_end_high;           /* End address of high x86 tables */
>  };
>
>  #endif
> diff --git a/arch/x86/lib/bdinfo.c b/arch/x86/lib/bdinfo.c
> index 0970efa4726f..9504e7fc293e 100644
> --- a/arch/x86/lib/bdinfo.c
> +++ b/arch/x86/lib/bdinfo.c
> @@ -23,6 +23,10 @@ void arch_print_bdinfo(void)
>         bdinfo_print_str(" name", cpu_vendor_name(gd->arch.x86_vendor));
>         bdinfo_print_num_l("model", gd->arch.x86_model);
>         bdinfo_print_num_l("phys_addr", cpu_phys_address_size());
> +       bdinfo_print_num_l("table start", gd->arch.table_start);
> +       bdinfo_print_num_l("table end", gd->arch.table_end);
> +       bdinfo_print_num_l(" high start", gd->arch.table_start_high);
> +       bdinfo_print_num_l(" high end", gd->arch.table_end_high);
>
>         if (IS_ENABLED(CONFIG_EFI_STUB))
>                 efi_show_bdinfo();
> diff --git a/arch/x86/lib/tables.c b/arch/x86/lib/tables.c
> index 132c02ee80f4..d95fdb205000 100644
> --- a/arch/x86/lib/tables.c
> +++ b/arch/x86/lib/tables.c
> @@ -54,6 +54,10 @@ static struct table_info table_list[] = {
>  #ifdef CONFIG_GENERATE_MP_TABLE
>         { "mp", write_mp_table, },
>  #endif
> +       /*
> +        * tables which can go in the bloblist must be last in this list, so
> +        * that the calculation of gd->table_end works properly
> +        */
>  #ifdef CONFIG_GENERATE_ACPI_TABLE
>         { "acpi", write_acpi_tables, BLOBLISTT_ACPI_TABLES, 0x10000, 0x1000},
>  #endif
> @@ -80,10 +84,12 @@ int write_tables(void)
>  {
>         u32 high_table, table_size;
>         struct memory_area cfg_tables[ARRAY_SIZE(table_list) + 1];
> +       bool use_high = false;
>         u32 rom_addr;
>         int i;
>
> -       rom_addr = ROM_TABLE_ADDR;
> +       gd->arch.table_start = ROM_TABLE_ADDR;
> +       rom_addr = gd->arch.table_start;
>
>         debug("Writing tables to %x:\n", rom_addr);
>         for (i = 0; i < ARRAY_SIZE(table_list); i++) {
> @@ -92,10 +98,15 @@ int write_tables(void)
>                 u32 rom_table_end;
>
>                 if (IS_ENABLED(CONFIG_BLOBLIST_TABLES) && table->tag) {
> +                       if (!gd->arch.table_end)
> +                               gd->arch.table_end = rom_addr;
>                         rom_addr = (ulong)bloblist_add(table->tag, size,
>                                                               table->align);
>                         if (!rom_addr)
>                                 return log_msg_ret("bloblist", -ENOBUFS);
> +                       use_high = true;

This should be put in the CONFIG_SEABIOS branch, no?

> +                       if (!gd->arch.table_start_high)
> +                               gd->arch.table_start_high = rom_addr;
>                 }
>                 rom_table_end = table->write(rom_addr);
>                 if (!rom_table_end) {
> @@ -132,6 +143,11 @@ int write_tables(void)
>                 rom_addr = rom_table_end;
>         }
>
> +       if (use_high)
> +               gd->arch.table_end_high = rom_addr;
> +       else
> +               gd->arch.table_end = rom_addr;
> +
>         if (IS_ENABLED(CONFIG_SEABIOS)) {
>                 /* make sure the last item is zero */
>                 cfg_tables[i].size = 0;
> diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
> index 0a93feeb4b2e..c0da4bd7359e 100644
> --- a/drivers/misc/qfw.c
> +++ b/drivers/misc/qfw.c
> @@ -65,6 +65,11 @@ static int bios_linker_allocate(struct udevice *dev,
>                         printf("error: allocating resource\n");
>                         return -ENOMEM;
>                 }
> +               if (aligned_addr < gd->arch.table_start_high)
> +                       gd->arch.table_start_high = aligned_addr;
> +               if (aligned_addr + size > gd->arch.table_end_high)
> +                       gd->arch.table_end_high = aligned_addr + size;
> +
>         } else if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG) {
>                 aligned_addr = ALIGN(*addr, align);
>         } else {
> @@ -189,6 +194,9 @@ ulong write_acpi_tables(ulong addr)
>                 return addr;
>         }
>
> +       gd->arch.table_start_high = (ulong)table_loader;
> +       gd->arch.table_end_high = (ulong)table_loader;

Is QFW always putting tables at high addresses?

> +
>         qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size, table_loader);
>
>         for (i = 0; i < (size / sizeof(*entry)); i++) {

Regards,
Bin


More information about the U-Boot mailing list