diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/acpi/Makefile | 2 | ||||
-rw-r--r-- | lib/acpi/acpi.c | 37 | ||||
-rw-r--r-- | lib/acpi/acpi_table.c | 4 | ||||
-rw-r--r-- | lib/acpi/acpi_writer.c | 4 | ||||
-rw-r--r-- | lib/acpi/base.c | 4 | ||||
-rw-r--r-- | lib/efi_loader/efi_smbios.c | 28 | ||||
-rw-r--r-- | lib/fdtdec.c | 44 | ||||
-rw-r--r-- | lib/smbios.c | 55 |
8 files changed, 102 insertions, 76 deletions
diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile index c1c9675b5d..cc2868488a 100644 --- a/lib/acpi/Makefile +++ b/lib/acpi/Makefile @@ -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 diff --git a/lib/acpi/acpi.c b/lib/acpi/acpi.c index 939a638bb5..f4d5c1e25d 100644 --- a/lib/acpi/acpi.c +++ b/lib/acpi/acpi.c @@ -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; + } } } diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c index e74522e997..39dd53ec40 100644 --- a/lib/acpi/acpi_table.c +++ b/lib/acpi/acpi_table.c @@ -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) + diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c index a8dc207557..bbb9b54786 100644 --- a/lib/acpi/acpi_writer.c +++ b/lib/acpi/acpi_writer.c @@ -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) { diff --git a/lib/acpi/base.c b/lib/acpi/base.c index 07b53e0c56..8b6af2bc43 100644 --- a/lib/acpi/base.c +++ b/lib/acpi/base.c @@ -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; diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c index bbb8421ce1..eb6d2ba43c 100644 --- a/lib/efi_loader/efi_smbios.c +++ b/lib/efi_loader/efi_smbios.c @@ -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; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4016bf3c11..b2c59ab381 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -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; + + /* 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; + } + } + } - /* 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; + /* 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 */ diff --git a/lib/smbios.c b/lib/smbios.c index 45480b01af..d9d52bd58d 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -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; - } - 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: + /* 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->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry)); unmap_sysmem(se); return addr; |