From f98caa6ae3864451b38c52c6be17e6e53b6685ac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Jul 2023 21:38:49 -0600 Subject: log: Tidy up an ambiguous comment Add a bit more detail so it is clear that multiple devices are supported, but only one per driver. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- common/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/log.c b/common/log.c index 6f02a25c593..b2de57fcb3b 100644 --- a/common/log.c +++ b/common/log.c @@ -437,7 +437,7 @@ int log_init(void) /* * We cannot add runtime data to the driver since it is likely stored * in rodata. Instead, set up a 'device' corresponding to each driver. - * We only support having a single device. + * We only support having a single device for each driver. */ INIT_LIST_HEAD((struct list_head *)&gd->log_head); while (drv < end) { -- cgit v1.3.1 From 8f015d37813b398c9f2bde9bbf531278a399ad88 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Jul 2023 21:38:52 -0600 Subject: x86: Improve the trampoline in 64-bit mode At present this leaves the stack at the pre-relocation value. This is not ideal since we want to have U-Boot running entirely from the top of memory. In addition, the new global_data pointer is not actually used, since the global_data pointer itself is relocated, then the pre-relocation value is changed, so the effective value (after relocation) does not update. Adjust the implementation to follow the 32-bit code more closely, with a trampoline function which is passed the new stack and global_data pointer. This ensures that the correct values come through even when relocating. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/start64.S | 19 +++++++++++++++++++ arch/x86/include/asm/u-boot-x86.h | 11 +++++++++++ common/board_f.c | 12 +++++++----- 3 files changed, 37 insertions(+), 5 deletions(-) (limited to 'common') diff --git a/arch/x86/cpu/start64.S b/arch/x86/cpu/start64.S index 7be834788b9..78e894d2a21 100644 --- a/arch/x86/cpu/start64.S +++ b/arch/x86/cpu/start64.S @@ -26,3 +26,22 @@ _start: /* Should not return here */ jmp . + +.globl board_init_f_r_trampoline64 +.type board_init_f_r_trampoline64, @function +board_init_f_r_trampoline64: + /* + * SDRAM has been initialised, U-Boot code has been copied into + * RAM, BSS has been cleared and relocation adjustments have been + * made. It is now time to jump into the in-RAM copy of U-Boot + * + * %eax = Address of top of new stack + */ + + /* Stack grows down from top of SDRAM */ + movq %rsi, %rsp + + /* New gd is in rdi */ + + /* Re-enter U-Boot by calling board_init_f_r() */ + call board_init_f_r diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 1d8aa320f53..02a8b0f1527 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -117,6 +117,17 @@ void __noreturn board_init_f_r_trampoline(ulong sp); */ void __noreturn board_init_f_r(void); +/* + * board_init_f_r_trampoline64() - jump to relocated address with new stack + * + * This is the 64-bit version + * + * @new_gd: New global_data pointer to use + * @sp: New stack pointer to pass on to board_init_r() + */ +void __noreturn board_init_f_r_trampoline64(struct global_data *new_gd, + ulong sp); + int arch_misc_init(void); /* Read the time stamp counter */ diff --git a/common/board_f.c b/common/board_f.c index 334d04af197..e5969ec9a27 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -729,8 +729,7 @@ static int fix_fdt(void) #endif /* ARM calls relocate_code from its crt0.S */ -#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ - !CONFIG_IS_ENABLED(X86_64) +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) static int jump_to_copy(void) { @@ -752,7 +751,11 @@ static int jump_to_copy(void) * (CPU cache) */ arch_setup_gd(gd->new_gd); - board_init_f_r_trampoline(gd->start_addr_sp); +# if CONFIG_IS_ENABLED(X86_64) + board_init_f_r_trampoline64(gd->new_gd, gd->start_addr_sp); +# else + board_init_f_r_trampoline(gd->start_addr_sp); +# endif #else relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr); #endif @@ -967,8 +970,7 @@ static const init_fnc_t init_sequence_f[] = { * watchdog device is not serviced is as small as possible. */ cyclic_unregister_all, -#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \ - !CONFIG_IS_ENABLED(X86_64) +#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) jump_to_copy, #endif NULL, -- cgit v1.3.1 From 0be0f205b974abb7b464e5b2819db47bbc6d5f1f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Jul 2023 21:38:53 -0600 Subject: bdinfo: Show the malloc base with the bdinfo command It is useful to see the base of the malloc region. This is visible when debugging but not in normal usage. Add it to the global data so that it can be shown. Signed-off-by: Simon Glass Reviewed-by: Nikhil M Jain Reviewed-by: Bin Meng Tested-by: Nikhil M Jain --- cmd/bdinfo.c | 1 + common/board_r.c | 7 ++++--- include/asm-generic/global_data.h | 13 +++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 44e6d6a972e..1fe13ca13a0 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -176,6 +176,7 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (IS_ENABLED(CONFIG_CMD_BDINFO_EXTRA)) { bdinfo_print_num_ll("stack ptr", (ulong)&bd); bdinfo_print_num_ll("ram_top ptr", (ulong)gd->ram_top); + bdinfo_print_num_l("malloc base", gd_malloc_start()); } arch_print_bdinfo(); diff --git a/common/board_r.c b/common/board_r.c index d798c00a80a..4aaa8940311 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -196,7 +196,7 @@ static int initr_barrier(void) static int initr_malloc(void) { - ulong malloc_start; + ulong start; #if CONFIG_VAL(SYS_MALLOC_F_LEN) debug("Pre-reloc malloc() used %#lx bytes (%ld KB)\n", gd->malloc_ptr, @@ -207,8 +207,9 @@ static int initr_malloc(void) * This value MUST match the value of gd->start_addr_sp in board_f.c: * reserve_noncached(). */ - malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN; - mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN), + start = gd->relocaddr - TOTAL_MALLOC_LEN; + gd_set_malloc_start(start); + mem_malloc_init((ulong)map_sysmem(start, TOTAL_MALLOC_LEN), TOTAL_MALLOC_LEN); return 0; } diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index a1e1b9d6400..8fc205ded1a 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -301,6 +301,12 @@ struct global_data { * @timebase_l: low 32 bits of timer */ unsigned int timebase_l; + /** + * @malloc_start: start of malloc() region + */ +#if CONFIG_IS_ENABLED(CMD_BDINFO_EXTRA) + unsigned long malloc_start; +#endif #if CONFIG_VAL(SYS_MALLOC_F_LEN) /** * @malloc_base: base address of early malloc() @@ -560,6 +566,13 @@ static_assert(sizeof(struct global_data) == GD_SIZE); #define gd_event_state() NULL #endif +#if CONFIG_IS_ENABLED(CMD_BDINFO_EXTRA) +#define gd_malloc_start() gd->malloc_start +#define gd_set_malloc_start(_val) gd->malloc_start = (_val) +#else +#define gd_malloc_start() 0 +#define gd_set_malloc_start(val) +#endif /** * enum gd_flags - global data flags * -- cgit v1.3.1 From 03fe79c091cee0bd591070dd24adfa8f556b50df Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Jul 2023 21:38:59 -0600 Subject: x86: Pass video settings from SPL to U-Boot proper When video is set up in SPL, U-Boot proper needs to use the correct parameters so it can write to the display. Put these in a bloblist so they are available to U-Boot proper. Signed-off-by: Simon Glass Reviewed-by: Nikhil M Jain Reviewed-by: Bin Meng --- common/bloblist.c | 1 + drivers/pci/pci_rom.c | 78 +++++++++++++++++++++++++++++++++++++-------------- include/bloblist.h | 1 + include/video.h | 24 ++++++++++++++++ 4 files changed, 83 insertions(+), 21 deletions(-) (limited to 'common') diff --git a/common/bloblist.c b/common/bloblist.c index 0d63b6e8817..2144b10e1d0 100644 --- a/common/bloblist.c +++ b/common/bloblist.c @@ -51,6 +51,7 @@ static struct tag_name { /* BLOBLISTT_PROJECT_AREA */ { BLOBLISTT_U_BOOT_SPL_HANDOFF, "SPL hand-off" }, + { BLOBLISTT_U_BOOT_VIDEO, "SPL video handoff" }, /* BLOBLISTT_VENDOR_AREA */ }; diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 228ab7fca72..bdfd1f03e79 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -374,34 +376,68 @@ int vesa_setup_video(struct udevice *dev, int (*int15_handler)(void)) printf("Not available (previous bootloader prevents it)\n"); return -EPERM; } - bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); - ret = dm_pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE | - PCI_ROM_ALLOW_FALLBACK); - bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); - if (ret) { - debug("failed to run video BIOS: %d\n", ret); - return ret; - } - ret = vesa_setup_video_priv(&mode_info.vesa, - mode_info.vesa.phys_base_ptr, uc_priv, - plat); - if (ret) { - if (ret == -ENFILE) { - /* - * See video-uclass.c for how to set up reserved memory - * in your video driver - */ - log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n", - dev->driver->name); + /* In U-Boot proper, collect the information added by SPL (see below) */ + if (IS_ENABLED(CONFIG_SPL_VIDEO) && spl_phase() > PHASE_SPL && + CONFIG_IS_ENABLED(BLOBLIST)) { + struct video_handoff *ho; + + ho = bloblist_find(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho)); + if (!ho) + return log_msg_ret("blf", -ENOENT); + plat->base = ho->fb; + plat->size = ho->size; + uc_priv->xsize = ho->xsize; + uc_priv->ysize = ho->ysize; + uc_priv->line_length = ho->line_length; + uc_priv->bpix = ho->bpix; + } else { + bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); + ret = dm_pci_run_vga_bios(dev, int15_handler, + PCI_ROM_USE_NATIVE | + PCI_ROM_ALLOW_FALLBACK); + bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); + if (ret) { + debug("failed to run video BIOS: %d\n", ret); + return ret; } - debug("No video mode configured\n"); - return ret; + ret = vesa_setup_video_priv(&mode_info.vesa, + mode_info.vesa.phys_base_ptr, + uc_priv, plat); + if (ret) { + if (ret == -ENFILE) { + /* + * See video-uclass.c for how to set up reserved + * memory in your video driver + */ + log_err("CONFIG_VIDEO_COPY enabled but driver '%s' set up no reserved memory\n", + dev->driver->name); + } + + debug("No video mode configured\n"); + return ret; + } } printf("Video: %dx%dx%d\n", uc_priv->xsize, uc_priv->ysize, mode_info.vesa.bits_per_pixel); + /* In SPL, store the information for use by U-Boot proper */ + if (spl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(BLOBLIST)) { + struct video_handoff *ho; + + ho = bloblist_add(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho), 0); + if (!ho) + return log_msg_ret("blc", -ENOMEM); + + ho->fb = plat->base; + ho->size = plat->size; + ho->xsize = uc_priv->xsize; + ho->ysize = uc_priv->ysize; + ho->line_length = uc_priv->line_length; + ho->bpix = uc_priv->bpix; + } + return 0; } diff --git a/include/bloblist.h b/include/bloblist.h index 2a2f1700eb0..7ea72c6bd46 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -113,6 +113,7 @@ enum bloblist_tag_t { BLOBLISTT_PROJECT_AREA = 0x8000, BLOBLISTT_U_BOOT_SPL_HANDOFF = 0x8000, /* Hand-off info from SPL */ BLOBLISTT_VBE = 0x8001, /* VBE per-phase state */ + BLOBLISTT_U_BOOT_VIDEO = 0x8002, /* Video information from SPL */ /* * Vendor-specific tags are permitted here. Projects can be open source diff --git a/include/video.h b/include/video.h index e98d0f9c895..9729fa348aa 100644 --- a/include/video.h +++ b/include/video.h @@ -134,6 +134,30 @@ struct video_ops { #define video_get_ops(dev) ((struct video_ops *)(dev)->driver->ops) +/** + * struct video_handoff - video information passed from SPL + * + * This is used when video is set up by SPL, to provide the details to U-Boot + * proper. + * + * @fb: Base address of frame buffer, 0 if not yet known + * @size: Frame-buffer size, in bytes + * @xsize: Number of pixel columns (e.g. 1366) + * @ysize: Number of pixels rows (e.g.. 768) + * @line_length: Length of each frame buffer line, in bytes. This can be + * set by the driver, but if not, the uclass will set it after + * probing + * @bpix: Encoded bits per pixel (enum video_log2_bpp) + */ +struct video_handoff { + u64 fb; + u32 size; + u16 xsize; + u16 ysize; + u32 line_length; + u8 bpix; +}; + /** enum colour_idx - the 16 colors supported by consoles */ enum colour_idx { VID_BLACK = 0, -- cgit v1.3.1 From f9ebfd7c7acebd3d28a3be1d33e30c6f88a05302 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Jul 2023 21:39:14 -0600 Subject: log: Support outputing function names in SPL The output is garbled when tiny printf() is used. Correct this by adding a special case. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- common/log_console.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/log_console.c b/common/log_console.c index f1dcc04b97c..bb091ce21a4 100644 --- a/common/log_console.c +++ b/common/log_console.c @@ -37,8 +37,14 @@ static int log_console_emit(struct log_device *ldev, struct log_rec *rec) printf("%s:", rec->file); if (fmt & BIT(LOGF_LINE)) printf("%d-", rec->line); - if (fmt & BIT(LOGF_FUNC)) - printf("%*s()", CONFIG_LOGF_FUNC_PAD, rec->func); + if (fmt & BIT(LOGF_FUNC)) { + if (CONFIG_IS_ENABLED(USE_TINY_PRINTF)) { + printf("%s()", rec->func); + } else { + printf("%*s()", CONFIG_LOGF_FUNC_PAD, + rec->func); + } + } } if (fmt & BIT(LOGF_MSG)) printf("%s%s", add_space ? " " : "", rec->msg); -- cgit v1.3.1