diff options
author | Tom Rini <trini@konsulko.com> | 2022-04-04 10:45:33 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-04-04 10:48:44 -0400 |
commit | 01f1ab67f38882dc7665a0a6eca4bbeba6d84f81 (patch) | |
tree | 31b1febefe82731d94571f7442877c039efb602c /common | |
parent | e4b6ebd3de982ae7185dbf689a030e73fd06e0d2 (diff) | |
parent | 8221c52d88fbe84ca9692dc23827e21403c952e8 (diff) | |
download | u-boot-01f1ab67f38882dc7665a0a6eca4bbeba6d84f81.zip u-boot-01f1ab67f38882dc7665a0a6eca4bbeba6d84f81.tar.gz u-boot-01f1ab67f38882dc7665a0a6eca4bbeba6d84f81.tar.bz2 |
Merge branch 'next'
Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 53 | ||||
-rw-r--r-- | common/Makefile | 2 | ||||
-rw-r--r-- | common/board_f.c | 13 | ||||
-rw-r--r-- | common/board_r.c | 1 | ||||
-rw-r--r-- | common/event.c | 196 | ||||
-rw-r--r-- | common/fdt_support.c | 2 | ||||
-rw-r--r-- | common/lcd.c | 194 | ||||
-rw-r--r-- | common/log.c | 1 | ||||
-rw-r--r-- | common/miiphyutil.c | 2 | ||||
-rw-r--r-- | common/spl/Kconfig | 6 | ||||
-rw-r--r-- | common/spl/Makefile | 1 | ||||
-rw-r--r-- | common/spl/spl_ram.c | 21 | ||||
-rw-r--r-- | common/spl/spl_semihosting.c | 71 | ||||
-rw-r--r-- | common/stdio.c | 4 |
14 files changed, 351 insertions, 216 deletions
diff --git a/common/Kconfig b/common/Kconfig index 82cd864..8f8a906 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -492,6 +492,37 @@ config DISPLAY_BOARDINFO_LATE menu "Start-up hooks" +config EVENT + bool "General-purpose event-handling mechanism" + default y if SANDBOX + help + This enables sending and processing of events, to allow interested + parties to be alerted when something happens. This is an attempt to + step the flow of weak functions, hooks, functions in board_f.c + and board_r.c and the Kconfig options below. + + See doc/develop/event.rst for more information. + +if EVENT + +config EVENT_DYNAMIC + bool "Support event registration at runtime" + default y if SANDBOX + help + Enable this to support adding an event spy at runtime, without adding + it to the EVENT_SPy() linker list. This increases code size slightly + but provides more flexibility for boards and subsystems that need it. + +config EVENT_DEBUG + bool "Enable event debugging assistance" + default y if SANDBOX + help + Enable this get usefui features for seeing what is happening with + events, such as event-type names. This adds to the code size of + U-Boot so can be turned off for production builds. + +endif # EVENT + config ARCH_EARLY_INIT_R bool "Call arch-specific init soon after relocation" help @@ -524,6 +555,12 @@ config BOARD_EARLY_INIT_R relocation. With this option, U-Boot calls board_early_init_r() in the post-relocation init sequence. +config BOARD_POSTCLK_INIT + bool "Call board_postclk_init" + help + Some boards need this to initialize select items, after clocks / + timebase and before env / serial. + config BOARD_LATE_INIT bool "Execute Board late init" help @@ -534,6 +571,10 @@ config BOARD_LATE_INIT So this config enable the late init code with the help of board_late_init function which should defined on respective boards. +config CLOCKS + bool "Call set_cpu_clk_info" + depends on ARM + config SYS_FSL_CLK bool depends on ARCH_LS1021A || FSL_LSCH2 || FSL_LSCH3 || \ @@ -552,12 +593,6 @@ config LAST_STAGE_INIT U-Boot calls last_stage_init() before the command-line interpreter is started. -config MISC_INIT_F - bool "Execute pre-relocation misc init" - help - Enabling this option calls the 'misc_init_f' function in the init - sequence just before DRAM is inited. - config MISC_INIT_R bool "Execute Misc Init" default y if ARCH_KEYSTONE || ARCH_SUNXI || MPC85xx @@ -580,6 +615,12 @@ config PCI_INIT_R case of DM PCI-based Ethernet devices, which will not be detected without having the enumeration performed earlier. +config RESET_PHY_R + bool "Reset ethernet PHY during init" + help + Implement reset_phy() in board code if required to reset the ethernet + PHY. + endmenu endmenu # Init options diff --git a/common/Makefile b/common/Makefile index 3eff719..cc2ba30 100644 --- a/common/Makefile +++ b/common/Makefile @@ -89,6 +89,8 @@ obj-y += malloc_simple.o endif endif +obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o + obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o obj-$(CONFIG_IO_TRACE) += iotrace.o obj-y += memsize.o diff --git a/common/board_f.c b/common/board_f.c index a687600..5b655ad 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -19,6 +19,7 @@ #include <dm.h> #include <env.h> #include <env_internal.h> +#include <event.h> #include <fdtdec.h> #include <fs.h> #include <hang.h> @@ -802,19 +803,19 @@ __weak int reserve_arch(void) return 0; } -__weak int arch_cpu_init_dm(void) +__weak int checkcpu(void) { return 0; } -__weak int checkcpu(void) +__weak int clear_bss(void) { return 0; } -__weak int clear_bss(void) +static int misc_init_f(void) { - return 0; + return event_notify_null(EVT_MISC_INIT_F); } static const init_fnc_t init_sequence_f[] = { @@ -828,6 +829,7 @@ static const init_fnc_t init_sequence_f[] = { initf_malloc, log_init, initf_bootstage, /* uses its own timer, so does not need DM */ + event_init, #ifdef CONFIG_BLOBLIST bloblist_init, #endif @@ -841,7 +843,6 @@ static const init_fnc_t init_sequence_f[] = { arch_cpu_init, /* basic arch cpu dependent setup */ mach_cpu_init, /* SoC/machine dependent CPU setup */ initf_dm, - arch_cpu_init_dm, #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, #endif @@ -875,9 +876,7 @@ static const init_fnc_t init_sequence_f[] = { show_board_info, #endif INIT_FUNC_WATCHDOG_INIT -#if defined(CONFIG_MISC_INIT_F) misc_init_f, -#endif INIT_FUNC_WATCHDOG_RESET #if CONFIG_IS_ENABLED(SYS_I2C_LEGACY) init_func_i2c, diff --git a/common/board_r.c b/common/board_r.c index c24d9b4..b92c1bb 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -594,6 +594,7 @@ static int run_main_loop(void) static init_fnc_t init_sequence_r[] = { initr_trace, initr_reloc, + event_init, /* TODO: could x86/PPC have this also perhaps? */ #if defined(CONFIG_ARM) || defined(CONFIG_RISCV) initr_caches, diff --git a/common/event.c b/common/event.c new file mode 100644 index 0000000..9d67a06 --- /dev/null +++ b/common/event.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Events provide a general-purpose way to react to / subscribe to changes + * within U-Boot + * + * Copyright 2021 Google LLC + * Written by Simon Glass <sjg@chromium.org> + */ + +#define LOG_CATEGORY LOGC_EVENT + +#include <common.h> +#include <event.h> +#include <event_internal.h> +#include <log.h> +#include <linker_lists.h> +#include <malloc.h> +#include <asm/global_data.h> +#include <linux/list.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(EVENT_DEBUG) +const char *const type_name[] = { + "none", + "test", + + /* Events related to driver model */ + "dm_post_init", + "dm_pre_probe", + "dm_post_probe", + "dm_pre_remove", + "dm_post_remove", + + /* init hooks */ + "misc_init_f", +}; + +_Static_assert(ARRAY_SIZE(type_name) == EVT_COUNT, "event type_name size"); +#endif + +static const char *event_type_name(enum event_t type) +{ +#if CONFIG_IS_ENABLED(EVENT_DEBUG) + return type_name[type]; +#else + return "(unknown)"; +#endif +} + +static int notify_static(struct event *ev) +{ + struct evspy_info *start = + ll_entry_start(struct evspy_info, evspy_info); + const int n_ents = ll_entry_count(struct evspy_info, evspy_info); + struct evspy_info *spy; + + for (spy = start; spy != start + n_ents; spy++) { + if (spy->type == ev->type) { + int ret; + + log_debug("Sending event %x/%s to spy '%s'\n", ev->type, + event_type_name(ev->type), event_spy_id(spy)); + ret = spy->func(NULL, ev); + + /* + * TODO: Handle various return codes to + * + * - claim an event (no others will see it) + * - return an error from the event + */ + if (ret) + return log_msg_ret("spy", ret); + } + } + + return 0; +} + +static int notify_dynamic(struct event *ev) +{ + struct event_state *state = gd_event_state(); + struct event_spy *spy, *next; + + list_for_each_entry_safe(spy, next, &state->spy_head, sibling_node) { + if (spy->type == ev->type) { + int ret; + + log_debug("Sending event %x/%s to spy '%s'\n", ev->type, + event_type_name(ev->type), spy->id); + ret = spy->func(spy->ctx, ev); + + /* + * TODO: Handle various return codes to + * + * - claim an event (no others will see it) + * - return an error from the event + */ + if (ret) + return log_msg_ret("spy", ret); + } + } + + return 0; +} + +int event_notify(enum event_t type, void *data, int size) +{ + struct event event; + int ret; + + event.type = type; + if (size > sizeof(event.data)) + return log_msg_ret("size", -E2BIG); + memcpy(&event.data, data, size); + + ret = notify_static(&event); + if (ret) + return log_msg_ret("dyn", ret); + + if (CONFIG_IS_ENABLED(EVENT_DYNAMIC)) { + ret = notify_dynamic(&event); + if (ret) + return log_msg_ret("dyn", ret); + } + + return 0; +} + +int event_notify_null(enum event_t type) +{ + return event_notify(type, NULL, 0); +} + +void event_show_spy_list(void) +{ + struct evspy_info *start = + ll_entry_start(struct evspy_info, evspy_info); + const int n_ents = ll_entry_count(struct evspy_info, evspy_info); + struct evspy_info *spy; + const int size = sizeof(ulong) * 2; + + printf("Seq %-24s %*s %s\n", "Type", size, "Function", "ID"); + for (spy = start; spy != start + n_ents; spy++) { + printf("%3x %-3x %-20s %*p %s\n", (uint)(spy - start), + spy->type, event_type_name(spy->type), size, spy->func, + event_spy_id(spy)); + } +} + +#if CONFIG_IS_ENABLED(EVENT_DYNAMIC) +static void spy_free(struct event_spy *spy) +{ + list_del(&spy->sibling_node); +} + +int event_register(const char *id, enum event_t type, event_handler_t func, void *ctx) +{ + struct event_state *state = gd_event_state(); + struct event_spy *spy; + + if (!CONFIG_IS_ENABLED(EVENT_DYNAMIC)) + return -ENOSYS; + spy = malloc(sizeof(*spy)); + if (!spy) + return log_msg_ret("alloc", -ENOMEM); + + spy->id = id; + spy->type = type; + spy->func = func; + spy->ctx = ctx; + list_add_tail(&spy->sibling_node, &state->spy_head); + + return 0; +} + +int event_uninit(void) +{ + struct event_state *state = gd_event_state(); + struct event_spy *spy, *next; + + list_for_each_entry_safe(spy, next, &state->spy_head, sibling_node) + spy_free(spy); + + return 0; +} + +int event_init(void) +{ + struct event_state *state = gd_event_state(); + + INIT_LIST_HEAD(&state->spy_head); + + return 0; +} +#endif /* EVENT_DYNAMIC */ diff --git a/common/fdt_support.c b/common/fdt_support.c index ea18ea3..8662bd2 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1725,7 +1725,7 @@ int fdt_set_status_by_pathf(void *fdt, enum fdt_status status, const char *fmt, return fdt_set_node_status(fdt, offset, status); } -#if defined(CONFIG_VIDEO) || defined(CONFIG_LCD) +#if defined(CONFIG_LCD) int fdt_add_edid(void *blob, const char *compat, unsigned char *edid_buf) { int noff; diff --git a/common/lcd.c b/common/lcd.c index 16a0a7c..0898bc0 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -90,54 +90,6 @@ static void lcd_stub_puts(struct stdio_dev *dev, const char *s) lcd_puts(s); } -/* Small utility to check that you got the colours right */ -#ifdef LCD_TEST_PATTERN - -#if LCD_BPP == LCD_COLOR8 -#define N_BLK_VERT 2 -#define N_BLK_HOR 3 - -static int test_colors[N_BLK_HOR * N_BLK_VERT] = { - CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW, - CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN, -}; /*LCD_BPP == LCD_COLOR8 */ - -#elif LCD_BPP == LCD_COLOR16 -#define N_BLK_VERT 2 -#define N_BLK_HOR 4 - -static int test_colors[N_BLK_HOR * N_BLK_VERT] = { - CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW, CONSOLE_COLOR_BLUE, - CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN, CONSOLE_COLOR_GREY, CONSOLE_COLOR_WHITE, -}; -#endif /*LCD_BPP == LCD_COLOR16 */ - -static void test_pattern(void) -{ - ushort v_max = panel_info.vl_row; - ushort h_max = panel_info.vl_col; - ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT; - ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR; - ushort v, h; -#if LCD_BPP == LCD_COLOR8 - uchar *pix = (uchar *)lcd_base; -#elif LCD_BPP == LCD_COLOR16 - ushort *pix = (ushort *)lcd_base; -#endif - - printf("[LCD] Test Pattern: %d x %d [%d x %d]\n", - h_max, v_max, h_step, v_step); - - for (v = 0; v < v_max; ++v) { - uchar iy = v / v_step; - for (h = 0; h < h_max; ++h) { - uchar ix = N_BLK_HOR * iy + h / h_step; - *pix++ = test_colors[ix]; - } - } -} -#endif /* LCD_TEST_PATTERN */ - /* * With most lcd drivers the line length is set up * by calculating it from panel_info parameters. Some @@ -201,9 +153,6 @@ void lcd_clear(void) bg_color = CONSOLE_COLOR_BLACK; #endif /* CONFIG_SYS_WHITE_ON_BLACK */ -#ifdef LCD_TEST_PATTERN - test_pattern(); -#else /* set framebuffer to background color */ #if (LCD_BPP != LCD_COLOR32) memset((char *)lcd_base, bg_color, lcd_line_length * panel_info.vl_row); @@ -216,7 +165,6 @@ void lcd_clear(void) *ppix++ = bg_color; } #endif -#endif /* setup text-console */ debug("[LCD] setting up console...\n"); lcd_init_console(lcd_base, @@ -399,135 +347,6 @@ static void splash_align_axis(int *axis, unsigned long panel_size, } #endif -#ifdef CONFIG_LCD_BMP_RLE8 -#define BMP_RLE8_ESCAPE 0 -#define BMP_RLE8_EOL 0 -#define BMP_RLE8_EOBMP 1 -#define BMP_RLE8_DELTA 2 - -static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap, - int cnt) -{ - while (cnt > 0) { - *(*fbp)++ = cmap[*bmap++]; - cnt--; - } -} - -static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt) -{ - ushort *fb = *fbp; - int cnt_8copy = cnt >> 3; - - cnt -= cnt_8copy << 3; - while (cnt_8copy > 0) { - *fb++ = c; - *fb++ = c; - *fb++ = c; - *fb++ = c; - *fb++ = c; - *fb++ = c; - *fb++ = c; - *fb++ = c; - cnt_8copy--; - } - while (cnt > 0) { - *fb++ = c; - cnt--; - } - *fbp = fb; -} - -/* - * Do not call this function directly, must be called from lcd_display_bitmap. - */ -static void lcd_display_rle8_bitmap(struct bmp_image *bmp, ushort *cmap, - uchar *fb, int x_off, int y_off) -{ - uchar *bmap; - ulong width, height; - ulong cnt, runlen; - int x, y; - int decode = 1; - - width = get_unaligned_le32(&bmp->header.width); - height = get_unaligned_le32(&bmp->header.height); - bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset); - - x = 0; - y = height - 1; - - while (decode) { - if (bmap[0] == BMP_RLE8_ESCAPE) { - switch (bmap[1]) { - case BMP_RLE8_EOL: - /* end of line */ - bmap += 2; - x = 0; - y--; - /* 16bpix, 2-byte per pixel, width should *2 */ - fb -= (width * 2 + lcd_line_length); - break; - case BMP_RLE8_EOBMP: - /* end of bitmap */ - decode = 0; - break; - case BMP_RLE8_DELTA: - /* delta run */ - x += bmap[2]; - y -= bmap[3]; - /* 16bpix, 2-byte per pixel, x should *2 */ - fb = (uchar *) (lcd_base + (y + y_off - 1) - * lcd_line_length + (x + x_off) * 2); - bmap += 4; - break; - default: - /* unencoded run */ - runlen = bmap[1]; - bmap += 2; - if (y < height) { - if (x < width) { - if (x + runlen > width) - cnt = width - x; - else - cnt = runlen; - draw_unencoded_bitmap( - (ushort **)&fb, - bmap, cmap, cnt); - } - x += runlen; - } - bmap += runlen; - if (runlen & 1) - bmap++; - } - } else { - /* encoded run */ - if (y < height) { - runlen = bmap[0]; - if (x < width) { - /* aggregate the same code */ - while (bmap[0] == 0xff && - bmap[2] != BMP_RLE8_ESCAPE && - bmap[1] == bmap[3]) { - runlen += bmap[2]; - bmap += 2; - } - if (x + runlen > width) - cnt = width - x; - else - cnt = runlen; - draw_encoded_bitmap((ushort **)&fb, - cmap[bmap[1]], cnt); - } - x += runlen; - } - bmap += 2; - } - } -} -#endif - __weak void fb_put_byte(uchar **fb, uchar **from) { *(*fb)++ = *(*from)++; @@ -633,19 +452,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) case 1: case 8: { cmap_base = configuration_get_cmap(); -#ifdef CONFIG_LCD_BMP_RLE8 - u32 compression = get_unaligned_le32(&bmp->header.compression); - debug("compressed %d %d\n", compression, BMP_BI_RLE8); - if (compression == BMP_BI_RLE8) { - if (bpix != 16) { - /* TODO implement render code for bpix != 16 */ - printf("Error: only support 16 bpix"); - return 1; - } - lcd_display_rle8_bitmap(bmp, cmap_base, fb, x, y); - break; - } -#endif if (bpix != 16) byte_width = width; diff --git a/common/log.c b/common/log.c index f7e0c0f..7254aa7 100644 --- a/common/log.c +++ b/common/log.c @@ -28,6 +28,7 @@ static const char *const log_cat_name[] = { "devres", "acpi", "boot", + "event", }; _Static_assert(ARRAY_SIZE(log_cat_name) == LOGC_COUNT - LOGC_NONE, diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 7d4d15e..194c84e 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -366,7 +366,7 @@ int miiphy_reset(const char *devname, unsigned char addr) debug("PHY reset failed\n"); return -1; } -#ifdef CONFIG_PHY_RESET_DELAY +#if CONFIG_PHY_RESET_DELAY > 0 udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */ #endif /* diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 9418d37..dc319ad 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1334,16 +1334,16 @@ config TPL_SIZE_LIMIT If this value is zero, it is ignored. config TPL_BINMAN_SYMBOLS - bool "Declare binman symbols in SPL" + bool "Declare binman symbols in TPL" depends on SPL_FRAMEWORK && BINMAN default y help - This enables use of symbols in TPL which refer to U-Boot, enabling SPL + This enables use of symbols in TPL which refer to U-Boot, enabling TPL to obtain the location of U-Boot simply by calling spl_get_image_pos() and spl_get_image_size(). For this to work, you must have a U-Boot image in the binman image, so - binman can update SPL with the location of it. + binman can update TPL with the location of it. config TPL_FRAMEWORK bool "Support TPL based upon the common SPL framework" diff --git a/common/spl/Makefile b/common/spl/Makefile index db8fd36..e71e7be 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_$(SPL_TPL_)USB_STORAGE) += spl_usb.o obj-$(CONFIG_$(SPL_TPL_)FS_FAT) += spl_fat.o obj-$(CONFIG_$(SPL_TPL_)FS_EXT4) += spl_ext.o obj-$(CONFIG_$(SPL_TPL_)SATA) += spl_sata.o +obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += spl_semihosting.o obj-$(CONFIG_$(SPL_TPL_)DFU) += spl_dfu.o obj-$(CONFIG_$(SPL_TPL_)SPI_LOAD) += spl_spi.o obj-$(CONFIG_$(SPL_TPL_)RAM_SUPPORT) += spl_ram.o diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index 3f7f7ac..8296459 100644 --- a/common/spl/spl_ram.c +++ b/common/spl/spl_ram.c @@ -24,9 +24,17 @@ static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, ulong count, void *buf) { + ulong addr; + debug("%s: sector %lx, count %lx, buf %lx\n", __func__, sector, count, (ulong)buf); - memcpy(buf, (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + sector), count); + + addr = (ulong)CONFIG_SPL_LOAD_FIT_ADDRESS + sector; + if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) + addr += image_load_offset; + + memcpy(buf, (void *)addr, count); + return count; } @@ -37,6 +45,17 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; + if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) { + unsigned long addr = (unsigned long)header; + int ret = image_pre_load(addr); + + if (ret) + return ret; + + addr += image_load_offset; + header = (struct image_header *)addr; + } + #if CONFIG_IS_ENABLED(DFU) if (bootdev->boot_device == BOOT_DEVICE_DFU) spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0"); diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c new file mode 100644 index 0000000..df6aeb2 --- /dev/null +++ b/common/spl/spl_semihosting.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com> + */ + +#include <common.h> +#include <image.h> +#include <log.h> +#include <semihosting.h> +#include <spl.h> + +static int smh_read_full(long fd, void *memp, size_t len) +{ + long read; + + read = smh_read(fd, memp, len); + if (read < 0) + return read; + if (read != len) + return -EIO; + return 0; +} + +static int spl_smh_load_image(struct spl_image_info *spl_image, + struct spl_boot_device *bootdev) +{ + const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME; + int ret; + long fd, len; + struct image_header *header = + spl_get_load_buffer(-sizeof(*header), sizeof(*header)); + + fd = smh_open(filename, MODE_READ | MODE_BINARY); + if (fd < 0) { + log_debug("could not open %s: %ld\n", filename, fd); + return fd; + } + + ret = smh_flen(fd); + if (ret < 0) { + log_debug("could not get length of image: %d\n", ret); + goto out; + } + len = ret; + + ret = smh_read_full(fd, header, sizeof(struct image_header)); + if (ret) { + log_debug("could not read image header: %d\n", ret); + goto out; + } + + ret = spl_parse_image_header(spl_image, bootdev, header); + if (ret) { + log_debug("failed to parse image header: %d\n", ret); + goto out; + } + + ret = smh_seek(fd, 0); + if (ret) { + log_debug("could not seek to start of image: %d\n", ret); + goto out; + } + + ret = smh_read_full(fd, (void *)spl_image->load_addr, len); + if (ret) + log_debug("could not read %s: %d\n", filename, ret); +out: + smh_close(fd); + return ret; +} +SPL_LOAD_IMAGE_METHOD("SEMIHOSTING", 0, BOOT_DEVICE_SMH, spl_smh_load_image); diff --git a/common/stdio.c b/common/stdio.c index 063c659..92161a0 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -367,9 +367,7 @@ int stdio_add_devices(void) } else { if (IS_ENABLED(CONFIG_LCD)) drv_lcd_init(); - if (IS_ENABLED(CONFIG_VIDEO) || - IS_ENABLED(CONFIG_CFB_CONSOLE) || - IS_ENABLED(CONFIG_VIDEO_VCXK)) + if (IS_ENABLED(CONFIG_VIDEO_VCXK)) drv_video_init(); } |