uboot/arch/x86/lib/tables.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
   4 */
   5
   6#define LOG_CATEGORY LOGC_BOARD
   7
   8#include <common.h>
   9#include <bloblist.h>
  10#include <log.h>
  11#include <malloc.h>
  12#include <smbios.h>
  13#include <acpi/acpi_table.h>
  14#include <asm/global_data.h>
  15#include <asm/sfi.h>
  16#include <asm/mpspec.h>
  17#include <asm/tables.h>
  18#include <asm/coreboot_tables.h>
  19
  20DECLARE_GLOBAL_DATA_PTR;
  21
  22/**
  23 * Function prototype to write a specific configuration table
  24 *
  25 * @addr:       start address to write the table
  26 * @return:     end address of the table
  27 */
  28typedef ulong (*table_write)(ulong addr);
  29
  30/**
  31 * struct table_info - Information about each table to write
  32 *
  33 * @name: Name of table (for debugging)
  34 * @write: Function to call to write this table
  35 * @tag: Bloblist tag if using CONFIG_BLOBLIST_TABLES
  36 * @size: Maximum table size
  37 * @align: Table alignment in bytes
  38 */
  39struct table_info {
  40        const char *name;
  41        table_write write;
  42        enum bloblist_tag_t tag;
  43        int size;
  44        int align;
  45};
  46
  47static struct table_info table_list[] = {
  48#ifdef CONFIG_GENERATE_PIRQ_TABLE
  49        { "pirq", write_pirq_routing_table },
  50#endif
  51#ifdef CONFIG_GENERATE_SFI_TABLE
  52        { "sfi", write_sfi_table, },
  53#endif
  54#ifdef CONFIG_GENERATE_MP_TABLE
  55        { "mp", write_mp_table, },
  56#endif
  57#ifdef CONFIG_GENERATE_ACPI_TABLE
  58        { "acpi", write_acpi_tables, BLOBLISTT_ACPI_TABLES, 0x10000, 0x1000},
  59#endif
  60#ifdef CONFIG_GENERATE_SMBIOS_TABLE
  61        { "smbios", write_smbios_table, BLOBLISTT_SMBIOS_TABLES, 0x1000, 0x100},
  62#endif
  63};
  64
  65void table_fill_string(char *dest, const char *src, size_t n, char pad)
  66{
  67        int start, len;
  68        int i;
  69
  70        strncpy(dest, src, n);
  71
  72        /* Fill the remaining bytes with pad */
  73        len = strlen(src);
  74        start = len < n ? len : n;
  75        for (i = start; i < n; i++)
  76                dest[i] = pad;
  77}
  78
  79int write_tables(void)
  80{
  81        u32 rom_table_start;
  82        u32 rom_table_end;
  83        u32 high_table, table_size;
  84        struct memory_area cfg_tables[ARRAY_SIZE(table_list) + 1];
  85        int i;
  86
  87        rom_table_start = ROM_TABLE_ADDR;
  88
  89        debug("Writing tables to %x:\n", rom_table_start);
  90        for (i = 0; i < ARRAY_SIZE(table_list); i++) {
  91                const struct table_info *table = &table_list[i];
  92                int size = table->size ? : CONFIG_ROM_TABLE_SIZE;
  93
  94                if (IS_ENABLED(CONFIG_BLOBLIST_TABLES) && table->tag) {
  95                        rom_table_start = (ulong)bloblist_add(table->tag, size,
  96                                                              table->align);
  97                        if (!rom_table_start)
  98                                return log_msg_ret("bloblist", -ENOBUFS);
  99                }
 100                rom_table_end = table->write(rom_table_start);
 101                if (!rom_table_end) {
 102                        log_err("Can't create configuration table %d\n", i);
 103                        return -EINTR;
 104                }
 105
 106                if (IS_ENABLED(CONFIG_SEABIOS)) {
 107                        table_size = rom_table_end - rom_table_start;
 108                        high_table = (u32)(ulong)high_table_malloc(table_size);
 109                        if (high_table) {
 110                                if (!table->write(high_table)) {
 111                                        log_err("Can't create configuration table %d\n",
 112                                                i);
 113                                        return -EINTR;
 114                                }
 115
 116                                cfg_tables[i].start = high_table;
 117                                cfg_tables[i].size = table_size;
 118                        } else {
 119                                printf("%d: no memory for configuration tables\n",
 120                                       i);
 121                                return -ENOSPC;
 122                        }
 123                }
 124
 125                debug("- wrote '%s' to %x, end %x\n", table->name,
 126                      rom_table_start, rom_table_end);
 127                if (rom_table_end - rom_table_start > size) {
 128                        log_err("Out of space for configuration tables: need %x, have %x\n",
 129                                rom_table_end - rom_table_start, size);
 130                        return log_msg_ret("bloblist", -ENOSPC);
 131                }
 132                rom_table_start = rom_table_end;
 133        }
 134
 135        if (IS_ENABLED(CONFIG_SEABIOS)) {
 136                /* make sure the last item is zero */
 137                cfg_tables[i].size = 0;
 138                write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
 139        }
 140
 141        if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) {
 142                void *ptr = (void *)CONFIG_ROM_TABLE_ADDR;
 143
 144                /* Write an RSDP pointing to the tables */
 145                if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
 146                        struct acpi_ctx *ctx = gd_acpi_ctx();
 147
 148                        acpi_write_rsdp(ptr, ctx->rsdt, ctx->xsdt);
 149                        ptr += ALIGN(sizeof(struct acpi_rsdp), 16);
 150                }
 151                if (IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE)) {
 152                        void *smbios;
 153
 154                        smbios = bloblist_find(BLOBLISTT_SMBIOS_TABLES, 0);
 155                        if (!smbios)
 156                                return log_msg_ret("smbios", -ENOENT);
 157                        memcpy(ptr, smbios, sizeof(struct smbios_entry));
 158                }
 159        }
 160
 161        debug("- done writing tables\n");
 162
 163        return 0;
 164}
 165