switch to SMBIOS3 tables

allow devicetree from bloblist
 ACPI support for ARM and RISC-V
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmWbPygRHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIrebFRQf+MS1t+wtPFz9Y8i7zBrEV1+fpPOp8XhJ5
 m7uCkCDYO1oYShI1ht6X1nzvprElk/J9ZWTUg2IXOFzSaaBiPrylcc5bDjkd2F7A
 FxqXn2oqKPIXYoZsJgVS2ua5m5pQbZk9ahX5NWzQV8xLMNjgK6BvCUX3zQsLtS1C
 jo3ly+G+FlnFZ187qqxzIQiVkRX6p/U+JLERsgfy9q0Fic5drBydQ3F8UjMdORq2
 NxxxjOl76vC+9O2A+XXC2c/1EiXR/DK2Mtz+lxA/d5/ZDrepp1bnJUjdV5qD4LdX
 +ZuwJBdctrlK0piOIJuAR7YjpNfxeUJl6L9l/3Hg2X3P8U84V0zqiA==
 =AD87
 -----END PGP SIGNATURE-----

Merge tag 'dm-next-7jan23' of https://source.denx.de/u-boot/custodians/u-boot-dm into next

switch to SMBIOS3 tables
allow devicetree from bloblist
ACPI support for ARM and RISC-V
This commit is contained in:
Tom Rini 2024-01-08 09:11:53 -05:00
commit f28a77589e
35 changed files with 556 additions and 372 deletions

View file

@ -53,6 +53,7 @@ Maintainers List (try to look for most precise areas first)
ACPI:
M: Simon Glass <sjg@chromium.org>
S: Maintained
F: board/emulation/configs/acpi.config
F: cmd/acpi.c
F: lib/acpi/

View file

@ -108,6 +108,7 @@ config PPC
config RISCV
bool "RISC-V architecture"
select CREATE_ARCH_SYMLINK
select SUPPORT_ACPI
select SUPPORT_OF_CONTROL
select OF_CONTROL
select DM

View file

@ -18,7 +18,12 @@ struct arch_global_data {
#if defined(CONFIG_FSL_ESDHC) || defined(CONFIG_FSL_ESDHC_IMX)
u32 sdhc_clk;
#endif
#if CONFIG_IS_ENABLED(ACPI)
ulong table_start; /* Start address of ACPI tables */
ulong table_end; /* End address of ACPI tables */
ulong table_start_high; /* Start address of high ACPI tables */
ulong table_end_high; /* End address of high ACPI tables */
#endif
#if defined(CONFIG_FSL_ESDHC)
u32 sdhc_per_clk;
#endif

View file

@ -33,6 +33,12 @@ struct arch_global_data {
ulong available_harts;
#endif
#endif
#if CONFIG_IS_ENABLED(ACPI)
ulong table_start; /* Start address of ACPI tables */
ulong table_end; /* End address of ACPI tables */
ulong table_start_high; /* Start address of high ACPI tables */
ulong table_end_high; /* End address of high ACPI tables */
#endif
#ifdef CONFIG_SMBIOS
ulong smbios_start; /* Start address of SMBIOS table */
#endif

View file

@ -231,5 +231,21 @@ static inline void unmap_sysmem(const void *vaddr)
unmap_physmem(vaddr, MAP_WRBACK);
}
/**
* nomap_sysmem() - pass through an address unchanged
*
* This is used to indicate an address which should NOT be mapped, e.g. in
* SMBIOS tables. Using this function instead of a case shows that the sandbox
* conversion has been done
*/
static inline void *nomap_sysmem(phys_addr_t paddr, unsigned long len)
{
return (void *)(uintptr_t)paddr;
}
static inline phys_addr_t nomap_to_sysmem(const void *ptr)
{
return (phys_addr_t)(uintptr_t)ptr;
}
#endif

View file

@ -7,6 +7,7 @@
#include <cpu.h>
#include <dm.h>
#include <log.h>
#include <mapmem.h>
#include <acpi/acpi_s3.h>
#include <acpi/acpi_table.h>
#include <asm/io.h>
@ -31,8 +32,6 @@ static int baytrail_write_fadt(struct acpi_ctx *ctx,
header->length = sizeof(struct acpi_fadt);
header->revision = 4;
fadt->firmware_ctrl = (u32)ctx->facs;
fadt->dsdt = (u32)ctx->dsdt;
fadt->preferred_pm_profile = ACPI_PM_MOBILE;
fadt->sci_int = 9;
fadt->smi_cmd = 0;
@ -79,10 +78,8 @@ static int baytrail_write_fadt(struct acpi_ctx *ctx,
fadt->reset_reg.addrh = 0;
fadt->reset_value = SYS_RST | RST_CPU | FULL_RST;
fadt->x_firmware_ctl_l = (u32)ctx->facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (u32)ctx->dsdt;
fadt->x_dsdt_h = 0;
fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs);
fadt->x_dsdt = map_to_sysmem(ctx->dsdt);
fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;

View file

@ -4,6 +4,7 @@
*/
#include <common.h>
#include <mapmem.h>
#include <acpi/acpi_table.h>
#include <asm/processor.h>
#include <asm/tables.h>
@ -26,8 +27,6 @@ static int quark_write_fadt(struct acpi_ctx *ctx,
header->length = sizeof(struct acpi_fadt);
header->revision = 4;
fadt->firmware_ctrl = (u32)ctx->facs;
fadt->dsdt = (u32)ctx->dsdt;
fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED;
fadt->sci_int = 9;
fadt->smi_cmd = 0;
@ -74,10 +73,8 @@ static int quark_write_fadt(struct acpi_ctx *ctx,
fadt->reset_reg.addrh = 0;
fadt->reset_value = SYS_RST | RST_CPU | FULL_RST;
fadt->x_firmware_ctl_l = (u32)ctx->facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (u32)ctx->dsdt;
fadt->x_dsdt_h = 0;
fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs);
fadt->x_dsdt = map_to_sysmem(ctx->dsdt);
fadt->x_pm1a_evt_blk.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;

View file

@ -8,6 +8,7 @@
#include <common.h>
#include <cpu.h>
#include <dm.h>
#include <mapmem.h>
#include <acpi/acpi_table.h>
#include <asm/ioapic.h>
#include <asm/mpspec.h>
@ -31,8 +32,6 @@ static int tangier_write_fadt(struct acpi_ctx *ctx,
header->length = sizeof(struct acpi_fadt);
header->revision = 6;
fadt->firmware_ctrl = (u32)ctx->facs;
fadt->dsdt = (u32)ctx->dsdt;
fadt->preferred_pm_profile = ACPI_PM_UNSPECIFIED;
fadt->iapc_boot_arch = ACPI_FADT_VGA_NOT_PRESENT |
@ -45,10 +44,8 @@ static int tangier_write_fadt(struct acpi_ctx *ctx,
fadt->minor_revision = 2;
fadt->x_firmware_ctl_l = (u32)ctx->facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (u32)ctx->dsdt;
fadt->x_dsdt_h = 0;
fadt->x_firmware_ctrl = map_to_sysmem(ctx->facs);
fadt->x_dsdt = map_to_sysmem(ctx->dsdt);
header->checksum = table_compute_checksum(fadt, header->length);

View file

@ -197,7 +197,7 @@ int acpi_write_tcpa(struct acpi_ctx *ctx, const struct acpi_writer *entry)
tcpa->platform_class = 0;
tcpa->laml = size;
tcpa->lasa = map_to_sysmem(log);
tcpa->lasa = nomap_to_sysmem(log);
/* (Re)calculate length and checksum */
current = (u32)tcpa + sizeof(struct acpi_tcpa);
@ -268,7 +268,7 @@ static int acpi_write_tpm2(struct acpi_ctx *ctx,
/* Fill the log area size and start address fields. */
tpm2->laml = tpm2_log_len;
tpm2->lasa = map_to_sysmem(lasa);
tpm2->lasa = nomap_to_sysmem(lasa);
/* Calculate checksum. */
header->checksum = table_compute_checksum(tpm2, header->length);
@ -430,7 +430,7 @@ int acpi_write_gnvs(struct acpi_ctx *ctx, const struct acpi_writer *entry)
u32 *gnvs = (u32 *)((u32)ctx->dsdt + i);
if (*gnvs == ACPI_GNVS_ADDR) {
*gnvs = map_to_sysmem(ctx->current);
*gnvs = nomap_to_sysmem(ctx->current);
log_debug("Fix up global NVS in DSDT to %#08x\n",
*gnvs);
break;
@ -572,13 +572,8 @@ void acpi_fadt_common(struct acpi_fadt *fadt, struct acpi_facs *facs,
memcpy(header->aslc_id, ASLC_ID, 4);
header->aslc_revision = 1;
fadt->firmware_ctrl = (unsigned long)facs;
fadt->dsdt = (unsigned long)dsdt;
fadt->x_firmware_ctl_l = (unsigned long)facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (unsigned long)dsdt;
fadt->x_dsdt_h = 0;
fadt->x_firmware_ctrl = map_to_sysmem(facs);
fadt->x_dsdt = map_to_sysmem(dsdt);
fadt->preferred_pm_profile = ACPI_PM_MOBILE;

View file

@ -0,0 +1,3 @@
CONFIG_CMD_QFW=y
CONFIG_ACPI=y
CONFIG_GENERATE_ACPI_TABLE=y

View file

@ -5,6 +5,7 @@ config TEXT_BASE
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
select QFW if ACPI
select QFW_MMIO if CMD_QFW
imply VIRTIO_MMIO
imply VIRTIO_PCI

View file

@ -33,6 +33,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
select GENERIC_RISCV
select SUPPORT_SPL
select QFW if ACPI
select QFW_MMIO if QFW
imply AHCI
imply SMP
imply BOARD_LATE_INIT

View file

@ -6,6 +6,7 @@
#include <common.h>
#include <command.h>
#include <display_options.h>
#include <log.h>
#include <mapmem.h>
#include <acpi/acpi_table.h>
#include <asm/acpi_table.h>
@ -45,7 +46,7 @@ static int dump_table_name(const char *sig)
if (!hdr)
return -ENOENT;
printf("%.*s @ %16lx\n", ACPI_NAME_LEN, hdr->signature,
(ulong)map_to_sysmem(hdr));
(ulong)nomap_to_sysmem(hdr));
print_buffer(0, hdr, 1, hdr->length, 0);
return 0;
@ -53,10 +54,17 @@ static int dump_table_name(const char *sig)
static void list_fadt(struct acpi_fadt *fadt)
{
if (fadt->dsdt)
dump_hdr(map_sysmem(fadt->dsdt, 0));
if (fadt->firmware_ctrl)
dump_hdr(map_sysmem(fadt->firmware_ctrl, 0));
if (fadt->header.revision >= 3 && fadt->x_dsdt)
dump_hdr(nomap_sysmem(fadt->x_dsdt, 0));
else if (fadt->dsdt)
dump_hdr(nomap_sysmem(fadt->dsdt, 0));
if (!IS_ENABLED(CONFIG_X86) &&
!(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI))
log_err("FADT not ACPI-hardware-reduced-compliant\n");
if (fadt->header.revision >= 3 && fadt->x_firmware_ctrl)
dump_hdr(nomap_sysmem(fadt->x_firmware_ctrl, 0));
else if (fadt->firmware_ctrl)
dump_hdr(nomap_sysmem(fadt->firmware_ctrl, 0));
}
static void list_rsdt(struct acpi_rsdp *rsdp)
@ -66,11 +74,11 @@ static void list_rsdt(struct acpi_rsdp *rsdp)
struct acpi_xsdt *xsdt;
if (rsdp->rsdt_address) {
rsdt = map_sysmem(rsdp->rsdt_address, 0);
rsdt = nomap_sysmem(rsdp->rsdt_address, 0);
dump_hdr(&rsdt->header);
}
if (rsdp->xsdt_address) {
xsdt = map_sysmem(rsdp->xsdt_address, 0);
xsdt = nomap_sysmem(rsdp->xsdt_address, 0);
dump_hdr(&xsdt->header);
len = xsdt->header.length - sizeof(xsdt->header);
count = len / sizeof(u64);
@ -91,7 +99,7 @@ static void list_rsdt(struct acpi_rsdp *rsdp)
entry = rsdt->entry[i];
if (!entry)
break;
hdr = map_sysmem(entry, 0);
hdr = nomap_sysmem(entry, 0);
dump_hdr(hdr);
if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN))
list_fadt((struct acpi_fadt *)hdr);

View file

@ -0,0 +1,23 @@
.. SPDX-License-Identifier: GPL-2.0+
ACPI on QEMU
============
QEMU can provide ACPI tables on ARM, RISC-V (since QEMU v8.0.0), and x86.
The following U-Boot settings are needed for ACPI support::
CONFIG_CMD_QFW=y
CONFIG_ACPI=y
CONFIG_GENERATE_ACPI_TABLE=y
On x86 these settings are already included in the defconfig files. ARM and
RISC-V default to use device-trees.
Instead of updating the configuration manually you can add the configuration
fragment `acpi.config` to the make command for initializing the configuration.
E.g.
.. code-block:: bash
make qemu-riscv64_smode_defconfig acpi.config

View file

@ -6,6 +6,7 @@ Emulation
.. toctree::
:maxdepth: 1
acpi
blkdev
../../usage/semihosting
qemu-arm

View file

@ -108,6 +108,9 @@ If CONFIG_OF_BOARD is defined, a board-specific routine will provide the
devicetree at runtime, for example if an earlier bootloader stage creates
it and passes it to U-Boot.
If CONFIG_BLOBLIST is defined, the devicetree may come from a bloblist passed
from a previous stage, if present.
If CONFIG_SANDBOX is defined, then it will be read from a file on
startup. Use the -d flag to U-Boot to specify the file to read, -D for the
default and -T for the test devicetree, used to run sandbox unit tests.

View file

@ -540,6 +540,13 @@ config QFW
Hidden option to enable QEMU fw_cfg interface and uclass. This will
be selected by either CONFIG_CMD_QFW or CONFIG_GENERATE_ACPI_TABLE.
config QFW_ACPI
bool
default y
depends on QFW && GENERATE_ACPI_TABLE && !SANDBOX
help
Hidden option to read ACPI tables from QEMU.
config QFW_PIO
bool
depends on QFW

View file

@ -63,6 +63,7 @@ obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o
ifdef CONFIG_QFW
obj-y += qfw.o
obj-$(CONFIG_QFW_ACPI) += qfw_acpi.o
obj-$(CONFIG_QFW_PIO) += qfw_pio.o
obj-$(CONFIG_QFW_MMIO) += qfw_mmio.o
obj-$(CONFIG_SANDBOX) += qfw_sandbox.o

View file

@ -21,246 +21,6 @@
#include <tables_csum.h>
#include <asm/acpi_table.h>
#if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_SANDBOX)
/*
* This function allocates memory for ACPI tables
*
* @entry : BIOS linker command entry which tells where to allocate memory
* (either high memory or low memory)
* @addr : The address that should be used for low memory allcation. If the
* memory allocation request is 'ZONE_HIGH' then this parameter will
* be ignored.
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_allocate(struct udevice *dev,
struct bios_linker_entry *entry, ulong *addr)
{
uint32_t size, align;
struct fw_file *file;
unsigned long aligned_addr;
align = le32_to_cpu(entry->alloc.align);
/* align must be power of 2 */
if (align & (align - 1)) {
printf("error: wrong alignment %u\n", align);
return -EINVAL;
}
file = qfw_find_file(dev, entry->alloc.file);
if (!file) {
printf("error: can't find file %s\n", entry->alloc.file);
return -ENOENT;
}
size = be32_to_cpu(file->cfg.size);
/*
* ZONE_HIGH means we need to allocate from high memory, since
* malloc space is already at the end of RAM, so we directly use it.
* If allocation zone is ZONE_FSEG, then we use the 'addr' passed
* in which is low memory
*/
if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH) {
aligned_addr = (unsigned long)memalign(align, size);
if (!aligned_addr) {
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 {
printf("error: invalid allocation zone\n");
return -EINVAL;
}
debug("bios_linker_allocate: allocate file %s, size %u, zone %d, align %u, addr 0x%lx\n",
file->cfg.name, size, entry->alloc.zone, align, aligned_addr);
qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size,
(void *)aligned_addr);
file->addr = aligned_addr;
/* adjust address for low memory allocation */
if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG)
*addr = (aligned_addr + size);
return 0;
}
/*
* This function patches ACPI tables previously loaded
* by bios_linker_allocate()
*
* @entry : BIOS linker command entry which tells how to patch
* ACPI tables
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_add_pointer(struct udevice *dev,
struct bios_linker_entry *entry)
{
struct fw_file *dest, *src;
uint32_t offset = le32_to_cpu(entry->pointer.offset);
uint64_t pointer = 0;
dest = qfw_find_file(dev, entry->pointer.dest_file);
if (!dest || !dest->addr)
return -ENOENT;
src = qfw_find_file(dev, entry->pointer.src_file);
if (!src || !src->addr)
return -ENOENT;
debug("bios_linker_add_pointer: dest->addr 0x%lx, src->addr 0x%lx, offset 0x%x size %u, 0x%llx\n",
dest->addr, src->addr, offset, entry->pointer.size, pointer);
memcpy(&pointer, (char *)dest->addr + offset, entry->pointer.size);
pointer = le64_to_cpu(pointer);
pointer += (unsigned long)src->addr;
pointer = cpu_to_le64(pointer);
memcpy((char *)dest->addr + offset, &pointer, entry->pointer.size);
return 0;
}
/*
* This function updates checksum fields of ACPI tables previously loaded
* by bios_linker_allocate()
*
* @entry : BIOS linker command entry which tells where to update ACPI table
* checksums
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_add_checksum(struct udevice *dev,
struct bios_linker_entry *entry)
{
struct fw_file *file;
uint8_t *data, cksum = 0;
uint8_t *cksum_start;
file = qfw_find_file(dev, entry->cksum.file);
if (!file || !file->addr)
return -ENOENT;
data = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.offset));
cksum_start = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.start));
cksum = table_compute_checksum(cksum_start,
le32_to_cpu(entry->cksum.length));
*data = cksum;
return 0;
}
/* This function loads and patches ACPI tables provided by QEMU */
ulong write_acpi_tables(ulong addr)
{
int i, ret;
struct fw_file *file;
struct bios_linker_entry *table_loader;
struct bios_linker_entry *entry;
uint32_t size;
struct udevice *dev;
ret = qfw_get_dev(&dev);
if (ret) {
printf("error: no qfw\n");
return addr;
}
/* make sure fw_list is loaded */
ret = qfw_read_firmware_list(dev);
if (ret) {
printf("error: can't read firmware file list\n");
return addr;
}
file = qfw_find_file(dev, "etc/table-loader");
if (!file) {
printf("error: can't find etc/table-loader\n");
return addr;
}
size = be32_to_cpu(file->cfg.size);
if ((size % sizeof(*entry)) != 0) {
printf("error: table-loader maybe corrupted\n");
return addr;
}
table_loader = malloc(size);
if (!table_loader) {
printf("error: no memory for table-loader\n");
return addr;
}
/* QFW always puts tables at high addresses */
gd->arch.table_start_high = (ulong)table_loader;
gd->arch.table_end_high = (ulong)table_loader;
qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size, table_loader);
for (i = 0; i < (size / sizeof(*entry)); i++) {
entry = table_loader + i;
switch (le32_to_cpu(entry->command)) {
case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
ret = bios_linker_allocate(dev, entry, &addr);
if (ret)
goto out;
break;
case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
ret = bios_linker_add_pointer(dev, entry);
if (ret)
goto out;
break;
case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
ret = bios_linker_add_checksum(dev, entry);
if (ret)
goto out;
break;
default:
break;
}
}
out:
if (ret) {
struct fw_cfg_file_iter iter;
for (file = qfw_file_iter_init(dev, &iter);
!qfw_file_iter_end(&iter);
file = qfw_file_iter_next(&iter)) {
if (file->addr) {
free((void *)file->addr);
file->addr = 0;
}
}
}
free(table_loader);
gd_set_acpi_start(acpi_get_rsdp_addr());
return addr;
}
ulong acpi_get_rsdp_addr(void)
{
int ret;
struct fw_file *file;
struct udevice *dev;
ret = qfw_get_dev(&dev);
if (ret) {
printf("error: no qfw\n");
return 0;
}
file = qfw_find_file(dev, "etc/acpi/rsdp");
return file->addr;
}
#endif
static void qfw_read_entry_io(struct qfw_dev *qdev, u16 entry, u32 size,
void *address)
{

281
drivers/misc/qfw_acpi.c Normal file
View file

@ -0,0 +1,281 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2015 Miao Yan <yanmiaobest@gmail.com>
* (C) Copyright 2021 Asherah Connor <ashe@kivikakk.ee>
*/
#define LOG_CATEGORY UCLASS_QFW
#include <acpi/acpi_table.h>
#include <errno.h>
#include <malloc.h>
#include <mapmem.h>
#include <qfw.h>
#include <tables_csum.h>
#include <stdio.h>
#include <linux/sizes.h>
#include <asm/byteorder.h>
#include <asm/global_data.h>
DECLARE_GLOBAL_DATA_PTR;
/*
* This function allocates memory for ACPI tables
*
* @entry : BIOS linker command entry which tells where to allocate memory
* (either high memory or low memory)
* @addr : The address that should be used for low memory allcation. If the
* memory allocation request is 'ZONE_HIGH' then this parameter will
* be ignored.
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_allocate(struct udevice *dev,
struct bios_linker_entry *entry, ulong *addr)
{
uint32_t size, align;
struct fw_file *file;
unsigned long aligned_addr;
align = le32_to_cpu(entry->alloc.align);
/* align must be power of 2 */
if (align & (align - 1)) {
printf("error: wrong alignment %u\n", align);
return -EINVAL;
}
file = qfw_find_file(dev, entry->alloc.file);
if (!file) {
printf("error: can't find file %s\n", entry->alloc.file);
return -ENOENT;
}
size = be32_to_cpu(file->cfg.size);
/*
* ZONE_HIGH means we need to allocate from high memory, since
* malloc space is already at the end of RAM, so we directly use it.
* If allocation zone is ZONE_FSEG, then we use the 'addr' passed
* in which is low memory
*/
if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH) {
aligned_addr = (unsigned long)memalign(align, size);
if (!aligned_addr) {
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 {
printf("error: invalid allocation zone\n");
return -EINVAL;
}
debug("bios_linker_allocate: allocate file %s, size %u, zone %d, align %u, addr 0x%lx\n",
file->cfg.name, size, entry->alloc.zone, align, aligned_addr);
qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size,
(void *)aligned_addr);
file->addr = aligned_addr;
/* adjust address for low memory allocation */
if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG)
*addr = (aligned_addr + size);
return 0;
}
/*
* This function patches ACPI tables previously loaded
* by bios_linker_allocate()
*
* @entry : BIOS linker command entry which tells how to patch
* ACPI tables
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_add_pointer(struct udevice *dev,
struct bios_linker_entry *entry)
{
struct fw_file *dest, *src;
uint32_t offset = le32_to_cpu(entry->pointer.offset);
uint64_t pointer = 0;
dest = qfw_find_file(dev, entry->pointer.dest_file);
if (!dest || !dest->addr)
return -ENOENT;
src = qfw_find_file(dev, entry->pointer.src_file);
if (!src || !src->addr)
return -ENOENT;
debug("bios_linker_add_pointer: dest->addr 0x%lx, src->addr 0x%lx, offset 0x%x size %u, 0x%llx\n",
dest->addr, src->addr, offset, entry->pointer.size, pointer);
memcpy(&pointer, (char *)dest->addr + offset, entry->pointer.size);
pointer = le64_to_cpu(pointer);
pointer += (unsigned long)src->addr;
pointer = cpu_to_le64(pointer);
memcpy((char *)dest->addr + offset, &pointer, entry->pointer.size);
return 0;
}
/*
* This function updates checksum fields of ACPI tables previously loaded
* by bios_linker_allocate()
*
* @entry : BIOS linker command entry which tells where to update ACPI table
* checksums
* @return: 0 on success, or negative value on failure
*/
static int bios_linker_add_checksum(struct udevice *dev,
struct bios_linker_entry *entry)
{
struct fw_file *file;
uint8_t *data, cksum = 0;
uint8_t *cksum_start;
file = qfw_find_file(dev, entry->cksum.file);
if (!file || !file->addr)
return -ENOENT;
data = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.offset));
cksum_start = (uint8_t *)(file->addr + le32_to_cpu(entry->cksum.start));
cksum = table_compute_checksum(cksum_start,
le32_to_cpu(entry->cksum.length));
*data = cksum;
return 0;
}
/* This function loads and patches ACPI tables provided by QEMU */
ulong write_acpi_tables(ulong addr)
{
int i, ret;
struct fw_file *file;
struct bios_linker_entry *table_loader;
struct bios_linker_entry *entry;
uint32_t size;
struct udevice *dev;
ret = qfw_get_dev(&dev);
if (ret) {
printf("error: no qfw\n");
return addr;
}
/* make sure fw_list is loaded */
ret = qfw_read_firmware_list(dev);
if (ret) {
printf("error: can't read firmware file list\n");
return addr;
}
file = qfw_find_file(dev, "etc/table-loader");
if (!file) {
printf("error: can't find etc/table-loader\n");
return addr;
}
size = be32_to_cpu(file->cfg.size);
if ((size % sizeof(*entry)) != 0) {
printf("error: table-loader maybe corrupted\n");
return addr;
}
table_loader = malloc(size);
if (!table_loader) {
printf("error: no memory for table-loader\n");
return addr;
}
/* QFW always puts tables at high addresses */
gd->arch.table_start_high = (ulong)table_loader;
gd->arch.table_end_high = (ulong)table_loader;
qfw_read_entry(dev, be16_to_cpu(file->cfg.select), size, table_loader);
for (i = 0; i < (size / sizeof(*entry)); i++) {
entry = table_loader + i;
switch (le32_to_cpu(entry->command)) {
case BIOS_LINKER_LOADER_COMMAND_ALLOCATE:
ret = bios_linker_allocate(dev, entry, &addr);
if (ret)
goto out;
break;
case BIOS_LINKER_LOADER_COMMAND_ADD_POINTER:
ret = bios_linker_add_pointer(dev, entry);
if (ret)
goto out;
break;
case BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM:
ret = bios_linker_add_checksum(dev, entry);
if (ret)
goto out;
break;
default:
break;
}
}
out:
if (ret) {
struct fw_cfg_file_iter iter;
for (file = qfw_file_iter_init(dev, &iter);
!qfw_file_iter_end(&iter);
file = qfw_file_iter_next(&iter)) {
if (file->addr) {
free((void *)file->addr);
file->addr = 0;
}
}
}
free(table_loader);
gd_set_acpi_start(acpi_get_rsdp_addr());
return addr;
}
ulong acpi_get_rsdp_addr(void)
{
int ret;
struct fw_file *file;
struct udevice *dev;
ret = qfw_get_dev(&dev);
if (ret) {
printf("error: no qfw\n");
return 0;
}
file = qfw_find_file(dev, "etc/acpi/rsdp");
return file->addr;
}
#ifndef CONFIG_X86
static int evt_write_acpi_tables(void)
{
ulong addr, end;
void *ptr;
/* Reserve 64K for ACPI tables, aligned to a 4K boundary */
ptr = memalign(SZ_4K, SZ_64K);
if (!ptr)
return -ENOMEM;
addr = map_to_sysmem(ptr);
/* Generate ACPI tables */
end = write_acpi_tables(addr);
gd->arch.table_start = addr;
gd->arch.table_end = addr;
return 0;
}
EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, evt_write_acpi_tables);
#endif

View file

@ -228,10 +228,8 @@ struct __packed acpi_fadt {
u8 reset_value;
u16 arm_boot_arch;
u8 minor_revision;
u32 x_firmware_ctl_l;
u32 x_firmware_ctl_h;
u32 x_dsdt_l;
u32 x_dsdt_h;
u64 x_firmware_ctrl;
u64 x_dsdt;
struct acpi_gen_regaddr x_pm1a_evt_blk;
struct acpi_gen_regaddr x_pm1b_evt_blk;
struct acpi_gen_regaddr x_pm1a_cnt_blk;

View file

@ -553,7 +553,7 @@ static_assert(sizeof(struct global_data) == GD_SIZE);
#endif
#ifdef CONFIG_SMBIOS
#define gd_smbios_start() gd->smbios_start
#define gd_smbios_start() gd->arch.smbios_start
#define gd_set_smbios_start(addr) gd->arch.smbios_start = addr
#else
#define gd_smbios_start() 0UL

View file

@ -433,6 +433,10 @@ struct efi_runtime_services {
EFI_GUID(0xeb9d2d31, 0x2d88, 0x11d3, \
0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
#define SMBIOS3_TABLE_GUID \
EFI_GUID(0xf2fd1544, 0x9794, 0x4a2c, \
0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
#define EFI_LOAD_FILE_PROTOCOL_GUID \
EFI_GUID(0x56ec3091, 0x954c, 0x11d2, \
0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)

View file

@ -72,7 +72,7 @@ struct bd_info;
* U-Boot is packaged as an ELF file, e.g. for debugging purposes
* @FDTSRC_ENV: Provided by the fdtcontroladdr environment variable. This should
* be used for debugging/development only
* @FDTSRC_NONE: No devicetree at all
* @FDTSRC_BLOBLIST: Provided by a bloblist from an earlier phase
*/
enum fdt_source_t {
FDTSRC_SEPARATE,
@ -80,6 +80,7 @@ enum fdt_source_t {
FDTSRC_BOARD,
FDTSRC_EMBED,
FDTSRC_ENV,
FDTSRC_BLOBLIST,
};
/*
@ -1190,7 +1191,8 @@ int fdtdec_resetup(int *rescan);
*
* The existing devicetree is available at gd->fdt_blob
*
* @err internal error code if we fail to setup a DTB
* @err: 0 on success, -EEXIST if the devicetree is already correct, or other
* internal error code if we fail to setup a DTB
* @returns new devicetree blob pointer
*/
void *board_fdt_blob_setup(int *err);

View file

@ -28,6 +28,24 @@ static inline phys_addr_t map_to_sysmem(const void *ptr)
{
return (phys_addr_t)(uintptr_t)ptr;
}
/**
* nomap_sysmem() - pass through an address unchanged
*
* This is used to indicate an address which should NOT be mapped, e.g. in
* SMBIOS tables. Using this function instead of a case shows that the sandbox
* conversion has been done
*/
static inline void *nomap_sysmem(phys_addr_t paddr, unsigned long len)
{
return (void *)(uintptr_t)paddr;
}
static inline phys_addr_t nomap_to_sysmem(const void *ptr)
{
return (phys_addr_t)(uintptr_t)ptr;
}
# endif
#endif /* __MAPMEM_H */

View file

@ -12,7 +12,7 @@
/* SMBIOS spec version implemented */
#define SMBIOS_MAJOR_VER 3
#define SMBIOS_MINOR_VER 0
#define SMBIOS_MINOR_VER 7
enum {
SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */
@ -54,6 +54,36 @@ struct __packed smbios_entry {
u8 bcd_rev;
};
/**
* struct smbios3_entry - SMBIOS 3.0 (64-bit) Entry Point structure
*/
struct __packed smbios3_entry {
/** @anchor: anchor string */
u8 anchor[5];
/** @checksum: checksum of the entry point structure */
u8 checksum;
/** @length: length of the entry point structure */
u8 length;
/** @major_ver: major version of the SMBIOS specification */
u8 major_ver;
/** @minor_ver: minor version of the SMBIOS specification */
u8 minor_ver;
/** @docrev: revision of the SMBIOS specification */
u8 doc_rev;
/** @entry_point_rev: revision of the entry point structure */
u8 entry_point_rev;
/** @reserved: reserved */
u8 reserved;
/** maximum size of SMBIOS table */
u32 max_struct_size;
/** @struct_table_address: 64-bit physical starting address */
u64 struct_table_address;
};
/* These two structures should use the same amount of 16-byte-aligned space */
static_assert(ALIGN(16, sizeof(struct smbios_entry)) ==
ALIGN(16, sizeof(struct smbios3_entry)));
/* BIOS characteristics */
#define BIOS_CHARACTERISTICS_PCI_SUPPORTED (1 << 7)
#define BIOS_CHARACTERISTICS_UPGRADEABLE (1 << 11)
@ -228,12 +258,13 @@ static inline void fill_smbios_header(void *table, int type,
*
* This writes SMBIOS table at a given address.
*
* @addr: start address to write SMBIOS table. If this is not
* 16-byte-aligned then it will be aligned before the table is
* written.
* @addr: start address to write SMBIOS table, 16-byte-alignment
* recommended. Note that while the SMBIOS tables themself have no alignment
* requirement, some systems may requires alignment. For example x86 systems
* which put tables at f0000 require 16-byte alignment
*
* Return: end address of SMBIOS table (and start address for next entry)
* or NULL in case of an error
*
*/
ulong write_smbios_table(ulong addr);

View file

@ -12,7 +12,7 @@ obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o
obj-y += acpi_writer.o
# With QEMU the ACPI tables come from there, not from U-Boot
ifndef CONFIG_QEMU
ifndef CONFIG_QFW_ACPI
obj-y += base.o
obj-y += csrt.o
obj-y += mcfg.o

View file

@ -22,13 +22,13 @@ struct acpi_table_header *acpi_find_table(const char *sig)
if (!rsdp)
return NULL;
if (rsdp->xsdt_address) {
xsdt = map_sysmem(rsdp->xsdt_address, 0);
xsdt = nomap_sysmem(rsdp->xsdt_address, 0);
len = xsdt->header.length - sizeof(xsdt->header);
count = len / sizeof(u64);
} else {
if (!rsdp->rsdt_address)
return NULL;
rsdt = map_sysmem(rsdp->rsdt_address, 0);
rsdt = nomap_sysmem(rsdp->rsdt_address, 0);
len = rsdt->header.length - sizeof(rsdt->header);
count = len / sizeof(u32);
}
@ -36,19 +36,38 @@ struct acpi_table_header *acpi_find_table(const char *sig)
struct acpi_table_header *hdr;
if (rsdp->xsdt_address)
hdr = map_sysmem(xsdt->entry[i], 0);
hdr = nomap_sysmem(xsdt->entry[i], 0);
else
hdr = map_sysmem(rsdt->entry[i], 0);
hdr = nomap_sysmem(rsdt->entry[i], 0);
if (!memcmp(hdr->signature, sig, ACPI_NAME_LEN))
return hdr;
if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN)) {
struct acpi_fadt *fadt = (struct acpi_fadt *)hdr;
if (!memcmp(sig, "DSDT", ACPI_NAME_LEN) && fadt->dsdt)
return map_sysmem(fadt->dsdt, 0);
if (!memcmp(sig, "FACS", ACPI_NAME_LEN) &&
fadt->firmware_ctrl)
return map_sysmem(fadt->firmware_ctrl, 0);
if (!memcmp(sig, "DSDT", ACPI_NAME_LEN)) {
void *dsdt;
if (fadt->header.revision >= 3 && fadt->x_dsdt)
dsdt = nomap_sysmem(fadt->x_dsdt, 0);
else if (fadt->dsdt)
dsdt = nomap_sysmem(fadt->dsdt, 0);
else
dsdt = NULL;
return dsdt;
}
if (!memcmp(sig, "FACS", ACPI_NAME_LEN)) {
void *facs;
if (fadt->header.revision >= 3 &&
fadt->x_firmware_ctrl)
facs = nomap_sysmem(fadt->x_firmware_ctrl, 0);
else if (fadt->firmware_ctrl)
facs = nomap_sysmem(fadt->firmware_ctrl, 0);
else
facs = NULL;
return facs;
}
}
}

View file

@ -167,7 +167,7 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
}
/* Add table to the RSDT */
rsdt->entry[i] = map_to_sysmem(table);
rsdt->entry[i] = nomap_to_sysmem(table);
/* Fix RSDT length or the kernel will assume invalid entries */
rsdt->header.length = sizeof(struct acpi_table_header) +
@ -185,7 +185,7 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
xsdt = ctx->xsdt;
/* Add table to the XSDT */
xsdt->entry[i] = map_to_sysmem(table);
xsdt->entry[i] = nomap_to_sysmem(table);
/* Fix XSDT length */
xsdt->header.length = sizeof(struct acpi_table_header) +

View file

@ -48,7 +48,7 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry)
return 0;
}
#ifndef CONFIG_QEMU
#ifndef CONFIG_QFW_ACPI
static int acpi_write_all(struct acpi_ctx *ctx)
{
const struct acpi_writer *writer =
@ -115,7 +115,7 @@ ulong acpi_get_rsdp_addr(void)
return map_to_sysmem(gd->acpi_ctx->rsdp);
}
#endif /* QEMU */
#endif /* QFW_ACPI */
void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start)
{

View file

@ -24,10 +24,10 @@ void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
memcpy(rsdp->oem_id, OEM_ID, 6);
if (rsdt)
rsdp->rsdt_address = map_to_sysmem(rsdt);
rsdp->rsdt_address = nomap_to_sysmem(rsdt);
if (xsdt)
rsdp->xsdt_address = map_to_sysmem(xsdt);
rsdp->xsdt_address = nomap_to_sysmem(xsdt);
rsdp->length = sizeof(struct acpi_rsdp);
rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;

View file

@ -14,6 +14,8 @@
#include <smbios.h>
#include <linux/sizes.h>
const efi_guid_t smbios3_guid = SMBIOS3_TABLE_GUID;
enum {
TABLE_SIZE = SZ_4K,
};
@ -27,8 +29,9 @@ efi_status_t efi_smbios_register(void)
{
ulong addr;
efi_status_t ret;
void *buf;
addr = gd->arch.smbios_start;
addr = gd_smbios_start();
if (!addr) {
log_err("No SMBIOS tables to install\n");
return EFI_NOT_FOUND;
@ -42,33 +45,34 @@ efi_status_t efi_smbios_register(void)
log_debug("EFI using SMBIOS tables at %lx\n", addr);
/* Install SMBIOS information as configuration table */
return efi_install_configuration_table(&smbios_guid,
map_sysmem(addr, 0));
buf = map_sysmem(addr, 0);
ret = efi_install_configuration_table(&smbios3_guid, buf);
unmap_sysmem(buf);
return ret;
}
static int install_smbios_table(void)
{
u64 addr;
efi_status_t ret;
ulong addr;
void *buf;
if (!IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE) || IS_ENABLED(CONFIG_X86))
return 0;
addr = SZ_4G;
ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
EFI_RUNTIME_SERVICES_DATA,
efi_size_in_pages(TABLE_SIZE), &addr);
if (ret != EFI_SUCCESS)
/* Align the table to a 4KB boundary to keep EFI happy */
buf = memalign(SZ_4K, TABLE_SIZE);
if (!buf)
return log_msg_ret("mem", -ENOMEM);
addr = map_to_sysmem((void *)(uintptr_t)addr);
addr = map_to_sysmem(buf);
if (!write_smbios_table(addr)) {
log_err("Failed to write SMBIOS table\n");
return log_msg_ret("smbios", -EINVAL);
}
/* Make a note of where we put it */
log_debug("SMBIOS tables written to %llx\n", addr);
log_debug("SMBIOS tables written to %lx\n", addr);
gd->arch.smbios_start = addr;
return 0;

View file

@ -7,6 +7,10 @@
*/
#ifndef USE_HOSTCC
#define LOG_CATEGORY LOGC_DT
#include <bloblist.h>
#include <boot_fit.h>
#include <display_options.h>
#include <dm.h>
@ -86,6 +90,7 @@ static const char *const fdt_src_name[] = {
[FDTSRC_BOARD] = "board",
[FDTSRC_EMBED] = "embed",
[FDTSRC_ENV] = "env",
[FDTSRC_BLOBLIST] = "bloblist",
};
const char *fdtdec_get_srcname(void)
@ -1662,23 +1667,42 @@ static void setup_multi_dtb_fit(void)
int fdtdec_setup(void)
{
int ret;
int ret = -ENOENT;
/* The devicetree is typically appended to U-Boot */
if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
gd->fdt_blob = fdt_find_separate();
gd->fdt_src = FDTSRC_SEPARATE;
} else { /* embed dtb in ELF file for testing / development */
gd->fdt_blob = dtb_dt_embedded();
gd->fdt_src = FDTSRC_EMBED;
/* If allowing a bloblist, check that first */
if (CONFIG_IS_ENABLED(BLOBLIST)) {
ret = bloblist_maybe_init();
if (!ret) {
gd->fdt_blob = bloblist_find(BLOBLISTT_CONTROL_FDT, 0);
if (gd->fdt_blob) {
gd->fdt_src = FDTSRC_BLOBLIST;
log_debug("Devicetree is in bloblist at %p\n",
gd->fdt_blob);
} else {
log_debug("No FDT found in bloblist\n");
ret = -ENOENT;
}
}
}
/* Otherwise, the devicetree is typically appended to U-Boot */
if (ret) {
if (IS_ENABLED(CONFIG_OF_SEPARATE)) {
gd->fdt_blob = fdt_find_separate();
gd->fdt_src = FDTSRC_SEPARATE;
} else { /* embed dtb in ELF file for testing / development */
gd->fdt_blob = dtb_dt_embedded();
gd->fdt_src = FDTSRC_EMBED;
}
}
/* Allow the board to override the fdt address. */
if (IS_ENABLED(CONFIG_OF_BOARD)) {
gd->fdt_blob = board_fdt_blob_setup(&ret);
if (ret)
if (!ret)
gd->fdt_src = FDTSRC_BOARD;
else if (ret != -EEXIST)
return ret;
gd->fdt_src = FDTSRC_BOARD;
}
/* Allow the early environment to override the fdt address */

View file

@ -544,15 +544,13 @@ static struct smbios_write_method smbios_write_funcs[] = {
ulong write_smbios_table(ulong addr)
{
ofnode parent_node = ofnode_null();
struct smbios_entry *se;
ulong table_addr, start_addr;
struct smbios3_entry *se;
struct smbios_ctx ctx;
ulong table_addr;
ulong tables;
int len = 0;
int max_struct_size = 0;
int handle = 0;
char *istart;
int isize;
int i;
ctx.node = ofnode_null();
@ -564,14 +562,10 @@ ulong write_smbios_table(ulong addr)
ctx.dev = NULL;
}
/* 16 byte align the table address */
addr = ALIGN(addr, 16);
start_addr = addr;
se = map_sysmem(addr, sizeof(struct smbios_entry));
memset(se, 0, sizeof(struct smbios_entry));
addr += sizeof(struct smbios_entry);
addr = ALIGN(addr, 16);
/* move past the (so-far-unwritten) header to start writing structs */
addr = ALIGN(addr + sizeof(struct smbios3_entry), 16);
tables = addr;
/* populate minimum required tables */
@ -589,40 +583,25 @@ ulong write_smbios_table(ulong addr)
len += tmp;
}
memcpy(se->anchor, "_SM_", 4);
se->length = sizeof(struct smbios_entry);
se->major_ver = SMBIOS_MAJOR_VER;
se->minor_ver = SMBIOS_MINOR_VER;
se->max_struct_size = max_struct_size;
memcpy(se->intermediate_anchor, "_DMI_", 5);
se->struct_table_length = len;
/*
* We must use a pointer here so things work correctly on sandbox. The
* user of this table is not aware of the mapping of addresses to
* sandbox's DRAM buffer.
*/
table_addr = (ulong)map_sysmem(tables, 0);
if (sizeof(table_addr) > sizeof(u32) && table_addr > (ulong)UINT_MAX) {
/*
* We need to put this >32-bit pointer into the table but the
* field is only 32 bits wide.
*/
printf("WARNING: SMBIOS table_address overflow %llx\n",
(unsigned long long)table_addr);
addr = 0;
goto out;
}
/* now go back and write the SMBIOS3 header */
se = map_sysmem(start_addr, sizeof(struct smbios_entry));
memset(se, '\0', sizeof(struct smbios_entry));
memcpy(se->anchor, "_SM3_", 5);
se->length = sizeof(struct smbios3_entry);
se->major_ver = SMBIOS_MAJOR_VER;
se->minor_ver = SMBIOS_MINOR_VER;
se->doc_rev = 0;
se->entry_point_rev = 1;
se->max_struct_size = len;
se->struct_table_address = table_addr;
se->struct_count = handle;
/* calculate checksums */
istart = (char *)se + SMBIOS_INTERMEDIATE_OFFSET;
isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
se->intermediate_checksum = table_compute_checksum(istart, isize);
se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
out:
se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry));
unmap_sysmem(se);
return addr;

View file

@ -291,8 +291,8 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
/* Check that the pointers were added correctly */
for (i = 0; i < 3; i++) {
ut_asserteq(map_to_sysmem(dmar + i), ctx.rsdt->entry[i]);
ut_asserteq(map_to_sysmem(dmar + i), ctx.xsdt->entry[i]);
ut_asserteq(nomap_to_sysmem(dmar + i), ctx.rsdt->entry[i]);
ut_asserteq(nomap_to_sysmem(dmar + i), ctx.xsdt->entry[i]);
}
ut_asserteq(0, ctx.rsdt->entry[3]);
ut_asserteq(0, ctx.xsdt->entry[3]);
@ -330,7 +330,7 @@ static int dm_test_acpi_basic(struct unit_test_state *uts)
DM_TEST(dm_test_acpi_basic, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/* Test setup_ctx_and_base_tables */
static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts)
static int dm_test_acpi_ctx_and_base_tables(struct unit_test_state *uts)
{
struct acpi_rsdp *rsdp;
struct acpi_rsdt *rsdt;
@ -371,12 +371,12 @@ static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts)
end = PTR_ALIGN((void *)xsdt + sizeof(*xsdt), 64);
ut_asserteq_ptr(end, ctx.current);
ut_asserteq(map_to_sysmem(rsdt), rsdp->rsdt_address);
ut_asserteq(map_to_sysmem(xsdt), rsdp->xsdt_address);
ut_asserteq(nomap_to_sysmem(rsdt), rsdp->rsdt_address);
ut_asserteq(nomap_to_sysmem(xsdt), rsdp->xsdt_address);
return 0;
}
DM_TEST(dm_test_setup_ctx_and_base_tables,
DM_TEST(dm_test_acpi_ctx_and_base_tables,
UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
/* Test 'acpi list' command */
@ -445,7 +445,7 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
/* Now a real table */
console_record_reset();
run_command("acpi dump dmar", 0);
addr = ALIGN(map_to_sysmem(ctx.xsdt) + sizeof(struct acpi_xsdt), 64);
addr = ALIGN(nomap_to_sysmem(ctx.xsdt) + sizeof(struct acpi_xsdt), 64);
ut_assert_nextline("DMAR @ %16lx", addr);
ut_assert_nextlines_are_dump(0x30);
ut_assert_console_end();