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

Simon Glass sjg at chromium.org
Sun Jul 16 01:40:28 CEST 2023


Hi Bin,

On Thu, 13 Jul 2023 at 04:49, Bin Meng <bmeng.cn at gmail.com> wrote:
>
> 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?

When U-Boot puts the tables in a bloblist they appear at the top of
memory, since that is where the bloblist is. So this doesn't have
anything to do with seabios.

>
> > +                       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?

Yes, or at least not at address 1000, etc. It seems to put it up near
2GB. I'll add a comnent.


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


More information about the U-Boot mailing list