diff options
author | Tom Rini <trini@konsulko.com> | 2025-01-22 16:08:34 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2025-01-22 17:08:47 -0600 |
commit | a3b71cc6f5cc74d4edc5808790a3d2999ea3f7fe (patch) | |
tree | bf148f9145392c695ffb623ef8c307a4a3fe8e82 /drivers | |
parent | 2eed5a1ff36217372e19f7513bd07077fc76718a (diff) | |
parent | 8985ff56b16dc6c04da2c96d48e7f6f54d04e3ff (diff) | |
download | u-boot-a3b71cc6f5cc74d4edc5808790a3d2999ea3f7fe.tar.gz |
Merge patch series "upl: Prerequite patches for updated spec"
Simon Glass <sjg@chromium.org> says:
The current UPL spec[1] has been tidied up and improved over the last
year, since U-Boot's original UPL support was written.
This series includes some prerequisite patches needed for the real UPL
patches. It is split from [2]
[1] https://github.com/UniversalPayload/spec/tree/3f1450d
[2] https://patchwork.ozlabs.org/project/uboot/list/?series=438574&state=*
Link: https://lore.kernel.org/r/20250111000029.245022-1-sjg@chromium.org
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/core/ofnode.c | 67 | ||||
-rw-r--r-- | drivers/misc/qfw_acpi.c | 37 | ||||
-rw-r--r-- | drivers/misc/qfw_smbios.c | 45 | ||||
-rw-r--r-- | drivers/pci/pci_rom.c | 3 | ||||
-rw-r--r-- | drivers/serial/ns16550.c | 2 | ||||
-rw-r--r-- | drivers/video/bochs.c | 1 | ||||
-rw-r--r-- | drivers/video/video-uclass.c | 1 |
7 files changed, 117 insertions, 39 deletions
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index c8161827d1c..26e014d5c53 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -118,7 +118,7 @@ int oftree_new(oftree *treep) return log_msg_ret("liv", ret); tree = oftree_from_np(root); } else { - const int size = 1024; + const int size = 4096; void *fdt; ret = check_tree_count(); @@ -309,6 +309,29 @@ bool ofnode_name_eq(ofnode node, const char *name) return (strlen(name) == len) && !strncmp(node_name, name, len); } +bool ofnode_name_eq_unit(ofnode node, const char *name) +{ + const char *node_name, *p; + int len; + + assert(ofnode_valid(node)); + + node_name = ofnode_get_name(node); + + /* check the whole name */ + if (!strcmp(node_name, name)) + return true; + + /* if @name has no unit address, try the node name without it */ + len = strlen(name); + p = strchr(node_name, '@'); + if (p && !strchr(name, '@') && len == p - node_name && + !strncmp(node_name, name, len)) + return true; + + return false; +} + int ofnode_read_u8(ofnode node, const char *propname, u8 *outp) { const u8 *cell; @@ -576,14 +599,9 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) log_debug("%s: %s: ", __func__, subnode_name); if (ofnode_is_np(node)) { - struct device_node *np = ofnode_to_np(node); - - for (np = np->child; np; np = np->sibling) { - if (!strcmp(subnode_name, np->name)) - break; - } - subnode = np_to_ofnode(np); + subnode = ofnode_find_subnode_unit(node, subnode_name); } else { + /* special case to avoid code-size increase */ int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); subnode = noffset_to_ofnode(node, ooffset); @@ -594,6 +612,26 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) return subnode; } +ofnode ofnode_find_subnode_unit(ofnode node, const char *subnode_name) +{ + ofnode subnode, found = ofnode_null(); + + assert(ofnode_valid(node)); + log_debug("%s: ", subnode_name); + + ofnode_for_each_subnode(subnode, node) { + if (ofnode_name_eq_unit(subnode, subnode_name)) { + found = subnode; + break; + } + } + + log_debug("%s\n", ofnode_valid(found) ? + ofnode_get_name(found) : "<none>"); + + return found; +} + int ofnode_read_u32_array(ofnode node, const char *propname, u32 *out_values, size_t sz) { @@ -1710,9 +1748,10 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, int ofnode_write_prop(ofnode node, const char *propname, const void *value, int len, bool copy) { + int ret; + if (of_live_active()) { void *newval; - int ret; if (copy) { newval = malloc(len); @@ -1726,8 +1765,12 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, free(newval); return ret; } else { - return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), - propname, value, len); + ret = fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, value, len); + if (ret) + return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EINVAL; + + return 0; } } @@ -2015,7 +2058,7 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) ret = -EEXIST; } if (offset < 0) - return -EINVAL; + return offset == -FDT_ERR_NOSPACE ? -ENOSPC : -EINVAL; subnode = noffset_to_ofnode(node, offset); } diff --git a/drivers/misc/qfw_acpi.c b/drivers/misc/qfw_acpi.c index 7ffed1e8c02..0d0cf764689 100644 --- a/drivers/misc/qfw_acpi.c +++ b/drivers/misc/qfw_acpi.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY UCLASS_QFW #include <acpi/acpi_table.h> +#include <bloblist.h> #include <errno.h> #include <malloc.h> #include <mapmem.h> @@ -160,6 +161,15 @@ ulong write_acpi_tables(ulong addr) struct bios_linker_entry *entry; uint32_t size; struct udevice *dev; + struct acpi_ctx *ctx; + + ctx = malloc(sizeof(*ctx)); + if (!ctx) { + printf("error: out of memory for acpi ctx\n"); + return addr; + } + + acpi_setup_ctx(ctx, addr); ret = qfw_get_dev(&dev); if (ret) { @@ -257,6 +267,29 @@ ulong acpi_get_rsdp_addr(void) return file->addr; } +void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt, + struct acpi_xsdt *xsdt) +{ + memset(rsdp, 0, sizeof(struct acpi_rsdp)); + + memcpy(rsdp->signature, RSDP_SIG, 8); + memcpy(rsdp->oem_id, OEM_ID, 6); + + if (rsdt) + rsdp->rsdt_address = nomap_to_sysmem(rsdt); + + if (xsdt) + rsdp->xsdt_address = nomap_to_sysmem(xsdt); + + rsdp->length = sizeof(struct acpi_rsdp); + rsdp->revision = ACPI_RSDP_REV_ACPI_2_0; + + /* Calculate checksums */ + rsdp->checksum = table_compute_checksum(rsdp, 20); + rsdp->ext_checksum = table_compute_checksum(rsdp, + sizeof(struct acpi_rsdp)); +} + #ifndef CONFIG_X86 static int evt_write_acpi_tables(void) { @@ -264,9 +297,9 @@ static int evt_write_acpi_tables(void) void *ptr; /* Reserve 64K for ACPI tables, aligned to a 4K boundary */ - ptr = memalign(SZ_4K, SZ_64K); + ptr = bloblist_add(BLOBLISTT_ACPI_TABLES, SZ_64K, 12); if (!ptr) - return -ENOMEM; + return -ENOBUFS; addr = map_to_sysmem(ptr); /* Generate ACPI tables */ diff --git a/drivers/misc/qfw_smbios.c b/drivers/misc/qfw_smbios.c index c3e8c310d00..93c4a80286b 100644 --- a/drivers/misc/qfw_smbios.c +++ b/drivers/misc/qfw_smbios.c @@ -5,6 +5,7 @@ #define LOG_CATEGORY UCLASS_QFW +#include <bloblist.h> #include <efi_loader.h> #include <errno.h> #include <log.h> @@ -15,6 +16,7 @@ #include <tables_csum.h> #include <linux/sizes.h> #include <asm/global_data.h> +#include <linux/err.h> DECLARE_GLOBAL_DATA_PTR; @@ -105,11 +107,10 @@ out: /** * qfw_write_smbios_tables() - copy SMBIOS tables from QEMU * - * @addr: target buffer - * @size: size of target buffer + * @addr: address of target buffer * Return: 0 for success, -ve on error */ -static int qfw_write_smbios_tables(u8 *addr, uint32_t size) +ulong write_smbios_table(ulong addr) { int ret; struct udevice *dev; @@ -143,16 +144,13 @@ static int qfw_write_smbios_tables(u8 *addr, uint32_t size) table = qfw_load_smbios_table(dev, &table_size, "etc/smbios/smbios-tables"); - if (table_size + sizeof(struct smbios3_entry) > size) { - free(table); - return -ENOMEM; - } - memcpy(addr, table, table_size); + memcpy((void *)addr, table, table_size); free(table); - return 0; + return addr + table_size; } +#ifndef CONFIG_X86 /** * qfw_evt_write_smbios_tables() - event handler for copying QEMU SMBIOS tables * @@ -160,9 +158,9 @@ static int qfw_write_smbios_tables(u8 *addr, uint32_t size) */ static int qfw_evt_write_smbios_tables(void) { - phys_addr_t addr; + ulong addr, end; void *ptr; - int ret; + /* * TODO: * This size is currently hard coded in lib/efi_loader/efi_smbios.c. @@ -170,22 +168,21 @@ static int qfw_evt_write_smbios_tables(void) */ uint32_t size = SZ_4K; - /* Reserve 64K for SMBIOS tables, aligned to a 4K boundary */ - ptr = memalign(SZ_4K, size); - if (!ptr) { - log_err("Out of memory\n"); - return -ENOMEM; - } + log_debug("qfw_evt_write_smbios_tables bloblist\n"); + /* Reserve 4K for SMBIOS tables, aligned to a 4K boundary */ + ptr = bloblist_add(BLOBLISTT_SMBIOS_TABLES, size, 12); + if (!ptr) + return log_msg_ret("bloblist", -ENOBUFS); + addr = map_to_sysmem(ptr); /* Generate SMBIOS tables */ - ret = qfw_write_smbios_tables(ptr, size); - if (ret) { - if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) { - log_info("Falling back to U-Boot generated SMBIOS tables\n"); - write_smbios_table(addr); - } + end = write_smbios_table(addr); + if (IS_ERR_VALUE(end)) { + log_warning("SMBIOS: Failed to write (err=%dE)\n", (int)end); } else { + if (end - addr > size) + return -ENOMEM; log_debug("SMBIOS tables copied from QEMU\n"); } @@ -193,5 +190,5 @@ static int qfw_evt_write_smbios_tables(void) return 0; } - EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, qfw_evt_write_smbios_tables); +#endif /* !X86 */ diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 2753df275ca..3697ad00be2 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -347,6 +347,7 @@ int vesa_setup_video_priv(struct vesa_mode_info *vesa, u64 fb, case 32: case 24: uc_priv->bpix = VIDEO_BPP32; + uc_priv->format = VIDEO_X8B8G8R8; break; case 16: uc_priv->bpix = VIDEO_BPP16; @@ -392,6 +393,7 @@ int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void)) uc_priv->ysize = ho->ysize; uc_priv->line_length = ho->line_length; uc_priv->bpix = ho->bpix; + uc_priv->format = ho->format; } else { bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); ret = dm_pci_run_vga_bios(dev, int15_handler, @@ -438,6 +440,7 @@ int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void)) ho->ysize = uc_priv->ysize; ho->line_length = uc_priv->line_length; ho->bpix = uc_priv->bpix; + ho->format = uc_priv->format; } return 0; diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index c3b884b6d00..039da835f5f 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -464,7 +464,7 @@ int ns16550_serial_getinfo(struct udevice *dev, struct serial_device_info *info) struct ns16550_plat *plat = com_port->plat; /* save code size */ - if (!not_xpl()) + if (!not_xpl() && !CONFIG_IS_ENABLED(UPL_OUT)) return -ENOSYS; info->type = SERIAL_CHIP_16550_COMPATIBLE; diff --git a/drivers/video/bochs.c b/drivers/video/bochs.c index 00e673a4db0..c34bc23f274 100644 --- a/drivers/video/bochs.c +++ b/drivers/video/bochs.c @@ -64,6 +64,7 @@ static int bochs_init_fb(struct udevice *dev) uc_priv->xsize = xsize; uc_priv->ysize = ysize; uc_priv->bpix = VIDEO_BPP32; + uc_priv->format = VIDEO_X8B8G8R8; /* setup video mode */ bochs_write(mmio, INDEX_ENABLE, 0); diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index a5b3e898066..ff4f2199585 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -589,6 +589,7 @@ static int video_post_probe(struct udevice *dev) ho->ysize = priv->ysize; ho->line_length = priv->line_length; ho->bpix = priv->bpix; + ho->format = priv->format; } if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base) |