]> Git Repo - u-boot.git/blame - arch/x86/lib/tables.c
Restore patch series "arm: dts: am62-beagleplay: Fix Beagleplay Ethernet"
[u-boot.git] / arch / x86 / lib / tables.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
5e2400e8
BM
2/*
3 * Copyright (C) 2015, Bin Meng <[email protected]>
5e2400e8
BM
4 */
5
8856d613 6#define LOG_CATEGORY LOGC_ACPI
c193d9bd 7
d2cb7a22 8#include <bloblist.h>
b336a2b8 9#include <log.h>
336d4615 10#include <malloc.h>
4b6dddc2 11#include <smbios.h>
776cc201 12#include <acpi/acpi_table.h>
401d1c4f 13#include <asm/global_data.h>
6388e357 14#include <asm/sfi.h>
07545d86 15#include <asm/mpspec.h>
5e2400e8 16#include <asm/tables.h>
3cf23719 17#include <asm/coreboot_tables.h>
1a2e02f9 18#include <linux/log2.h>
5e2400e8 19
d2cb7a22
SG
20DECLARE_GLOBAL_DATA_PTR;
21
ef4d0a52
BM
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 */
42fd8c19 28typedef ulong (*table_write)(ulong addr);
ef4d0a52 29
b336a2b8
SG
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
d2cb7a22
SG
35 * @tag: Bloblist tag if using CONFIG_BLOBLIST_TABLES
36 * @size: Maximum table size
37 * @align: Table alignment in bytes
b336a2b8
SG
38 */
39struct table_info {
40 const char *name;
41 table_write write;
d2cb7a22
SG
42 enum bloblist_tag_t tag;
43 int size;
44 int align;
b336a2b8
SG
45};
46
47static struct table_info table_list[] = {
ef4d0a52 48#ifdef CONFIG_GENERATE_PIRQ_TABLE
b336a2b8 49 { "pirq", write_pirq_routing_table },
ef4d0a52
BM
50#endif
51#ifdef CONFIG_GENERATE_SFI_TABLE
b336a2b8 52 { "sfi", write_sfi_table, },
ef4d0a52
BM
53#endif
54#ifdef CONFIG_GENERATE_MP_TABLE
b336a2b8 55 { "mp", write_mp_table, },
ef4d0a52 56#endif
6a324897
SG
57 /*
58 * tables which can go in the bloblist must be last in this list, so
59 * that the calculation of gd->table_end works properly
60 */
ef4d0a52 61#ifdef CONFIG_GENERATE_ACPI_TABLE
d2cb7a22 62 { "acpi", write_acpi_tables, BLOBLISTT_ACPI_TABLES, 0x10000, 0x1000},
ef4d0a52 63#endif
1c5aab80 64#if defined(CONFIG_GENERATE_SMBIOS_TABLE) && !defined(CONFIG_QFW_SMBIOS)
d2cb7a22 65 { "smbios", write_smbios_table, BLOBLISTT_SMBIOS_TABLES, 0x1000, 0x100},
ef4d0a52
BM
66#endif
67};
68
7f5df8d4
BM
69void table_fill_string(char *dest, const char *src, size_t n, char pad)
70{
71 int start, len;
72 int i;
73
74 strncpy(dest, src, n);
75
76 /* Fill the remaining bytes with pad */
77 len = strlen(src);
78 start = len < n ? len : n;
79 for (i = start; i < n; i++)
80 dest[i] = pad;
81}
82
38e498c3 83int write_tables(void)
5e2400e8 84{
ff94c219 85 u32 high_table, table_size;
b336a2b8 86 struct memory_area cfg_tables[ARRAY_SIZE(table_list) + 1];
6a324897 87 bool use_high = false;
8856d613 88 u32 rom_addr;
ef4d0a52 89 int i;
5e2400e8 90
6a324897
SG
91 gd->arch.table_start = ROM_TABLE_ADDR;
92 rom_addr = gd->arch.table_start;
d2cb7a22 93
8856d613 94 debug("Writing tables to %x:\n", rom_addr);
b336a2b8
SG
95 for (i = 0; i < ARRAY_SIZE(table_list); i++) {
96 const struct table_info *table = &table_list[i];
d2cb7a22 97 int size = table->size ? : CONFIG_ROM_TABLE_SIZE;
8856d613 98 u32 rom_table_end;
b336a2b8 99
52c62acc
HS
100 rom_addr = ALIGN(rom_addr, 16);
101
50834884
SG
102 if (!strcmp("smbios", table->name))
103 gd->arch.smbios_start = rom_addr;
104
d2cb7a22 105 if (IS_ENABLED(CONFIG_BLOBLIST_TABLES) && table->tag) {
6a324897
SG
106 if (!gd->arch.table_end)
107 gd->arch.table_end = rom_addr;
8856d613 108 rom_addr = (ulong)bloblist_add(table->tag, size,
1a2e02f9 109 ilog2(table->align));
8856d613 110 if (!rom_addr)
d2cb7a22 111 return log_msg_ret("bloblist", -ENOBUFS);
6a324897
SG
112
113 /* the bloblist is always in high memory */
114 use_high = true;
115 if (!gd->arch.table_start_high)
116 gd->arch.table_start_high = rom_addr;
d2cb7a22 117 }
8856d613 118 rom_table_end = table->write(rom_addr);
c193d9bd
HS
119 if (!rom_table_end) {
120 log_err("Can't create configuration table %d\n", i);
121 return -EINTR;
122 }
ff94c219 123
f36e4c7d 124 if (IS_ENABLED(CONFIG_SEABIOS)) {
8856d613 125 table_size = rom_table_end - rom_addr;
f36e4c7d
SG
126 high_table = (u32)(ulong)high_table_malloc(table_size);
127 if (high_table) {
c193d9bd
HS
128 if (!table->write(high_table)) {
129 log_err("Can't create configuration table %d\n",
130 i);
131 return -EINTR;
132 }
f36e4c7d
SG
133
134 cfg_tables[i].start = high_table;
135 cfg_tables[i].size = table_size;
136 } else {
137 printf("%d: no memory for configuration tables\n",
138 i);
139 return -ENOSPC;
140 }
ff94c219
BM
141 }
142
b336a2b8 143 debug("- wrote '%s' to %x, end %x\n", table->name,
8856d613
SG
144 rom_addr, rom_table_end);
145 if (rom_table_end - rom_addr > size) {
d2cb7a22 146 log_err("Out of space for configuration tables: need %x, have %x\n",
8856d613 147 rom_table_end - rom_addr, size);
d2cb7a22
SG
148 return log_msg_ret("bloblist", -ENOSPC);
149 }
8856d613 150 rom_addr = rom_table_end;
ef4d0a52 151 }
3cf23719 152
6a324897
SG
153 if (use_high)
154 gd->arch.table_end_high = rom_addr;
155 else
156 gd->arch.table_end = rom_addr;
157
f36e4c7d
SG
158 if (IS_ENABLED(CONFIG_SEABIOS)) {
159 /* make sure the last item is zero */
160 cfg_tables[i].size = 0;
161 write_coreboot_table(CB_TABLE_ADDR, cfg_tables);
162 }
163
d2cb7a22
SG
164 if (IS_ENABLED(CONFIG_BLOBLIST_TABLES)) {
165 void *ptr = (void *)CONFIG_ROM_TABLE_ADDR;
166
167 /* Write an RSDP pointing to the tables */
168 if (IS_ENABLED(CONFIG_GENERATE_ACPI_TABLE)) {
169 struct acpi_ctx *ctx = gd_acpi_ctx();
170
171 acpi_write_rsdp(ptr, ctx->rsdt, ctx->xsdt);
172 ptr += ALIGN(sizeof(struct acpi_rsdp), 16);
173 }
174 if (IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE)) {
175 void *smbios;
176
177 smbios = bloblist_find(BLOBLISTT_SMBIOS_TABLES, 0);
178 if (!smbios)
179 return log_msg_ret("smbios", -ENOENT);
180 memcpy(ptr, smbios, sizeof(struct smbios_entry));
181 }
182 }
183
b336a2b8 184 debug("- done writing tables\n");
38e498c3
SG
185
186 return 0;
5e2400e8 187}
This page took 0.210699 seconds and 4 git commands to generate.