1 /* SPDX-License-Identifier: GPL-2.0-only */
7 #include <console/console.h>
10 #include <commonlib/endian.h>
13 #include "fw_cfg_if.h"
15 #define FW_CFG_PORT_CTL 0x0510
16 #define FW_CFG_PORT_DATA 0x0511
17 #define FW_CFG_DMA_ADDR_HIGH 0x0514
18 #define FW_CFG_DMA_ADDR_LOW 0x0518
20 static int fw_cfg_detected
;
21 static uint8_t fw_ver
;
23 static void fw_cfg_dma(int control
, void *buf
, int len
);
25 static int fw_cfg_present(void)
27 static const char qsig
[] = "QEMU";
28 unsigned char sig
[FW_CFG_SIG_SIZE
];
31 if (fw_cfg_detected
== 0) {
32 fw_cfg_get(FW_CFG_SIGNATURE
, sig
, sizeof(sig
));
33 detected
= memcmp(sig
, qsig
, FW_CFG_SIG_SIZE
) == 0;
34 printk(BIOS_INFO
, "QEMU: firmware config interface %s\n",
35 detected
? "detected" : "not found");
37 fw_cfg_get(FW_CFG_ID
, &fw_ver
, sizeof(fw_ver
));
38 printk(BIOS_INFO
, "Firmware config version id: %d\n", fw_ver
);
40 fw_cfg_detected
= detected
+ 1;
42 return fw_cfg_detected
- 1;
45 static void fw_cfg_select(uint16_t entry
)
47 if (fw_ver
& FW_CFG_VERSION_DMA
)
48 fw_cfg_dma(FW_CFG_DMA_CTL_SELECT
| entry
<< 16, NULL
, 0);
50 outw(entry
, FW_CFG_PORT_CTL
);
53 static void fw_cfg_read(void *dst
, int dstlen
)
55 if (fw_ver
& FW_CFG_VERSION_DMA
)
56 fw_cfg_dma(FW_CFG_DMA_CTL_READ
, dst
, dstlen
);
58 insb(FW_CFG_PORT_DATA
, dst
, dstlen
);
61 void fw_cfg_get(uint16_t entry
, void *dst
, int dstlen
)
64 fw_cfg_read(dst
, dstlen
);
67 static int fw_cfg_find_file(FWCfgFile
*file
, const char *name
)
71 fw_cfg_select(FW_CFG_FILE_DIR
);
72 fw_cfg_read(&count
, sizeof(count
));
73 count
= be32_to_cpu(count
);
75 for (int i
= 0; i
< count
; i
++) {
76 fw_cfg_read(file
, sizeof(*file
));
77 if (strcmp(file
->name
, name
) == 0) {
78 file
->size
= be32_to_cpu(file
->size
);
79 file
->select
= be16_to_cpu(file
->select
);
80 printk(BIOS_INFO
, "QEMU: firmware config: Found '%s'\n", name
);
84 printk(BIOS_INFO
, "QEMU: firmware config: Couldn't find '%s'\n", name
);
88 int fw_cfg_check_file(FWCfgFile
*file
, const char *name
)
90 if (!fw_cfg_present())
92 return fw_cfg_find_file(file
, name
);
95 static int fw_cfg_e820_select(uint32_t *size
)
99 if (!fw_cfg_present() || fw_cfg_find_file(&file
, "etc/e820"))
101 fw_cfg_select(file
.select
);
106 static int fw_cfg_e820_read(FwCfgE820Entry
*entry
, uint32_t *size
,
109 if (*pos
+ sizeof(*entry
) > *size
)
112 fw_cfg_read(entry
, sizeof(*entry
));
113 *pos
+= sizeof(*entry
);
117 /* returns tolud on success or 0 on failure */
118 uintptr_t fw_cfg_tolud(void)
122 uint32_t size
= 0, pos
= 0;
124 if (fw_cfg_e820_select(&size
) == 0) {
125 while (!fw_cfg_e820_read(&e
, &size
, &pos
)) {
126 uint64_t limit
= e
.address
+ e
.length
;
127 if (e
.type
== 1 && limit
< 4ULL * GiB
&& limit
> top
)
131 return (uintptr_t)top
;
134 int fw_cfg_max_cpus(void)
136 unsigned short max_cpus
;
138 if (!fw_cfg_present())
141 fw_cfg_get(FW_CFG_MAX_CPUS
, &max_cpus
, sizeof(max_cpus
));
145 /* ---------------------------------------------------------------------- */
148 * Starting with release 1.7 qemu provides ACPI tables via fw_cfg.
149 * Main advantage is that new (virtual) hardware which needs acpi
150 * support JustWorks[tm] without having to patch & update the firmware
151 * (seabios, coreboot, ...) accordingly.
153 * Qemu provides a etc/table-loader file with instructions for the
155 * - A "load" instruction to fetch ACPI data from fw_cfg.
156 * - A "pointer" instruction to patch a pointer. This is needed to
157 * get table-to-table references right, it is basically a
158 * primitive dynamic linker for ACPI tables.
159 * - A "checksum" instruction to generate ACPI table checksums.
161 * If a etc/table-loader file is found we'll go try loading the acpi
162 * tables from fw_cfg, otherwise we'll fallback to the ACPI tables
166 #define BIOS_LINKER_LOADER_FILESZ 56
168 struct BiosLinkerLoaderEntry
{
172 * COMMAND_ALLOCATE - allocate a table from @alloc.file
173 * subject to @alloc.align alignment (must be power of 2)
174 * and @alloc.zone (can be HIGH or FSEG) requirements.
176 * Must appear exactly once for each file, and before
177 * this file is referenced by any other command.
180 char file
[BIOS_LINKER_LOADER_FILESZ
];
186 * COMMAND_ADD_POINTER - patch the table (originating from
187 * @dest_file) at @pointer.offset, by adding a pointer to the table
188 * originating from @src_file. 1,2,4 or 8 byte unsigned
189 * addition is used depending on @pointer.size.
192 char dest_file
[BIOS_LINKER_LOADER_FILESZ
];
193 char src_file
[BIOS_LINKER_LOADER_FILESZ
];
199 * COMMAND_ADD_CHECKSUM - calculate checksum of the range specified by
200 * @cksum_start and @cksum_length fields,
201 * and then add the value at @cksum.offset.
202 * Checksum simply sums -X for each byte X in the range
206 char file
[BIOS_LINKER_LOADER_FILESZ
];
216 typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry
;
219 BIOS_LINKER_LOADER_COMMAND_ALLOCATE
= 0x1,
220 BIOS_LINKER_LOADER_COMMAND_ADD_POINTER
= 0x2,
221 BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM
= 0x3,
225 BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH
= 0x1,
226 BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG
= 0x2,
229 unsigned long fw_cfg_acpi_tables(unsigned long start
)
232 BiosLinkerLoaderEntry
*s
;
233 unsigned long *addrs
, current
;
235 int i
, j
, src
, dst
, max
;
237 if (fw_cfg_check_file(&f
, "etc/table-loader"))
240 printk(BIOS_DEBUG
, "QEMU: found ACPI tables in fw_cfg.\n");
242 max
= f
.size
/ sizeof(*s
);
244 addrs
= malloc(max
* sizeof(*addrs
));
245 fw_cfg_get(f
.select
, s
, f
.size
);
248 for (i
= 0; i
< max
&& s
[i
].command
!= 0; i
++) {
253 switch (s
[i
].command
) {
254 case BIOS_LINKER_LOADER_COMMAND_ALLOCATE
:
255 current
= ALIGN_UP(current
, s
[i
].alloc
.align
);
256 if (fw_cfg_check_file(&f
, s
[i
].alloc
.file
))
259 printk(BIOS_DEBUG
, "QEMU: loading \"%s\" to 0x%lx (len %d)\n",
260 s
[i
].alloc
.file
, current
, f
.size
);
261 fw_cfg_get(f
.select
, (void *)current
, f
.size
);
266 case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER
:
268 for (j
= 0; j
< i
; j
++) {
269 if (s
[j
].command
!= BIOS_LINKER_LOADER_COMMAND_ALLOCATE
)
271 if (strcmp(s
[j
].alloc
.file
, s
[i
].pointer
.dest_file
) == 0)
273 if (strcmp(s
[j
].alloc
.file
, s
[i
].pointer
.src_file
) == 0)
276 if (src
== -1 || dst
== -1)
279 switch (s
[i
].pointer
.size
) {
281 ptr
= (uint8_t *)addrs
[dst
];
282 ptr
+= s
[i
].pointer
.offset
;
283 addr4
= read_le32(ptr
);
285 write_le32(ptr
, addr4
);
289 ptr
= (uint8_t *)addrs
[dst
];
290 ptr
+= s
[i
].pointer
.offset
;
291 addr8
= read_le64(ptr
);
293 write_le64(ptr
, addr8
);
298 * Should not happen. ACPI knows 1 and 2 byte ptrs
299 * too, but we are operating with 32bit offsets which
300 * would simply not fit in there ...
302 printk(BIOS_DEBUG
, "QEMU: acpi: unimplemented ptr size %d\n",
308 case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM
:
310 for (j
= 0; j
< i
; j
++) {
311 if (s
[j
].command
!= BIOS_LINKER_LOADER_COMMAND_ALLOCATE
)
313 if (strcmp(s
[j
].alloc
.file
, s
[i
].cksum
.file
) == 0)
319 ptr
= (uint8_t *)(addrs
[dst
] + s
[i
].cksum
.offset
);
320 cksum_data
= (void *)(addrs
[dst
] + s
[i
].cksum
.start
);
321 cksum
= acpi_checksum(cksum_data
, s
[i
].cksum
.length
);
322 write_le8(ptr
, cksum
);
326 printk(BIOS_DEBUG
, "QEMU: acpi: unknown script cmd 0x%x @ %p\n",
332 printk(BIOS_DEBUG
, "QEMU: loaded ACPI tables from fw_cfg.\n");
335 return ALIGN_UP(current
, 16);
338 printk(BIOS_DEBUG
, "QEMU: loading ACPI tables from fw_cfg failed.\n");
344 /* ---------------------------------------------------------------------- */
345 /* pick up smbios information from fw_cfg */
347 #if CONFIG(GENERATE_SMBIOS_TABLES)
348 static const char *type1_manufacturer
;
349 static const char *type1_product_name
;
350 static const char *type1_version
;
351 static const char *type1_serial_number
;
352 static const char *type1_family
;
353 static u8 type1_uuid
[16];
355 static void fw_cfg_smbios_init(void)
358 uint16_t i
, count
= 0;
366 fw_cfg_get(FW_CFG_SMBIOS_ENTRIES
, &count
, sizeof(count
));
367 for (i
= 0; i
< count
; i
++) {
368 fw_cfg_read(&entry
, sizeof(entry
));
369 buf
= malloc(entry
.length
- sizeof(entry
));
370 fw_cfg_read(buf
, entry
.length
- sizeof(entry
));
371 if (entry
.headertype
== SMBIOS_FIELD_ENTRY
&&
372 entry
.tabletype
== 1) {
373 switch (entry
.fieldoffset
) {
374 case offsetof(struct smbios_type1
, manufacturer
):
375 type1_manufacturer
= strdup(buf
);
377 case offsetof(struct smbios_type1
, product_name
):
378 type1_product_name
= strdup(buf
);
380 case offsetof(struct smbios_type1
, version
):
381 type1_version
= strdup(buf
);
383 case offsetof(struct smbios_type1
, serial_number
):
384 type1_serial_number
= strdup(buf
);
386 case offsetof(struct smbios_type1
, family
):
387 type1_family
= strdup(buf
);
389 case offsetof(struct smbios_type1
, uuid
):
390 memcpy(type1_uuid
, buf
, 16);
398 static unsigned long smbios_next(unsigned long current
)
400 struct smbios_header
*header
;
404 header
= (void *)current
;
405 current
+= header
->length
;
410 return current
+ (count
? 1 : 2);
417 * Starting with version 2.1 qemu provides a full set of smbios tables
418 * for the virtual hardware emulated, except type 0 (bios information).
420 * What we are going to do here is find the type0 table, keep it, and
421 * override everything else generated by coreboot with the qemu smbios
424 * It's a bit hackish, but qemu is a special case (compared to real
425 * hardware) and this way we don't need special qemu support in the
426 * generic smbios code.
428 unsigned long fw_cfg_smbios_tables(int *handle
, unsigned long *current
)
431 struct smbios_header
*header
;
432 unsigned long start
, end
;
433 int ret
, i
, count
= 1;
436 if (fw_cfg_check_file(&f
, "etc/smbios/smbios-tables"))
439 printk(BIOS_DEBUG
, "QEMU: found smbios tables in fw_cfg (len %d).\n", f
.size
);
442 * Search backwards for "coreboot" (first string in type0 table,
443 * see src/arch/x86/boot/smbios.c), then find type0 table.
445 for (i
= 0; i
< 16384; i
++) {
446 str
= (char*)(*current
- i
);
447 if (strcmp(str
, "coreboot") == 0)
452 i
+= sizeof(struct smbios_type0
) - 2;
453 header
= (struct smbios_header
*)(*current
- i
);
454 if (header
->type
!= SMBIOS_BIOS_INFORMATION
|| header
->handle
!= 0)
456 printk(BIOS_DEBUG
, "QEMU: coreboot type0 table found at 0x%lx.\n",
458 start
= smbios_next(*current
- i
);
461 * Fetch smbios tables from qemu, go find the end marker.
462 * We'll exclude the end marker as coreboot will add one.
464 printk(BIOS_DEBUG
, "QEMU: loading smbios tables to 0x%lx\n", start
);
465 fw_cfg_get(f
.select
, (void *)start
, f
.size
);
468 header
= (struct smbios_header
*)end
;
469 if (header
->type
== SMBIOS_END_OF_TABLE
)
471 end
= smbios_next(end
);
473 } while (end
< start
+ f
.size
);
476 ret
= end
- *current
;
482 const char *smbios_mainboard_manufacturer(void)
484 fw_cfg_smbios_init();
485 return type1_manufacturer
?: CONFIG_MAINBOARD_SMBIOS_MANUFACTURER
;
488 const char *smbios_mainboard_product_name(void)
490 fw_cfg_smbios_init();
491 return type1_product_name
?: CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME
;
494 const char *smbios_mainboard_version(void)
496 fw_cfg_smbios_init();
497 return type1_version
?: CONFIG_MAINBOARD_VERSION
;
500 const char *smbios_mainboard_serial_number(void)
502 fw_cfg_smbios_init();
503 return type1_serial_number
?: CONFIG_MAINBOARD_SERIAL_NUMBER
;
506 void smbios_system_set_uuid(u8
*uuid
)
508 fw_cfg_smbios_init();
509 memcpy(uuid
, type1_uuid
, 16);
511 #endif /* CONFIG(GENERATE_SMBIOS_TABLES) */
514 * Configure DMA setup
517 static void fw_cfg_dma(int control
, void *buf
, int len
)
519 volatile FwCfgDmaAccess dma
;
520 uintptr_t dma_desc_addr
;
521 uint32_t dma_desc_addr_hi
, dma_desc_addr_lo
;
523 dma
.control
= be32_to_cpu(control
);
524 dma
.length
= be32_to_cpu(len
);
525 dma
.address
= be64_to_cpu((uintptr_t)buf
);
527 dma_desc_addr
= (uintptr_t)&dma
;
528 dma_desc_addr_lo
= (uint32_t)(dma_desc_addr
& 0xFFFFFFFFU
);
529 dma_desc_addr_hi
= sizeof(uintptr_t) > sizeof(uint32_t)
530 ? (uint32_t)(dma_desc_addr
>> 32) : 0;
532 // Skip writing high half if unnecessary.
533 if (dma_desc_addr_hi
)
534 outl(be32_to_cpu(dma_desc_addr_hi
), FW_CFG_DMA_ADDR_HIGH
);
535 outl(be32_to_cpu(dma_desc_addr_lo
), FW_CFG_DMA_ADDR_LOW
);
537 while (be32_to_cpu(dma
.control
) & ~FW_CFG_DMA_CTL_ERROR
)