summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig20
-rw-r--r--common/Makefile3
-rw-r--r--common/board_f.c82
-rw-r--r--common/board_r.c31
-rw-r--r--common/bootm_os.c14
-rw-r--r--common/bootstage.c257
-rw-r--r--common/dlmalloc.c2
-rw-r--r--common/edid.c6
-rw-r--r--common/env_mmc.c7
-rw-r--r--common/fb_mmc.c168
-rw-r--r--common/lcd.c4
-rw-r--r--common/lynxkdi.c2
-rw-r--r--common/spl/Kconfig105
-rw-r--r--common/spl/Makefile1
-rw-r--r--common/spl/spl.c24
-rw-r--r--common/spl/spl_xip.c28
16 files changed, 517 insertions, 237 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 5c39663f56..27dde11b14 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
@@ -448,7 +464,7 @@ config BOARD_LATE_INIT
config DISPLAY_CPUINFO
bool "Display information about the CPU during start up"
- default y if ARM || NIOS2 || X86 || XTENSA || MPC5xxx
+ default y if ARM || NIOS2 || X86 || XTENSA
help
Display information about the CPU that U-Boot is running on
when U-Boot starts up. The function print_cpuinfo() is called
diff --git a/common/Makefile b/common/Makefile
index c7c8ea42c6..539cf98e19 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 a212f2b539..850d19db75 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
@@ -384,7 +387,7 @@ static int reserve_video(void)
gd->fb_base = gd->relocaddr;
# endif /* CONFIG_FB_ADDR */
#elif defined(CONFIG_VIDEO) && \
- (!defined(CONFIG_PPC) || defined(CONFIG_8xx)) && \
+ (!defined(CONFIG_PPC)) && \
!defined(CONFIG_ARM) && !defined(CONFIG_X86) && \
!defined(CONFIG_M68K)
/* reserve memory for video display (always full pages) */
@@ -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;
@@ -530,11 +547,10 @@ static int setup_board_part1(void)
bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */
#endif
-#if defined(CONFIG_8xx) || defined(CONFIG_MPC8260) || defined(CONFIG_5xx) || \
- defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+#if defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
bd->bi_immr_base = CONFIG_SYS_IMMR; /* base of IMMR register */
#endif
-#if defined(CONFIG_MPC5xxx) || defined(CONFIG_M68K)
+#if defined(CONFIG_M68K)
bd->bi_mbar_base = CONFIG_SYS_MBAR; /* base of internal registers */
#endif
#if defined(CONFIG_MPC83xx)
@@ -558,13 +574,6 @@ static int setup_board_part2(void)
bd->bi_sccfreq = gd->arch.scc_clk;
bd->bi_vco = gd->arch.vco_out;
#endif /* CONFIG_CPM2 */
-#if defined(CONFIG_MPC512X)
- bd->bi_ipsfreq = gd->arch.ips_clk;
-#endif /* CONFIG_MPC512X */
-#if defined(CONFIG_MPC5xxx)
- bd->bi_ipbfreq = gd->arch.ipb_clk;
- bd->bi_pcifreq = gd->pci_clk;
-#endif /* CONFIG_MPC5xxx */
#if defined(CONFIG_M68K) && defined(CONFIG_PCI)
bd->bi_pcifreq = gd->pci_clk;
#endif
@@ -602,6 +611,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) {
@@ -610,13 +637,16 @@ static int setup_reloc(void)
}
#ifdef CONFIG_SYS_TEXT_BASE
- gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
-#ifdef CONFIG_M68K
+#ifdef ARM
+ gd->reloc_off = gd->relocaddr - (unsigned long)__image_copy_start;
+#elif defined(CONFIG_M68K)
/*
* On all ColdFire arch cpu, monitor code starts always
* just after the default vector table location, so at 0x400
*/
gd->reloc_off = gd->relocaddr - (CONFIG_SYS_TEXT_BASE + 0x400);
+#else
+ gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
#endif
#endif
memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
@@ -670,8 +700,26 @@ 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)
{
+ bool from_spl = IS_ENABLED(CONFIG_SPL_BOOTSTAGE) &&
+ IS_ENABLED(CONFIG_BOOTSTAGE_STASH);
+ 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 +739,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 +774,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 +783,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 +869,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 +891,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 00ba319ca7..adc1f1937e 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>
@@ -226,13 +227,6 @@ static int initr_post_backlog(void)
}
#endif
-#ifdef CONFIG_SYS_DELAYED_ICACHE
-static int initr_icache_enable(void)
-{
- return 0;
-}
-#endif
-
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
static int initr_unlock_ram_in_cache(void)
{
@@ -296,8 +290,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 +313,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 +330,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;
@@ -630,11 +632,7 @@ static int initr_pcmcia(void)
#if defined(CONFIG_IDE)
static int initr_ide(void)
{
-#ifdef CONFIG_IDE_8xx_PCCARD
- puts("PCMCIA:");
-#else
puts("IDE: ");
-#endif
#if defined(CONFIG_START_IDE)
if (board_start_ide())
ide_init();
@@ -726,6 +724,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 +736,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
@@ -777,9 +775,6 @@ static init_fnc_t init_sequence_r[] = {
initr_post_backlog,
#endif
INIT_FUNC_WATCHDOG_RESET
-#ifdef CONFIG_SYS_DELAYED_ICACHE
- initr_icache_enable,
-#endif
#if defined(CONFIG_PCI) && defined(CONFIG_SYS_EARLY_PCI_INIT)
/*
* Do early PCI configuration _before_ the flash gets initialised,
diff --git a/common/bootm_os.c b/common/bootm_os.c
index e102406976..d9e6e937f7 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -56,7 +56,6 @@ static int do_bootm_netbsd(int flag, int argc, char * const argv[],
void (*loader)(bd_t *, image_header_t *, char *, char *);
image_header_t *os_hdr, *hdr;
ulong kernel_data, kernel_len;
- char *consdev;
char *cmdline;
if (flag != BOOTM_STATE_OS_GO)
@@ -88,17 +87,6 @@ static int do_bootm_netbsd(int flag, int argc, char * const argv[],
os_hdr = hdr;
}
- consdev = "";
-#if defined(CONFIG_8xx_CONS_SMC1)
- consdev = "smc1";
-#elif defined(CONFIG_8xx_CONS_SMC2)
- consdev = "smc2";
-#elif defined(CONFIG_8xx_CONS_SCC2)
- consdev = "scc2";
-#elif defined(CONFIG_8xx_CONS_SCC3)
- consdev = "scc3";
-#endif
-
if (argc > 0) {
ulong len;
int i;
@@ -127,7 +115,7 @@ static int do_bootm_netbsd(int flag, int argc, char * const argv[],
* arg[2]: char pointer to the console device to use
* arg[3]: char pointer to the boot arguments
*/
- (*loader)(gd->bd, os_hdr, consdev, cmdline);
+ (*loader)(gd->bd, os_hdr, "", cmdline);
return 1;
}
diff --git a/common/bootstage.c b/common/bootstage.c
index 35bce3d881..61479d7f07 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 adc680e959..fc1e8b391c 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/edid.c b/common/edid.c
index 19410aa4fc..3d0809ad11 100644
--- a/common/edid.c
+++ b/common/edid.c
@@ -148,8 +148,8 @@ static bool cea_is_hdmi_vsdb_present(struct edid_cea861_info *info)
/* check for end of data block */
end = info->dtd_offset;
if (end == 0)
- end = 127;
- if (end < 4 || end > 127)
+ end = sizeof(info->data);
+ if (end < 4 || end > sizeof(info->data))
return false;
end -= 4;
@@ -295,7 +295,7 @@ static void edid_print_dtd(struct edid_monitor_descriptor *monitor,
h_total = h_active + h_blanking;
v_total = v_active + v_blanking;
- if (v_total * h_total)
+ if (v_total > 0 && h_total > 0)
vfreq = pixclock / (v_total * h_total);
else
vfreq = 1; /* Error case */
diff --git a/common/env_mmc.c b/common/env_mmc.c
index 404de85062..88b043ec35 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -121,7 +121,12 @@ static const char *init_mmc_for_env(struct mmc *mmc)
if (!mmc)
return "!No MMC card found";
-#ifndef CONFIG_BLK
+#ifdef CONFIG_BLK
+ struct udevice *dev;
+
+ if (blk_get_from_parent(mmc->dev, &dev))
+ return "!No block device";
+#else
if (mmc_init(mmc))
return "!MMC init failed";
#endif
diff --git a/common/fb_mmc.c b/common/fb_mmc.c
index 866982e41c..2113b6c372 100644
--- a/common/fb_mmc.c
+++ b/common/fb_mmc.c
@@ -13,6 +13,8 @@
#include <part.h>
#include <mmc.h>
#include <div64.h>
+#include <linux/compat.h>
+#include <android_image.h>
/*
* FIXME: Ensure we always set these names via Kconfig once xxx_PARTITION is
@@ -27,6 +29,8 @@
#define CONFIG_FASTBOOT_MBR_NAME "mbr"
#endif
+#define BOOT_PARTITION_NAME "boot"
+
struct fb_mmc_sparse {
struct blk_desc *dev_desc;
};
@@ -99,6 +103,163 @@ static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
fastboot_okay("");
}
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+/**
+ * Read Android boot image header from boot partition.
+ *
+ * @param[in] dev_desc MMC device descriptor
+ * @param[in] info Boot partition info
+ * @param[out] hdr Where to store read boot image header
+ *
+ * @return Boot image header sectors count or 0 on error
+ */
+static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
+ disk_partition_t *info,
+ struct andr_img_hdr *hdr)
+{
+ ulong sector_size; /* boot partition sector size */
+ lbaint_t hdr_sectors; /* boot image header sectors count */
+ int res;
+
+ /* Calculate boot image sectors count */
+ sector_size = info->blksz;
+ hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
+ if (hdr_sectors == 0) {
+ error("invalid number of boot sectors: 0");
+ fastboot_fail("invalid number of boot sectors: 0");
+ return 0;
+ }
+
+ /* Read the boot image header */
+ res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
+ if (res == 0) {
+ error("cannot read header from boot partition");
+ fastboot_fail("cannot read header from boot partition");
+ return 0;
+ }
+
+ /* Check boot header magic string */
+ res = android_image_check_header(hdr);
+ if (res != 0) {
+ error("bad boot image magic");
+ fastboot_fail("boot partition not initialized");
+ return 0;
+ }
+
+ return hdr_sectors;
+}
+
+/**
+ * Write downloaded zImage to boot partition and repack it properly.
+ *
+ * @param dev_desc MMC device descriptor
+ * @param download_buffer Address to fastboot buffer with zImage in it
+ * @param download_bytes Size of fastboot buffer, in bytes
+ *
+ * @return 0 on success or -1 on error
+ */
+static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
+ void *download_buffer,
+ unsigned int download_bytes)
+{
+ u32 hdr_addr; /* boot image header address */
+ struct andr_img_hdr *hdr; /* boot image header */
+ lbaint_t hdr_sectors; /* boot image header sectors */
+ u8 *ramdisk_buffer;
+ u32 ramdisk_sector_start;
+ u32 ramdisk_sectors;
+ u32 kernel_sector_start;
+ u32 kernel_sectors;
+ u32 sectors_per_page;
+ disk_partition_t info;
+ int res;
+
+ puts("Flashing zImage\n");
+
+ /* Get boot partition info */
+ res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
+ if (res < 0) {
+ error("cannot find boot partition");
+ fastboot_fail("cannot find boot partition");
+ return -1;
+ }
+
+ /* Put boot image header in fastboot buffer after downloaded zImage */
+ hdr_addr = (u32)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
+ hdr = (struct andr_img_hdr *)hdr_addr;
+
+ /* Read boot image header */
+ hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
+ if (hdr_sectors == 0) {
+ error("unable to read boot image header");
+ fastboot_fail("unable to read boot image header");
+ return -1;
+ }
+
+ /* Check if boot image has second stage in it (we don't support it) */
+ if (hdr->second_size > 0) {
+ error("moving second stage is not supported yet");
+ fastboot_fail("moving second stage is not supported yet");
+ return -1;
+ }
+
+ /* Extract ramdisk location */
+ sectors_per_page = hdr->page_size / info.blksz;
+ ramdisk_sector_start = info.start + sectors_per_page;
+ ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
+ sectors_per_page;
+ ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
+ sectors_per_page;
+
+ /* Read ramdisk and put it in fastboot buffer after boot image header */
+ ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
+ res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
+ ramdisk_buffer);
+ if (res == 0) {
+ error("cannot read ramdisk from boot partition");
+ fastboot_fail("cannot read ramdisk from boot partition");
+ return -1;
+ }
+
+ /* Write new kernel size to boot image header */
+ hdr->kernel_size = download_bytes;
+ res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
+ if (res == 0) {
+ error("cannot writeback boot image header");
+ fastboot_fail("cannot write back boot image header");
+ return -1;
+ }
+
+ /* Write the new downloaded kernel */
+ kernel_sector_start = info.start + sectors_per_page;
+ kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
+ sectors_per_page;
+ res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
+ download_buffer);
+ if (res == 0) {
+ error("cannot write new kernel");
+ fastboot_fail("cannot write new kernel");
+ return -1;
+ }
+
+ /* Write the saved ramdisk back */
+ ramdisk_sector_start = info.start + sectors_per_page;
+ ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
+ sectors_per_page;
+ res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
+ ramdisk_buffer);
+ if (res == 0) {
+ error("cannot write back original ramdisk");
+ fastboot_fail("cannot write back original ramdisk");
+ return -1;
+ }
+
+ puts("........ zImage was updated in boot partition\n");
+ fastboot_okay("");
+ return 0;
+}
+#endif
+
void fb_mmc_flash_write(const char *cmd, void *download_buffer,
unsigned int download_bytes)
{
@@ -153,6 +314,13 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
}
#endif
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+ if (strncasecmp(cmd, "zimage", 6) == 0) {
+ fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
+ return;
+ }
+#endif
+
if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
error("cannot find partition: '%s'\n", cmd);
fastboot_fail("cannot find partition");
diff --git a/common/lcd.c b/common/lcd.c
index 2405146cf0..7e399cee2d 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -562,11 +562,7 @@ __weak void lcd_set_cmap(struct bmp_image *bmp, unsigned colors)
*cmap = (((cte.red) << 8) & 0xf800) |
(((cte.green) << 3) & 0x07e0) |
(((cte.blue) >> 3) & 0x001f);
-#if defined(CONFIG_MPC823)
- cmap--;
-#else
cmap++;
-#endif
}
}
diff --git a/common/lynxkdi.c b/common/lynxkdi.c
index 22ad384ef6..98560159fe 100644
--- a/common/lynxkdi.c
+++ b/common/lynxkdi.c
@@ -22,7 +22,7 @@
DECLARE_GLOBAL_DATA_PTR;
-#if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
void lynxkdi_boot(image_header_t *hdr)
{
void (*lynxkdi)(void) = (void(*)(void))image_get_ep(hdr);
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 48a0fadb5f..4de81392b0 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,6 @@ 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
@@ -315,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
@@ -327,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
@@ -339,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
@@ -353,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,
@@ -363,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
@@ -377,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,
@@ -387,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
@@ -398,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
@@ -407,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
@@ -417,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
@@ -426,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.
@@ -435,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
@@ -456,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
@@ -465,16 +431,23 @@ 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
a memory-mapped device makes it very easy to access. Loading from
NOR is typically achieved with just a memcpy().
+config SPL_XIP_SUPPORT
+ bool "Support XIP"
+ depends on SPL
+ help
+ Enable support for execute in place of U-Boot or kernel image. There
+ is no need to copy image from flash to ram if flash supports execute
+ in place. Its very useful in systems having enough flash but not
+ enough ram to load the image.
+
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
@@ -483,7 +456,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.
@@ -492,7 +465,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.
@@ -501,7 +474,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
@@ -510,7 +482,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
@@ -519,7 +490,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
@@ -529,7 +499,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
@@ -542,7 +511,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
@@ -559,7 +527,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
@@ -569,7 +536,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
@@ -580,7 +546,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
@@ -590,7 +555,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
@@ -601,7 +565,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
@@ -612,7 +575,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
@@ -621,7 +583,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
@@ -642,7 +603,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.
@@ -690,7 +650,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
@@ -699,7 +658,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
@@ -708,7 +666,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).
@@ -720,71 +678,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/Makefile b/common/spl/Makefile
index b3b34d6277..47a64dd7d0 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -12,6 +12,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
obj-$(CONFIG_SPL_LOAD_FIT) += spl_fit.o
obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o
+obj-$(CONFIG_SPL_XIP_SUPPORT) += spl_xip.o
obj-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o
ifndef CONFIG_SPL_UBI
obj-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 0a49766f21..7f3fd925ba 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -121,9 +121,6 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
{
spl_image->size = CONFIG_SYS_MONITOR_LEN;
spl_image->entry_point = CONFIG_SYS_UBOOT_START;
-#ifdef CONFIG_CPU_V7M
- spl_image->entry_point |= 0x1;
-#endif
spl_image->load_addr = CONFIG_SYS_TEXT_BASE;
spl_image->os = IH_OS_U_BOOT;
spl_image->name = "U-Boot";
@@ -232,6 +229,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 +244,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;
@@ -396,6 +402,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
hang();
}
+#ifdef CONFIG_CPU_V7M
+ spl_image.entry_point |= 0x1;
+#endif
switch (spl_image.os) {
case IH_OS_U_BOOT:
debug("Jumping to U-Boot\n");
@@ -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);
}
diff --git a/common/spl/spl_xip.c b/common/spl/spl_xip.c
new file mode 100644
index 0000000000..18c7d11f2d
--- /dev/null
+++ b/common/spl/spl_xip.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Vikas Manocha <vikas.manocha@st.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+
+static int spl_xip(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ spl_image->arg = (void *)CONFIG_SYS_FDT_BASE;
+ spl_image->name = "Linux";
+ spl_image->os = IH_OS_LINUX;
+ spl_image->load_addr = CONFIG_SYS_LOAD_ADDR;
+ spl_image->entry_point = CONFIG_SYS_LOAD_ADDR;
+ debug("spl: payload xipImage, load addr: 0x%lx\n",
+ spl_image->load_addr);
+ return 0;
+ }
+#endif
+ return(spl_parse_image_header(spl_image, (const struct image_header *)
+ CONFIG_SYS_UBOOT_BASE));
+}
+SPL_LOAD_IMAGE_METHOD("XIP", 0, BOOT_DEVICE_XIP, spl_xip);