diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Kconfig | 18 | ||||
-rw-r--r-- | common/Makefile | 3 | ||||
-rw-r--r-- | common/board_f.c | 64 | ||||
-rw-r--r-- | common/board_r.c | 17 | ||||
-rw-r--r-- | common/bootstage.c | 257 | ||||
-rw-r--r-- | common/dlmalloc.c | 2 | ||||
-rw-r--r-- | common/spl/Kconfig | 97 | ||||
-rw-r--r-- | common/spl/spl.c | 18 |
8 files changed, 292 insertions, 184 deletions
diff --git a/common/Kconfig b/common/Kconfig index 5c39663..c49199b 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -18,6 +18,15 @@ config BOOTSTAGE Calls to show_boot_progress() will also result in log entries but these will not have names. +config SPL_BOOTSTAGE + bool "Boot timing and reported in SPL" + depends on BOOTSTAGE + help + Enable recording of boot time in SPL. To make this visible to U-Boot + proper, enable BOOTSTAGE_STASH as well. This will stash the timing + information when SPL finishes and load it when U-Boot proper starts + up. + config BOOTSTAGE_REPORT bool "Display a detailed boot timing report before booting the OS" depends on BOOTSTAGE @@ -38,7 +47,7 @@ config BOOTSTAGE_REPORT 30,361,327 445,160 start_kernel config BOOTSTAGE_USER_COUNT - hex "Number of boot ID numbers available for user use" + int "Number of boot ID numbers available for user use" default 20 help This is the number of available user bootstage records. @@ -46,6 +55,13 @@ config BOOTSTAGE_USER_COUNT a new ID will be allocated from this stash. If you exceed the limit, recording will stop. +config BOOTSTAGE_RECORD_COUNT + int "Number of boot stage records to store" + default 30 + help + This is the size of the bootstage record list and is the maximum + number of bootstage records that can be recorded. + config BOOTSTAGE_FDT bool "Store boot timing information in the OS device tree" depends on BOOTSTAGE diff --git a/common/Makefile b/common/Makefile index c7c8ea4..539cf98 100644 --- a/common/Makefile +++ b/common/Makefile @@ -65,7 +65,6 @@ obj-$(CONFIG_USB_STORAGE) += usb_storage.o endif # others -obj-$(CONFIG_BOOTSTAGE) += bootstage.o obj-$(CONFIG_CONSOLE_MUX) += iomux.o obj-$(CONFIG_MTD_NOR_FLASH) += flash.o obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o @@ -89,6 +88,8 @@ obj-$(CONFIG_CMDLINE) += cli_readline.o cli_simple.o endif # !CONFIG_SPL_BUILD +obj-$(CONFIG_$(SPL_)BOOTSTAGE) += bootstage.o + ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_DFU_SUPPORT) += dfu.o obj-$(CONFIG_SPL_DFU_SUPPORT) += cli_hush.o diff --git a/common/board_f.c b/common/board_f.c index a212f2b..46e5284 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -31,6 +31,9 @@ #include <trace.h> #include <video.h> #include <watchdog.h> +#ifdef CONFIG_MACH_TYPE +#include <asm/mach-types.h> +#endif #if defined(CONFIG_MP) && defined(CONFIG_PPC) #include <asm/mp.h> #endif @@ -488,6 +491,20 @@ static int reserve_fdt(void) return 0; } +static int reserve_bootstage(void) +{ +#ifdef CONFIG_BOOTSTAGE + int size = bootstage_get_size(); + + gd->start_addr_sp -= size; + gd->new_bootstage = map_sysmem(gd->start_addr_sp, size); + debug("Reserving %#x Bytes for bootstage at: %08lx\n", size, + gd->start_addr_sp); +#endif + + return 0; +} + int arch_reserve_stacks(void) { return 0; @@ -602,6 +619,24 @@ static int reloc_fdt(void) return 0; } +static int reloc_bootstage(void) +{ +#ifdef CONFIG_BOOTSTAGE + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; + if (gd->new_bootstage) { + int size = bootstage_get_size(); + + debug("Copying bootstage from %p to %p, size %x\n", + gd->bootstage, gd->new_bootstage, size); + memcpy(gd->new_bootstage, gd->bootstage, size); + gd->bootstage = gd->new_bootstage; + } +#endif + + return 0; +} + static int setup_reloc(void) { if (gd->flags & GD_FLG_SKIP_RELOC) { @@ -670,8 +705,29 @@ static int jump_to_copy(void) #endif /* Record the board_init_f() bootstage (after arch_cpu_init()) */ -static int mark_bootstage(void) +static int initf_bootstage(void) { +#if defined(CONFIG_SPL_BOOTSTAGE) && defined(CONFIG_BOOTSTAGE_STASH) + bool from_spl = true; +#else + bool from_spl = false; +#endif + int ret; + + ret = bootstage_init(!from_spl); + if (ret) + return ret; + if (from_spl) { + const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, + CONFIG_BOOTSTAGE_STASH_SIZE); + + ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); + if (ret && ret != -ENOENT) { + debug("Failed to unstash bootstage: err=%d\n", ret); + return ret; + } + } + bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f"); return 0; @@ -691,7 +747,9 @@ static int initf_dm(void) #if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN) int ret; + bootstage_start(BOOTSTATE_ID_ACCUM_DM_F, "dm_f"); ret = dm_init_and_scan(true); + bootstage_accum(BOOTSTATE_ID_ACCUM_DM_F); if (ret) return ret; #endif @@ -724,6 +782,7 @@ static const init_fnc_t init_sequence_f[] = { trace_early_init, #endif initf_malloc, + initf_bootstage, /* uses its own timer, so does not need DM */ initf_console_record, #if defined(CONFIG_HAVE_FSP) arch_fsp_init, @@ -732,7 +791,6 @@ static const init_fnc_t init_sequence_f[] = { mach_cpu_init, /* SoC/machine dependent CPU setup */ initf_dm, arch_cpu_init_dm, - mark_bootstage, /* need timer, go after init dm */ #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, #endif @@ -819,6 +877,7 @@ static const init_fnc_t init_sequence_f[] = { setup_machine, reserve_global_data, reserve_fdt, + reserve_bootstage, reserve_arch, reserve_stacks, dram_init_banksize, @@ -840,6 +899,7 @@ static const init_fnc_t init_sequence_f[] = { #endif INIT_FUNC_WATCHDOG_RESET reloc_fdt, + reloc_bootstage, setup_reloc, #if defined(CONFIG_X86) || defined(CONFIG_ARC) copy_uboot_to_ram, diff --git a/common/board_r.c b/common/board_r.c index 00ba319..15977e4 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -11,6 +11,7 @@ */ #include <common.h> +#include <api.h> /* TODO: can we just include all these headers whether needed or not? */ #if defined(CONFIG_CMD_BEDBUG) #include <bedbug/type.h> @@ -296,8 +297,15 @@ static int initr_noncached(void) #ifdef CONFIG_OF_LIVE static int initr_of_live(void) { - return of_live_build(gd->fdt_blob, - (struct device_node **)&gd->of_root); + int ret; + + bootstage_start(BOOTSTAGE_ID_ACCUM_OF_LIVE, "of_live"); + ret = of_live_build(gd->fdt_blob, (struct device_node **)&gd->of_root); + bootstage_accum(BOOTSTAGE_ID_ACCUM_OF_LIVE); + if (ret) + return ret; + + return 0; } #endif @@ -312,7 +320,9 @@ static int initr_dm(void) #ifdef CONFIG_TIMER gd->timer = NULL; #endif + bootstage_start(BOOTSTATE_ID_ACCUM_DM_R, "dm_r"); ret = dm_init_and_scan(false); + bootstage_accum(BOOTSTATE_ID_ACCUM_DM_R); if (ret) return ret; #ifdef CONFIG_TIMER_EARLY @@ -327,7 +337,6 @@ static int initr_dm(void) static int initr_bootstage(void) { - /* We cannot do this before initr_dm() */ bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r"); return 0; @@ -726,6 +735,7 @@ static init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, + initr_bootstage, /* Needs malloc() but has its own timer */ initr_console_record, #ifdef CONFIG_SYS_NONCACHED_MEMORY initr_noncached, @@ -737,7 +747,6 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_DM initr_dm, #endif - initr_bootstage, #if defined(CONFIG_ARM) || defined(CONFIG_NDS32) board_init, /* Setup chipselects */ #endif diff --git a/common/bootstage.c b/common/bootstage.c index 35bce3d..61479d7 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -8,8 +8,6 @@ /* * This module records the progress of boot and arbitrary commands, and * permits accurate timestamping of each. - * - * TBD: Pass timings to kernel in the FDT */ #include <common.h> @@ -19,6 +17,10 @@ DECLARE_GLOBAL_DATA_PTR; +enum { + RECORD_COUNT = CONFIG_BOOTSTAGE_RECORD_COUNT, +}; + struct bootstage_record { ulong time_us; uint32_t start_us; @@ -27,8 +29,11 @@ struct bootstage_record { enum bootstage_id id; }; -static struct bootstage_record record[BOOTSTAGE_ID_COUNT] = { {1} }; -static int next_id = BOOTSTAGE_ID_USER; +struct bootstage_data { + uint rec_count; + uint next_id; + struct bootstage_record record[RECORD_COUNT]; +}; enum { BOOTSTAGE_VERSION = 0, @@ -45,41 +50,72 @@ struct bootstage_hdr { int bootstage_relocate(void) { + struct bootstage_data *data = gd->bootstage; int i; /* * Duplicate all strings. They may point to an old location in the * program .text section that can eventually get trashed. */ - for (i = 0; i < BOOTSTAGE_ID_COUNT; i++) - if (record[i].name) - record[i].name = strdup(record[i].name); + debug("Relocating %d records\n", data->rec_count); + for (i = 0; i < data->rec_count; i++) + data->record[i].name = strdup(data->record[i].name); return 0; } +struct bootstage_record *find_id(struct bootstage_data *data, + enum bootstage_id id) +{ + struct bootstage_record *rec; + struct bootstage_record *end; + + for (rec = data->record, end = rec + data->rec_count; rec < end; + rec++) { + if (rec->id == id) + return rec; + } + + return NULL; +} + +struct bootstage_record *ensure_id(struct bootstage_data *data, + enum bootstage_id id) +{ + struct bootstage_record *rec; + + rec = find_id(data, id); + if (!rec && data->rec_count < RECORD_COUNT) { + rec = &data->record[data->rec_count++]; + rec->id = id; + return rec; + } + + return rec; +} + ulong bootstage_add_record(enum bootstage_id id, const char *name, int flags, ulong mark) { + struct bootstage_data *data = gd->bootstage; struct bootstage_record *rec; if (flags & BOOTSTAGEF_ALLOC) - id = next_id++; - - if (id < BOOTSTAGE_ID_COUNT) { - rec = &record[id]; - - /* Only record the first event for each */ - if (!rec->time_us) { - rec->time_us = mark; - rec->name = name; - rec->flags = flags; - rec->id = id; - } + id = data->next_id++; + + /* Only record the first event for each */ + rec = find_id(data, id); + if (!rec && data->rec_count < RECORD_COUNT) { + rec = &data->record[data->rec_count++]; + rec->time_us = mark; + rec->name = name; + rec->flags = flags; + rec->id = id; } /* Tell the board about this progress */ show_boot_progress(flags & BOOTSTAGEF_ERROR ? -id : id); + return mark; } @@ -101,6 +137,7 @@ ulong bootstage_mark_name(enum bootstage_id id, const char *name) if (id == BOOTSTAGE_ID_ALLOC) flags = BOOTSTAGEF_ALLOC; + return bootstage_add_record(id, name, flags, timer_get_boot_us()); } @@ -133,20 +170,29 @@ ulong bootstage_mark_code(const char *file, const char *func, int linenum) uint32_t bootstage_start(enum bootstage_id id, const char *name) { - struct bootstage_record *rec = &record[id]; + struct bootstage_data *data = gd->bootstage; + struct bootstage_record *rec = ensure_id(data, id); + ulong start_us = timer_get_boot_us(); + + if (rec) { + rec->start_us = start_us; + rec->name = name; + } - rec->start_us = timer_get_boot_us(); - rec->name = name; - return rec->start_us; + return start_us; } uint32_t bootstage_accum(enum bootstage_id id) { - struct bootstage_record *rec = &record[id]; + struct bootstage_data *data = gd->bootstage; + struct bootstage_record *rec = ensure_id(data, id); uint32_t duration; + if (!rec) + return 0; duration = (uint32_t)timer_get_boot_us() - rec->start_us; rec->time_us += duration; + return duration; } @@ -159,7 +205,7 @@ uint32_t bootstage_accum(enum bootstage_id id) * @return pointer to name, either from the record or pointing to buf. */ static const char *get_record_name(char *buf, int len, - struct bootstage_record *rec) + const struct bootstage_record *rec) { if (rec->name) return rec->name; @@ -171,8 +217,7 @@ static const char *get_record_name(char *buf, int len, return buf; } -static uint32_t print_time_record(enum bootstage_id id, - struct bootstage_record *rec, uint32_t prev) +static uint32_t print_time_record(struct bootstage_record *rec, uint32_t prev) { char buf[20]; @@ -204,9 +249,10 @@ static int h_compare_record(const void *r1, const void *r2) */ static int add_bootstages_devicetree(struct fdt_header *blob) { + struct bootstage_data *data = gd->bootstage; int bootstage; char buf[20]; - int id; + int recnum; int i; if (!blob) @@ -218,17 +264,17 @@ static int add_bootstages_devicetree(struct fdt_header *blob) */ bootstage = fdt_add_subnode(blob, 0, "bootstage"); if (bootstage < 0) - return -1; + return -EINVAL; /* * Insert the timings to the device tree in the reverse order so * that they can be printed in the Linux kernel in the right order. */ - for (id = BOOTSTAGE_ID_COUNT - 1, i = 0; id >= 0; id--, i++) { - struct bootstage_record *rec = &record[id]; + for (recnum = data->rec_count - 1, i = 0; recnum >= 0; recnum--, i++) { + struct bootstage_record *rec = &data->record[recnum]; int node; - if (id != BOOTSTAGE_ID_AWAKE && rec->time_us == 0) + if (rec->id != BOOTSTAGE_ID_AWAKE && rec->time_us == 0) continue; node = fdt_add_subnode(blob, bootstage, simple_itoa(i)); @@ -237,14 +283,14 @@ static int add_bootstages_devicetree(struct fdt_header *blob) /* add properties to the node. */ if (fdt_setprop_string(blob, node, "name", - get_record_name(buf, sizeof(buf), rec))) - return -1; + get_record_name(buf, sizeof(buf), rec))) + return -EINVAL; /* Check if this is a 'mark' or 'accum' record */ if (fdt_setprop_cell(blob, node, rec->start_us ? "accum" : "mark", rec->time_us)) - return -1; + return -EINVAL; } return 0; @@ -261,54 +307,36 @@ int bootstage_fdt_add_report(void) void bootstage_report(void) { - struct bootstage_record *rec = record; - int id; + struct bootstage_data *data = gd->bootstage; + struct bootstage_record *rec = data->record; uint32_t prev; + int i; - puts("Timer summary in microseconds:\n"); + printf("Timer summary in microseconds (%d records):\n", + data->rec_count); printf("%11s%11s %s\n", "Mark", "Elapsed", "Stage"); - /* Fake the first record - we could get it from early boot */ - rec->name = "reset"; - rec->time_us = 0; - prev = print_time_record(BOOTSTAGE_ID_AWAKE, rec, 0); + prev = print_time_record(rec, 0); /* Sort records by increasing time */ - qsort(record, ARRAY_SIZE(record), sizeof(*rec), h_compare_record); + qsort(data->record, data->rec_count, sizeof(*rec), h_compare_record); - for (id = 0; id < BOOTSTAGE_ID_COUNT; id++, rec++) { - if (rec->time_us != 0 && !rec->start_us) - prev = print_time_record(rec->id, rec, prev); + for (i = 1, rec++; i < data->rec_count; i++, rec++) { + if (rec->id && !rec->start_us) + prev = print_time_record(rec, prev); } - if (next_id > BOOTSTAGE_ID_COUNT) - printf("(Overflowed internal boot id table by %d entries\n" - "- please increase CONFIG_BOOTSTAGE_USER_COUNT\n", - next_id - BOOTSTAGE_ID_COUNT); + if (data->rec_count > RECORD_COUNT) + printf("Overflowed internal boot id table by %d entries\n" + "- please increase CONFIG_BOOTSTAGE_RECORD_COUNT\n", + data->rec_count - RECORD_COUNT); puts("\nAccumulated time:\n"); - for (id = 0, rec = record; id < BOOTSTAGE_ID_COUNT; id++, rec++) { + for (i = 0, rec = data->record; i < data->rec_count; i++, rec++) { if (rec->start_us) - prev = print_time_record(id, rec, -1); + prev = print_time_record(rec, -1); } } -ulong __timer_get_boot_us(void) -{ - static ulong base_time; - - /* - * We can't implement this properly. Return 0 on the first call and - * larger values after that. - */ - if (base_time) - return get_timer(base_time) * 1000; - base_time = get_timer(0); - return 0; -} - -ulong timer_get_boot_us(void) - __attribute__((weak, alias("__timer_get_boot_us"))); - /** * Append data to a memory buffer * @@ -333,25 +361,26 @@ static void append_data(char **ptrp, char *end, const void *data, int size) int bootstage_stash(void *base, int size) { + const struct bootstage_data *data = gd->bootstage; struct bootstage_hdr *hdr = (struct bootstage_hdr *)base; - struct bootstage_record *rec; + const struct bootstage_record *rec; char buf[20]; char *ptr = base, *end = ptr + size; uint32_t count; - int id; + int i; if (hdr + 1 > (struct bootstage_hdr *)end) { debug("%s: Not enough space for bootstage hdr\n", __func__); - return -1; + return -ENOSPC; } /* Write an arbitrary version number */ hdr->version = BOOTSTAGE_VERSION; /* Count the number of records, and write that value first */ - for (rec = record, id = count = 0; id < BOOTSTAGE_ID_COUNT; - id++, rec++) { - if (rec->time_us != 0) + for (rec = data->record, i = count = 0; i < data->rec_count; + i++, rec++) { + if (rec->id != 0) count++; } hdr->count = count; @@ -360,89 +389,88 @@ int bootstage_stash(void *base, int size) ptr += sizeof(*hdr); /* Write the records, silently stopping when we run out of space */ - for (rec = record, id = 0; id < BOOTSTAGE_ID_COUNT; id++, rec++) { - if (rec->time_us != 0) - append_data(&ptr, end, rec, sizeof(*rec)); + for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) { + append_data(&ptr, end, rec, sizeof(*rec)); } /* Write the name strings */ - for (rec = record, id = 0; id < BOOTSTAGE_ID_COUNT; id++, rec++) { - if (rec->time_us != 0) { - const char *name; + for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) { + const char *name; - name = get_record_name(buf, sizeof(buf), rec); - append_data(&ptr, end, name, strlen(name) + 1); - } + name = get_record_name(buf, sizeof(buf), rec); + append_data(&ptr, end, name, strlen(name) + 1); } /* Check for buffer overflow */ if (ptr > end) { debug("%s: Not enough space for bootstage stash\n", __func__); - return -1; + return -ENOSPC; } /* Update total data size */ hdr->size = ptr - (char *)base; - printf("Stashed %d records\n", hdr->count); + debug("Stashed %d records\n", hdr->count); return 0; } -int bootstage_unstash(void *base, int size) +int bootstage_unstash(const void *base, int size) { - struct bootstage_hdr *hdr = (struct bootstage_hdr *)base; + const struct bootstage_hdr *hdr = (struct bootstage_hdr *)base; + struct bootstage_data *data = gd->bootstage; + const char *ptr = base, *end = ptr + size; struct bootstage_record *rec; - char *ptr = base, *end = ptr + size; uint rec_size; - int id; + int i; if (size == -1) end = (char *)(~(uintptr_t)0); if (hdr + 1 > (struct bootstage_hdr *)end) { debug("%s: Not enough space for bootstage hdr\n", __func__); - return -1; + return -EPERM; } if (hdr->magic != BOOTSTAGE_MAGIC) { debug("%s: Invalid bootstage magic\n", __func__); - return -1; + return -ENOENT; } if (ptr + hdr->size > end) { debug("%s: Bootstage data runs past buffer end\n", __func__); - return -1; + return -ENOSPC; } if (hdr->count * sizeof(*rec) > hdr->size) { debug("%s: Bootstage has %d records needing %lu bytes, but " "only %d bytes is available\n", __func__, hdr->count, (ulong)hdr->count * sizeof(*rec), hdr->size); - return -1; + return -ENOSPC; } if (hdr->version != BOOTSTAGE_VERSION) { debug("%s: Bootstage data version %#0x unrecognised\n", __func__, hdr->version); - return -1; + return -EINVAL; } - if (next_id + hdr->count > BOOTSTAGE_ID_COUNT) { + if (data->rec_count + hdr->count > RECORD_COUNT) { debug("%s: Bootstage has %d records, we have space for %d\n" "- please increase CONFIG_BOOTSTAGE_USER_COUNT\n", - __func__, hdr->count, BOOTSTAGE_ID_COUNT - next_id); - return -1; + __func__, hdr->count, RECORD_COUNT - data->rec_count); + return -ENOSPC; } ptr += sizeof(*hdr); /* Read the records */ - rec_size = hdr->count * sizeof(*record); - memcpy(record + next_id, ptr, rec_size); + rec_size = hdr->count * sizeof(*data->record); + memcpy(data->record + data->rec_count, ptr, rec_size); /* Read the name strings */ ptr += rec_size; - for (rec = record + next_id, id = 0; id < hdr->count; id++, rec++) { + for (rec = data->record + data->next_id, i = 0; i < hdr->count; + i++, rec++) { rec->name = ptr; /* Assume no data corruption here */ @@ -450,8 +478,31 @@ int bootstage_unstash(void *base, int size) } /* Mark the records as read */ - next_id += hdr->count; - printf("Unstashed %d records\n", hdr->count); + data->rec_count += hdr->count; + debug("Unstashed %d records\n", hdr->count); + + return 0; +} + +int bootstage_get_size(void) +{ + return sizeof(struct bootstage_data); +} + +int bootstage_init(bool first) +{ + struct bootstage_data *data; + int size = sizeof(struct bootstage_data); + + gd->bootstage = (struct bootstage_data *)malloc(size); + if (!gd->bootstage) + return -ENOMEM; + data = gd->bootstage; + memset(data, '\0', size); + if (first) { + data->next_id = BOOTSTAGE_ID_USER; + bootstage_add_record(BOOTSTAGE_ID_AWAKE, "reset", 0, 0); + } return 0; } diff --git a/common/dlmalloc.c b/common/dlmalloc.c index adc680e..fc1e8b3 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -1,6 +1,6 @@ #include <common.h> -#ifdef CONFIG_SANDBOX +#if defined(CONFIG_UNIT_TEST) #define DEBUG #endif diff --git a/common/spl/Kconfig b/common/spl/Kconfig index eabb2d0..732690c 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -16,8 +16,9 @@ config SPL help If you want to build SPL as well as the normal image, say Y. +if SPL + config SPL_BOARD_INIT - depends on SPL bool "Call board-specific initialization in SPL" help If this option is enabled, U-Boot will call the function @@ -26,7 +27,6 @@ config SPL_BOARD_INIT config SPL_RAW_IMAGE_SUPPORT bool "Support SPL loading and booting of RAW images" - depends on SPL default n if (ARCH_MX6 && (SPL_MMC_SUPPORT || SPL_SATA_SUPPORT)) default y if !TI_SECURE_DEVICE help @@ -44,7 +44,6 @@ config SPL_LEGACY_IMAGE_SUPPORT config SPL_SYS_MALLOC_SIMPLE bool - depends on SPL prompt "Only use malloc_simple functions in the SPL" help Say Y here to only use the *_simple malloc functions from @@ -53,7 +52,6 @@ config SPL_SYS_MALLOC_SIMPLE usage as the *_simple malloc functions do not re-use free-ed mem. config SPL_STACK_R - depends on SPL bool "Enable SDRAM location for SPL stack" help SPL starts off execution in SRAM and thus typically has only a small @@ -81,7 +79,6 @@ config SPL_STACK_R_MALLOC_SIMPLE_LEN SRAM which is limited to SYS_MALLOC_F_LEN bytes. config SPL_SEPARATE_BSS - depends on SPL bool "BSS section is in a different memory region from text" help Some platforms need a large BSS region in SPL and can provide this @@ -91,7 +88,6 @@ config SPL_SEPARATE_BSS but with this option enabled, it goes at _image_binary_end. config SPL_DISPLAY_PRINT - depends on SPL bool "Display a board-specific message in SPL" help If this option is enabled, U-Boot will call the function @@ -101,7 +97,6 @@ config SPL_DISPLAY_PRINT config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR bool "MMC raw mode: by sector" - depends on SPL default y if ARCH_SUNXI || ARCH_DAVINCI || ARCH_UNIPHIER ||ARCH_MX6 || \ ARCH_ROCKCHIP || ARCH_MVEBU || ARCH_SOCFPGA || \ ARCH_AT91 || ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || \ @@ -112,7 +107,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR hex "Address on the MMC to load U-Boot from" - depends on SPL && SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR + depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR default 0x50 if ARCH_SUNXI default 0x75 if ARCH_DAVINCI default 0x8a if ARCH_MX6 @@ -127,13 +122,12 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION bool "MMC Raw mode: by partition" - depends on SPL help Use a partition for loading U-Boot when using MMC/SD in raw mode. config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION hex "Partition to use to load U-Boot from" - depends on SPL && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION + depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION default 1 help Partition on the MMC to load U-Boot from when the MMC is being @@ -141,8 +135,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE bool "MMC raw mode: by partition type" - depends on SPL && DOS_PARTITION && \ - SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION + depends on DOS_PARTITION && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION help Use partition type for specifying U-Boot partition on MMC/SD in raw mode. U-Boot will be loaded from the first partition of this @@ -150,18 +143,11 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE config SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE hex "Partition Type on the MMC to load U-Boot from" - depends on SPL && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE + depends on SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE help Partition Type on the MMC to load U-Boot from, when the MMC is being used in raw mode. -config TPL - bool - depends on SPL && SUPPORT_TPL - prompt "Enable TPL" - help - If you want to build TPL as well as the normal image and SPL, say Y. - config SPL_CRC32_SUPPORT bool "Support CRC32" depends on SPL_FIT @@ -212,7 +198,6 @@ config SPL_SHA256_SUPPORT config SPL_CPU_SUPPORT bool "Support CPU drivers" - depends on SPL help Enable this to support CPU drivers in SPL. These drivers can set up CPUs and provide information about them such as the model and @@ -222,7 +207,6 @@ config SPL_CPU_SUPPORT config SPL_CRYPTO_SUPPORT bool "Support crypto drivers" - depends on SPL help Enable crypto drivers in SPL. These drivers can be used to accelerate secure boot processing in secure applications. Enable @@ -233,7 +217,6 @@ config SPL_HASH_SUPPORT bool "Support hashing drivers" select SHA1 select SHA256 - depends on SPL help Enable hashing drivers in SPL. These drivers can be used to accelerate secure boot processing in secure applications. Enable @@ -242,7 +225,6 @@ config SPL_HASH_SUPPORT config SPL_DMA_SUPPORT bool "Support DMA drivers" - depends on SPL help Enable DMA (direct-memory-access) drivers in SPL. These drivers can be used to handle memory-to-peripheral data transfer without @@ -251,7 +233,6 @@ config SPL_DMA_SUPPORT config SPL_DRIVERS_MISC_SUPPORT bool "Support misc drivers" - depends on SPL help Enable miscellaneous drivers in SPL. These drivers perform various tasks that don't fall nicely into other categories, Enable this @@ -260,7 +241,6 @@ config SPL_DRIVERS_MISC_SUPPORT config SPL_ENV_SUPPORT bool "Support an environment" - depends on SPL help Enable environment support in SPL. The U-Boot environment provides a number of settings (essentially name/value pairs) which can @@ -273,7 +253,7 @@ config SPL_ENV_SUPPORT config SPL_SAVEENV bool "Support save environment" - depends on SPL && SPL_ENV_SUPPORT + depends on SPL_ENV_SUPPORT help Enable save environment support in SPL after setenv. By default the saveenv option is not provided in SPL, but some boards need @@ -296,7 +276,6 @@ config SPL_ETH_SUPPORT config SPL_EXT_SUPPORT bool "Support EXT filesystems" - depends on SPL help Enable support for EXT2/3/4 filesystems with SPL. This permits U-Boot (or Linux in Falcon mode) to be loaded from an EXT @@ -305,7 +284,7 @@ config SPL_EXT_SUPPORT config SPL_FAT_SUPPORT bool "Support FAT filesystems" - depends on SPL + select FS_FAT help Enable support for FAT and VFAT filesystems with SPL. This permits U-Boot (or Linux in Falcon mode) to be loaded from a FAT @@ -314,7 +293,6 @@ config SPL_FAT_SUPPORT config SPL_FPGA_SUPPORT bool "Support FPGAs" - depends on SPL help Enable support for FPGAs in SPL. Field-programmable Gate Arrays provide software-configurable hardware which is typically used to @@ -326,7 +304,6 @@ config SPL_FPGA_SUPPORT config SPL_GPIO_SUPPORT bool "Support GPIO" - depends on SPL help Enable support for GPIOs (General-purpose Input/Output) in SPL. GPIOs allow U-Boot to read the state of an input line (high or @@ -338,7 +315,6 @@ config SPL_GPIO_SUPPORT config SPL_I2C_SUPPORT bool "Support I2C" - depends on SPL help Enable support for the I2C (Inter-Integrated Circuit) bus in SPL. I2C works with a clock and data line which can be driven by a @@ -352,7 +328,6 @@ config SPL_I2C_SUPPORT config SPL_LIBCOMMON_SUPPORT bool "Support common libraries" - depends on SPL help Enable support for common U-Boot libraries within SPL. These libraries include common code to deal with U-Boot images, @@ -362,7 +337,6 @@ config SPL_LIBCOMMON_SUPPORT config SPL_LIBDISK_SUPPORT bool "Support disk paritions" - depends on SPL help Enable support for disk partitions within SPL. 'Disk' is something of a misnomer as it includes non-spinning media such as flash (as @@ -376,7 +350,6 @@ config SPL_LIBDISK_SUPPORT config SPL_LIBGENERIC_SUPPORT bool "Support generic libraries" - depends on SPL help Enable support for generic U-Boot libraries within SPL. These libraries include generic code to deal with device tree, hashing, @@ -386,7 +359,7 @@ config SPL_LIBGENERIC_SUPPORT config SPL_MMC_SUPPORT bool "Support MMC" - depends on SPL && MMC + depends on MMC help Enable support for MMC (Multimedia Card) within SPL. This enables the MMC protocol implementation and allows any enabled drivers to @@ -397,7 +370,6 @@ config SPL_MMC_SUPPORT config SPL_MPC8XXX_INIT_DDR_SUPPORT bool "Support MPC8XXX DDR init" - depends on SPL help Enable support for DDR-SDRAM (double-data-rate synchronous dynamic random-access memory) on the MPC8XXX family within SPL. This @@ -406,7 +378,6 @@ config SPL_MPC8XXX_INIT_DDR_SUPPORT config SPL_MTD_SUPPORT bool "Support MTD drivers" - depends on SPL help Enable support for MTD (Memory Technology Device) within SPL. MTD provides a block interface over raw NAND and can also be used with @@ -416,7 +387,6 @@ config SPL_MTD_SUPPORT config SPL_MUSB_NEW_SUPPORT bool "Support new Mentor Graphics USB" - depends on SPL help Enable support for Mentor Graphics USB in SPL. This is a new driver used by some boards. Enable this option to build @@ -425,7 +395,6 @@ config SPL_MUSB_NEW_SUPPORT config SPL_NAND_SUPPORT bool "Support NAND flash" - depends on SPL help Enable support for NAND (Negative AND) flash in SPL. NAND flash can be used to allow SPL to load U-Boot from supported devices. @@ -434,7 +403,6 @@ config SPL_NAND_SUPPORT config SPL_NET_SUPPORT bool "Support networking" - depends on SPL help Enable support for network devices (such as Ethernet) in SPL. This permits SPL to load U-Boot over a network link rather than @@ -455,7 +423,6 @@ endif # if SPL_NET_SUPPORT config SPL_NO_CPU_SUPPORT bool "Drop CPU code in SPL" - depends on SPL help This is specific to the ARM926EJ-S CPU. It disables the standard start.S start-up code, presumably so that a replacement can be @@ -464,7 +431,6 @@ config SPL_NO_CPU_SUPPORT config SPL_NOR_SUPPORT bool "Support NOR flash" - depends on SPL help Enable support for loading U-Boot from memory-mapped NOR (Negative OR) flash in SPL. NOR flash is slow to write but fast to read, and @@ -473,7 +439,6 @@ config SPL_NOR_SUPPORT config SPL_ONENAND_SUPPORT bool "Support OneNAND flash" - depends on SPL help Enable support for OneNAND (Negative AND) flash in SPL. OneNAND is a type of NAND flash and therefore can be used to allow SPL to @@ -482,7 +447,7 @@ config SPL_ONENAND_SUPPORT config SPL_OS_BOOT bool "Activate Falcon Mode" - depends on SPL && !TI_SECURE_DEVICE + depends on !TI_SECURE_DEVICE default n help Enable booting directly to an OS from SPL. @@ -491,7 +456,7 @@ config SPL_OS_BOOT if SPL_OS_BOOT config SYS_OS_BASE hex "addr, where OS is found" - depends on SPL && SPL_NOR_SUPPORT + depends on SPL_NOR_SUPPORT help Specify the address, where the OS image is found, which gets booted. @@ -500,7 +465,6 @@ endif # SPL_OS_BOOT config SPL_PCI_SUPPORT bool "Support PCI drivers" - depends on SPL help Enable support for PCI in SPL. For platforms that need PCI to boot, or must perform some init using PCI in SPL, this provides the @@ -509,7 +473,6 @@ config SPL_PCI_SUPPORT config SPL_PCH_SUPPORT bool "Support PCH drivers" - depends on SPL help Enable support for PCH (Platform Controller Hub) devices in SPL. These are used to set up GPIOs and the SPI peripheral early in @@ -518,7 +481,6 @@ config SPL_PCH_SUPPORT config SPL_POST_MEM_SUPPORT bool "Support POST drivers" - depends on SPL help Enable support for POST (Power-on Self Test) in SPL. POST is a procedure that checks that the hardware (CPU or board) appears to @@ -528,7 +490,6 @@ config SPL_POST_MEM_SUPPORT config SPL_POWER_SUPPORT bool "Support power drivers" - depends on SPL help Enable support for power control in SPL. This includes support for PMICs (Power-management Integrated Circuits) and some of the @@ -541,7 +502,6 @@ config SPL_POWER_SUPPORT config SPL_RAM_SUPPORT bool "Support booting from RAM" - depends on SPL default y if MICROBLAZE || ARCH_SOCFPGA || TEGRA || ARCH_ZYNQ help Enable booting of an image in RAM. The image can be preloaded or @@ -558,7 +518,6 @@ config SPL_RAM_DEVICE config SPL_RTC_SUPPORT bool "Support RTC drivers" - depends on SPL help Enable RTC (Real-time Clock) support in SPL. This includes support for reading and setting the time. Some RTC devices also have some @@ -568,7 +527,6 @@ config SPL_RTC_SUPPORT config SPL_SATA_SUPPORT bool "Support loading from SATA" - depends on SPL help Enable support for SATA (Serial AT attachment) in SPL. This allows use of SATA devices such as hard drives and flash drivers for @@ -579,7 +537,6 @@ config SPL_SATA_SUPPORT config SPL_SERIAL_SUPPORT bool "Support serial" - depends on SPL help Enable support for serial in SPL. This allows use of a serial UART for displaying messages while SPL is running. It also brings in @@ -589,7 +546,6 @@ config SPL_SERIAL_SUPPORT config SPL_SPI_FLASH_SUPPORT bool "Support SPI flash drivers" - depends on SPL help Enable support for using SPI flash in SPL, and loading U-Boot from SPI flash. SPI flash (Serial Peripheral Bus flash) is named after @@ -600,7 +556,6 @@ config SPL_SPI_FLASH_SUPPORT config SPL_SPI_SUPPORT bool "Support SPI drivers" - depends on SPL help Enable support for using SPI in SPL. This is used for connecting to SPI flash for loading U-Boot. See SPL_SPI_FLASH_SUPPORT for @@ -611,7 +566,6 @@ config SPL_SPI_SUPPORT config SPL_TIMER_SUPPORT bool "Support timer drivers" - depends on SPL help Enable support for timer drivers in SPL. These can be used to get a timer value when in SPL, or perhaps for implementing a delay @@ -620,7 +574,6 @@ config SPL_TIMER_SUPPORT config SPL_USB_HOST_SUPPORT bool "Support USB host drivers" - depends on SPL help Enable access to USB (Universal Serial Bus) host devices so that SPL can load U-Boot from a connected USB peripheral, such as a USB @@ -641,7 +594,6 @@ config SPL_USB_SUPPORT config SPL_USB_GADGET_SUPPORT bool "Suppport USB Gadget drivers" - depends on SPL help Enable USB Gadget API which allows to enable USB device functions in SPL. @@ -689,7 +641,6 @@ endif config SPL_WATCHDOG_SUPPORT bool "Support watchdog drivers" - depends on SPL help Enable support for watchdog drivers in SPL. A watchdog is typically a hardware peripheral which can reset the system when it @@ -698,7 +649,6 @@ config SPL_WATCHDOG_SUPPORT config SPL_YMODEM_SUPPORT bool "Support loading using Ymodem" - depends on SPL help While loading from serial is slow it can be a useful backup when there is no other option. The Ymodem protocol provides a reliable @@ -707,7 +657,7 @@ config SPL_YMODEM_SUPPORT config SPL_ATF_SUPPORT bool "Support ARM Trusted Firmware" - depends on SPL && ARM64 + depends on ARM64 help ATF(ARM Trusted Firmware) is a component for ARM arch64 which which is loaded by SPL(which is considered as BL2 in ATF terminology). @@ -719,71 +669,74 @@ config SPL_ATF_TEXT_BASE help This is the base address in memory for ATF BL31 text and entry point. +config TPL + bool + depends on SUPPORT_TPL + prompt "Enable TPL" + help + If you want to build TPL as well as the normal image and SPL, say Y. + +if TPL + config TPL_ENV_SUPPORT bool "Support an environment" - depends on TPL help Enable environment support in TPL. See SPL_ENV_SUPPORT for details. config TPL_I2C_SUPPORT bool "Support I2C" - depends on TPL help Enable support for the I2C bus in SPL. See SPL_I2C_SUPPORT for details. config TPL_LIBCOMMON_SUPPORT bool "Support common libraries" - depends on TPL help Enable support for common U-Boot libraries within TPL. See SPL_LIBCOMMON_SUPPORT for details. config TPL_LIBGENERIC_SUPPORT bool "Support generic libraries" - depends on TPL help Enable support for generic U-Boot libraries within TPL. See SPL_LIBGENERIC_SUPPORT for details. config TPL_MPC8XXX_INIT_DDR_SUPPORT bool "Support MPC8XXX DDR init" - depends on TPL help Enable support for DDR-SDRAM on the MPC8XXX family within TPL. See SPL_MPC8XXX_INIT_DDR_SUPPORT for details. config TPL_MMC_SUPPORT bool "Support MMC" - depends on TPL && MMC + depends on MMC help Enable support for MMC within TPL. See SPL_MMC_SUPPORT for details. config TPL_NAND_SUPPORT bool "Support NAND flash" - depends on TPL help Enable support for NAND in SPL. See SPL_NAND_SUPPORT for details. config TPL_SERIAL_SUPPORT bool "Support serial" - depends on TPL help Enable support for serial in SPL. See SPL_SERIAL_SUPPORT for details. config TPL_SPI_FLASH_SUPPORT bool "Support SPI flash drivers" - depends on TPL help Enable support for using SPI flash in SPL. See SPL_SPI_FLASH_SUPPORT for details. config TPL_SPI_SUPPORT bool "Support SPI drivers" - depends on TPL help Enable support for using SPI in SPL. See SPL_SPI_SUPPORT for details. +endif # TPL + +endif # SPL endmenu diff --git a/common/spl/spl.c b/common/spl/spl.c index 0a49766..f493a3a 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -232,6 +232,13 @@ static int spl_common_init(bool setup_malloc) gd->malloc_ptr = 0; } #endif + ret = bootstage_init(true); + if (ret) { + debug("%s: Failed to set up bootstage: ret=%d\n", __func__, + ret); + return ret; + } + bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) { ret = fdtdec_setup(); if (ret) { @@ -240,8 +247,10 @@ static int spl_common_init(bool setup_malloc) } } if (IS_ENABLED(CONFIG_SPL_DM)) { + bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, "dm_spl"); /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); + bootstage_accum(BOOTSTATE_ID_ACCUM_DM_SPL); if (ret) { debug("dm_init_and_scan() returned error %d\n", ret); return ret; @@ -421,6 +430,15 @@ void board_init_r(gd_t *dummy1, ulong dummy2) } debug("loaded - jumping to U-Boot...\n"); +#ifdef CONFIG_BOOTSTAGE_STASH + int ret; + + bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); + ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, + CONFIG_BOOTSTAGE_STASH_SIZE); + if (ret) + debug("Failed to stash bootstage: err=%d\n", ret); +#endif spl_board_prepare_for_boot(); jump_to_image_no_args(&spl_image); } |