aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mvebu/Kconfig1
-rw-r--r--arch/arm/mach-mvebu/spl.c12
-rw-r--r--arch/sandbox/cpu/os.c59
-rw-r--r--arch/sandbox/cpu/start.c16
-rw-r--r--arch/sandbox/include/asm/global_data.h1
-rw-r--r--board/sandbox/README.sandbox46
-rw-r--r--cmd/Kconfig13
-rw-r--r--common/board_f.c2
-rw-r--r--common/bootstage.c7
-rw-r--r--common/command.c14
-rw-r--r--common/image-fdt.c33
-rw-r--r--configs/sandbox_defconfig2
-rw-r--r--drivers/core/Kconfig9
-rw-r--r--drivers/core/fdtaddr.c9
-rw-r--r--drivers/core/root.c21
-rw-r--r--drivers/core/simple-bus.c1
-rw-r--r--include/asm-generic/global_data.h4
-rw-r--r--include/configs/sandbox.h4
-rw-r--r--include/div64.h70
-rw-r--r--include/dm/fdtaddr.h21
-rw-r--r--include/fdtdec.h5
-rw-r--r--include/initcall.h19
-rw-r--r--include/os.h11
-rw-r--r--include/pci.h1
-rw-r--r--lib/Kconfig57
-rw-r--r--lib/div64.c20
-rw-r--r--lib/fdtdec.c7
-rw-r--r--lib/trace.c17
-rw-r--r--scripts/config_whitelist.txt5
29 files changed, 335 insertions, 152 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index f5fd60d..f99bd3b 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -14,6 +14,7 @@ config ARMADA_32BIT
select SPL_OF_CONTROL if SPL
select SPL_SIMPLE_BUS if SPL
select SUPPORT_SPL
+ select TRANSLATION_OFFSET
config ARMADA_64BIT
bool
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 9dd7c84..530b98c1 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -93,15 +93,21 @@ void board_init_f(ulong dummy)
*/
#endif
+ /*
+ * Use special translation offset for SPL. This needs to be
+ * configured *before* spl_init() is called as this function
+ * calls dm_init() which calls the bind functions of the
+ * device drivers. Here the base address needs to be configured
+ * (translated) correctly.
+ */
+ gd->translation_offset = 0xd0000000 - 0xf1000000;
+
ret = spl_init();
if (ret) {
debug("spl_init() failed: %d\n", ret);
hang();
}
- /* Use special translation offset for SPL */
- dm_set_translation_offset(0xd0000000 - 0xf1000000);
-
preloader_console_init();
timer_init();
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index a8d01e4..47dfb47 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -209,8 +209,8 @@ void os_tty_raw(int fd, bool allow_sigs)
void *os_malloc(size_t length)
{
- struct os_mem_hdr *hdr;
int page_size = getpagesize();
+ struct os_mem_hdr *hdr;
/*
* Use an address that is hopefully available to us so that pointers
@@ -229,30 +229,34 @@ void *os_malloc(size_t length)
void os_free(void *ptr)
{
- struct os_mem_hdr *hdr = ptr;
+ int page_size = getpagesize();
+ struct os_mem_hdr *hdr;
- hdr--;
- if (ptr)
- munmap(hdr, hdr->length + sizeof(*hdr));
+ if (ptr) {
+ hdr = ptr - page_size;
+ munmap(hdr, hdr->length + page_size);
+ }
}
void *os_realloc(void *ptr, size_t length)
{
- struct os_mem_hdr *hdr = ptr;
+ int page_size = getpagesize();
+ struct os_mem_hdr *hdr;
void *buf = NULL;
- hdr--;
- if (length != 0) {
+ if (length) {
buf = os_malloc(length);
if (!buf)
return buf;
if (ptr) {
+ hdr = ptr - page_size;
if (length > hdr->length)
length = hdr->length;
memcpy(buf, ptr, length);
}
}
- os_free(ptr);
+ if (ptr)
+ os_free(ptr);
return buf;
}
@@ -786,3 +790,40 @@ int os_mprotect_allow(void *start, size_t len)
return mprotect(start, len, PROT_READ | PROT_WRITE);
}
+
+void *os_find_text_base(void)
+{
+ char line[500];
+ void *base = NULL;
+ int len;
+ int fd;
+
+ /*
+ * This code assumes that the first line of /proc/self/maps holds
+ * information about the text, for example:
+ *
+ * 5622d9907000-5622d9a55000 r-xp 00000000 08:01 15067168 u-boot
+ *
+ * The first hex value is assumed to be the address.
+ *
+ * This is tested in Linux 4.15.
+ */
+ fd = open("/proc/self/maps", O_RDONLY);
+ if (fd == -1)
+ return NULL;
+ len = read(fd, line, sizeof(line));
+ if (len > 0) {
+ char *end = memchr(line, '-', len);
+
+ if (end) {
+ unsigned long long addr;
+
+ *end = '\0';
+ if (sscanf(line, "%llx", &addr) == 1)
+ base = (void *)addr;
+ }
+ }
+ close(fd);
+
+ return base;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 2f5e6e9..82828f0 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -303,10 +303,8 @@ int board_run_command(const char *cmdline)
static void setup_ram_buf(struct sandbox_state *state)
{
/* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
- if (!state->ram_buf_read) {
+ if (!state->ram_buf_read)
memset(state->ram_buf, '\0', state->ram_size);
- printf("clear %p %x\n", state->ram_buf, state->ram_size);
- }
gd->arch.ram_buf = state->ram_buf;
gd->ram_size = state->ram_size;
@@ -328,6 +326,10 @@ int main(int argc, char *argv[])
gd_t data;
int ret;
+ memset(&data, '\0', sizeof(data));
+ gd = &data;
+ gd->arch.text_base = os_find_text_base();
+
ret = state_init();
if (ret)
goto err;
@@ -340,8 +342,6 @@ int main(int argc, char *argv[])
if (ret)
goto err;
- memset(&data, '\0', sizeof(data));
- gd = &data;
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
gd->malloc_base = CONFIG_MALLOC_F_ADDR;
#endif
@@ -350,6 +350,12 @@ int main(int argc, char *argv[])
#endif
setup_ram_buf(state);
+ /*
+ * Set up the relocation offset here, since sandbox symbols are always
+ * relocated by the OS before sandbox is entered.
+ */
+ gd->reloc_off = (ulong)gd->arch.text_base;
+
/* Do pre- and post-relocation init */
board_init_f(0);
diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h
index f6a6a34..f4ce72d 100644
--- a/arch/sandbox/include/asm/global_data.h
+++ b/arch/sandbox/include/asm/global_data.h
@@ -12,6 +12,7 @@
/* Architecture-specific global data */
struct arch_global_data {
uint8_t *ram_buf; /* emulated RAM buffer */
+ void *text_base; /* pointer to base of text region */
};
#include <asm-generic/global_data.h>
diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox
index 9b09404..48c1e2b 100644
--- a/board/sandbox/README.sandbox
+++ b/board/sandbox/README.sandbox
@@ -392,6 +392,49 @@ state_setprop() which does this automatically and avoids running out of
space. See existing code for examples.
+Debugging the init sequence
+---------------------------
+
+If you get a failure in the initcall sequence, like this:
+
+ initcall sequence 0000560775957c80 failed at call 0000000000048134 (err=-96)
+
+Then you use can use grep to see which init call failed, e.g.:
+
+ $ grep 0000000000048134 u-boot.map
+ stdio_add_devices
+
+Of course another option is to run it with a debugger such as gdb:
+
+ $ gdb u-boot
+ ...
+ (gdb) br initcall.h:41
+ Breakpoint 1 at 0x4db9d: initcall.h:41. (2 locations)
+
+Note that two locations are reported, since this function is used in both
+board_init_f() and board_init_r().
+
+ (gdb) r
+ Starting program: /tmp/b/sandbox/u-boot
+ [Thread debugging using libthread_db enabled]
+ Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
+
+ U-Boot 2018.09-00264-ge0c2ba9814-dirty (Sep 22 2018 - 12:21:46 -0600)
+
+ DRAM: 128 MiB
+ MMC:
+
+ Breakpoint 1, initcall_run_list (init_sequence=0x5555559619e0 <init_sequence_f>)
+ at /scratch/sglass/cosarm/src/third_party/u-boot/files/include/initcall.h:41
+ 41 printf("initcall sequence %p failed at call %p (err=%d)\n",
+ (gdb) print *init_fnc_ptr
+ $1 = (const init_fnc_t) 0x55555559c114 <stdio_add_devices>
+ (gdb)
+
+
+This approach can be used on normal boards as well as sandbox.
+
+
Testing
-------
@@ -434,6 +477,9 @@ that are mapped into that memory:
0 CONFIG_SYS_FDT_LOAD_ADDR Device tree
e000 CONFIG_BLOBLIST_ADDR Blob list
10000 CONFIG_MALLOC_F_ADDR Early memory allocation
+ f0000 CONFIG_PRE_CON_BUF_ADDR Pre-console buffer
+ 100000 CONFIG_TRACE_EARLY_ADDR Early trace buffer (if enabled)
+=
--
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 5d1999e..67d23ca 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -53,6 +53,17 @@ config SYS_PROMPT
This string is displayed in the command line to the left of the
cursor.
+config SYS_XTRACE
+ string "Command execution tracer"
+ depends on CMDLINE
+ default y if CMDLINE
+ help
+ This option enables the possiblity to print all commands before
+ executing them and after all variables are evaluated (similar
+ to Bash's xtrace/'set -x' feature).
+ To enable the tracer a variable "xtrace" needs to be defined in
+ the environment.
+
menu "Autoboot options"
config AUTOBOOT
@@ -1900,7 +1911,7 @@ config CMD_TRACE
Enables a command to control using of function tracing within
U-Boot. This allows recording of call traces including timing
information. The command can write data to memory for exporting
- for analsys (e.g. using bootchart). See doc/README.trace for full
+ for analysis (e.g. using bootchart). See doc/README.trace for full
details.
config CMD_AVB
diff --git a/common/board_f.c b/common/board_f.c
index 149a722..7ef20f2 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -714,7 +714,7 @@ static int setup_reloc(void)
* just after the default vector table location, so at 0x400
*/
gd->reloc_off = gd->relocaddr - (CONFIG_SYS_TEXT_BASE + 0x400);
-#else
+#elif !defined(CONFIG_SANDBOX)
gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;
#endif
#endif
diff --git a/common/bootstage.c b/common/bootstage.c
index 9793b85..56ef91a 100644
--- a/common/bootstage.c
+++ b/common/bootstage.c
@@ -99,6 +99,13 @@ ulong bootstage_add_record(enum bootstage_id id, const char *name,
struct bootstage_data *data = gd->bootstage;
struct bootstage_record *rec;
+ /*
+ * initf_bootstage() is called very early during boot but since hang()
+ * calls bootstage_error() we can be called before bootstage is set up.
+ * Add a check to avoid this.
+ */
+ if (!data)
+ return mark;
if (flags & BOOTSTAGEF_ALLOC)
id = data->next_id++;
diff --git a/common/command.c b/common/command.c
index e14d1fa..e192bb2 100644
--- a/common/command.c
+++ b/common/command.c
@@ -574,6 +574,20 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
enum command_ret_t rc = CMD_RET_SUCCESS;
cmd_tbl_t *cmdtp;
+#if defined(CONFIG_SYS_XTRACE)
+ char *xtrace;
+
+ xtrace = env_get("xtrace");
+ if (xtrace) {
+ puts("+");
+ for (int i = 0; i < argc; i++) {
+ puts(" ");
+ puts(argv[i]);
+ }
+ puts("\n");
+ }
+#endif
+
/* Look up command in command table */
cmdtp = find_cmd(argv[0]);
if (cmdtp == NULL) {
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 9ed00b7..eb552ca 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -279,7 +279,6 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
int fdt_noffset;
#endif
const char *select = NULL;
- int ok_no_fdt = 0;
*of_flat_tree = NULL;
*of_size = 0;
@@ -462,17 +461,24 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
struct andr_img_hdr *hdr = buf;
ulong fdt_data, fdt_len;
- if (android_image_get_second(hdr, &fdt_data, &fdt_len) != 0)
- goto no_fdt;
+ if (!android_image_get_second(hdr, &fdt_data, &fdt_len) &&
+ !fdt_check_header((char *)fdt_data)) {
+ fdt_blob = (char *)fdt_data;
+ if (fdt_totalsize(fdt_blob) != fdt_len)
+ goto error;
- fdt_blob = (char *)fdt_data;
- if (fdt_check_header(fdt_blob) != 0)
- goto no_fdt;
+ debug("## Using FDT in Android image second area\n");
+ } else {
+ fdt_addr = env_get_hex("fdtaddr", 0);
+ if (!fdt_addr)
+ goto no_fdt;
- if (fdt_totalsize(fdt_blob) != fdt_len)
- goto error;
+ fdt_blob = map_sysmem(fdt_addr, 0);
+ if (fdt_check_header(fdt_blob))
+ goto no_fdt;
- debug("## Using FDT found in Android image second area\n");
+ debug("## Using FDT at ${fdtaddr}=Ox%lx\n", fdt_addr);
+ }
#endif
} else {
debug("## No Flattened Device Tree\n");
@@ -487,14 +493,9 @@ int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
return 0;
no_fdt:
- ok_no_fdt = 1;
+ debug("Continuing to boot without FDT\n");
+ return 0;
error:
- *of_flat_tree = NULL;
- *of_size = 0;
- if (!select && ok_no_fdt) {
- debug("Continuing to boot without FDT\n");
- return 0;
- }
return 1;
}
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index bb508a8..ba28db6 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -16,7 +16,7 @@ CONFIG_CONSOLE_RECORD=y
CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
CONFIG_SILENT_CONSOLE=y
CONFIG_PRE_CONSOLE_BUFFER=y
-CONFIG_PRE_CON_BUF_ADDR=0x100000
+CONFIG_PRE_CON_BUF_ADDR=0xf0000
CONFIG_LOG_MAX_LEVEL=6
CONFIG_LOG_ERROR_RETURN=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig
index ddf2fb3..2d195ae 100644
--- a/drivers/core/Kconfig
+++ b/drivers/core/Kconfig
@@ -225,6 +225,15 @@ config SPL_OF_TRANSLATE
used for the address translation. This function is faster and
smaller in size than fdt_translate_address().
+config TRANSLATION_OFFSET
+ bool "Platforms specific translation offset"
+ depends on DM && OF_CONTROL
+ help
+ Some platforms need a special address translation. Those
+ platforms (e.g. mvebu in SPL) can configure a translation
+ offset by enabling this option and setting the translation_offset
+ variable in the GD in their platform- / board-specific code.
+
config OF_ISA_BUS
bool
depends on OF_TRANSLATE
diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c
index e113f1d..c287386 100644
--- a/drivers/core/fdtaddr.c
+++ b/drivers/core/fdtaddr.c
@@ -74,13 +74,16 @@ fdt_addr_t devfdt_get_addr_index(struct udevice *dev, int index)
}
}
+#if defined(CONFIG_TRANSLATION_OFFSET)
/*
* Some platforms need a special address translation. Those
* platforms (e.g. mvebu in SPL) can configure a translation
- * offset in the DM by calling dm_set_translation_offset() that
- * will get added to all addresses returned by devfdt_get_addr().
+ * offset by setting this value in the GD and enaling this
+ * feature via CONFIG_TRANSLATION_OFFSET. This value will
+ * get added to all addresses returned by devfdt_get_addr().
*/
- addr += dm_get_translation_offset();
+ addr += gd->translation_offset;
+#endif
return addr;
#else
diff --git a/drivers/core/root.c b/drivers/core/root.c
index e6ec7fa..8fa0966 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -25,10 +25,6 @@
DECLARE_GLOBAL_DATA_PTR;
-struct root_priv {
- fdt_addr_t translation_offset; /* optional translation offset */
-};
-
static const struct driver_info root_info = {
.name = "root_driver",
};
@@ -52,22 +48,6 @@ void dm_fixup_for_gd_move(struct global_data *new_gd)
}
}
-fdt_addr_t dm_get_translation_offset(void)
-{
- struct udevice *root = dm_root();
- struct root_priv *priv = dev_get_priv(root);
-
- return priv->translation_offset;
-}
-
-void dm_set_translation_offset(fdt_addr_t offs)
-{
- struct udevice *root = dm_root();
- struct root_priv *priv = dev_get_priv(root);
-
- priv->translation_offset = offs;
-}
-
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
void fix_drivers(void)
{
@@ -420,7 +400,6 @@ int dm_init_and_scan(bool pre_reloc_only)
U_BOOT_DRIVER(root_driver) = {
.name = "root_driver",
.id = UCLASS_ROOT,
- .priv_auto_alloc_size = sizeof(struct root_priv),
};
/* This is the root uclass */
diff --git a/drivers/core/simple-bus.c b/drivers/core/simple-bus.c
index e16d8a9..7fc23ef 100644
--- a/drivers/core/simple-bus.c
+++ b/drivers/core/simple-bus.c
@@ -60,4 +60,5 @@ U_BOOT_DRIVER(simple_bus_drv) = {
.name = "generic_simple_bus",
.id = UCLASS_SIMPLE_BUS,
.of_match = generic_simple_bus_ids,
+ .flags = DM_FLAG_PRE_RELOC,
};
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 78dcf40..65ee3e5 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -20,6 +20,7 @@
*/
#ifndef __ASSEMBLY__
+#include <fdtdec.h>
#include <membuff.h>
#include <linux/list.h>
@@ -133,6 +134,9 @@ typedef struct global_data {
struct spl_handoff *spl_handoff;
# endif
#endif
+#if defined(CONFIG_TRANSLATION_OFFSET)
+ fdt_addr_t translation_offset; /* optional translation offset */
+#endif
} gd_t;
#endif
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index e36a5fe..bf03bae 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -8,11 +8,11 @@
#ifdef FTRACE
#define CONFIG_TRACE
+#define CONFIG_CMD_TRACE
#define CONFIG_TRACE_BUFFER_SIZE (16 << 20)
-#define CONFIG_TRACE_EARLY_SIZE (8 << 20)
+#define CONFIG_TRACE_EARLY_SIZE (16 << 20)
#define CONFIG_TRACE_EARLY
#define CONFIG_TRACE_EARLY_ADDR 0x00100000
-
#endif
#ifndef CONFIG_SPL_BUILD
diff --git a/include/div64.h b/include/div64.h
index 76563ef..8b92d2b 100644
--- a/include/div64.h
+++ b/include/div64.h
@@ -9,11 +9,11 @@
*
* The semantics of do_div() are:
*
- * uint32_t do_div(uint64_t *n, uint32_t base)
+ * u32 do_div(u64 *n, u32 base)
* {
- * uint32_t remainder = *n % base;
- * *n = *n / base;
- * return remainder;
+ * u32 remainder = *n % base;
+ * *n = *n / base;
+ * return remainder;
* }
*
* NOTE: macro parameter n is evaluated multiple times,
@@ -26,10 +26,10 @@
#if BITS_PER_LONG == 64
# define do_div(n,base) ({ \
- uint32_t __base = (base); \
- uint32_t __rem; \
- __rem = ((uint64_t)(n)) % __base; \
- (n) = ((uint64_t)(n)) / __base; \
+ u32 __base = (base); \
+ u32 __rem; \
+ __rem = ((u64)(n)) % __base; \
+ (n) = ((u64)(n)) / __base; \
__rem; \
})
@@ -62,8 +62,8 @@
* Hence this monstrous macro (static inline doesn't always \
* do the trick here). \
*/ \
- uint64_t ___res, ___x, ___t, ___m, ___n = (n); \
- uint32_t ___p, ___bias; \
+ u64 ___res, ___x, ___t, ___m, ___n = (n); \
+ u32 ___p, ___bias; \
\
/* determine MSB of b */ \
___p = 1 << ilog2(___b); \
@@ -110,7 +110,7 @@
* possible, otherwise that'll need extra overflow \
* handling later. \
*/ \
- uint32_t ___bits = -(___m & -___m); \
+ u32 ___bits = -(___m & -___m); \
___bits |= ___m >> 32; \
___bits = (~___bits) << 1; \
/* \
@@ -150,61 +150,61 @@
/*
* Default C implementation for __arch_xprod_64()
*
- * Prototype: uint64_t __arch_xprod_64(const uint64_t m, uint64_t n, bool bias)
+ * Prototype: u64 __arch_xprod_64(const u64 m, u64 n, bool bias)
* Semantic: retval = ((bias ? m : 0) + m * n) >> 64
*
* The product is a 128-bit value, scaled down to 64 bits.
* Assuming constant propagation to optimize away unused conditional code.
* Architectures may provide their own optimized assembly implementation.
*/
-static inline uint64_t __arch_xprod_64(const uint64_t m, uint64_t n, bool bias)
+static inline u64 __arch_xprod_64(const u64 m, u64 n, bool bias)
{
- uint32_t m_lo = m;
- uint32_t m_hi = m >> 32;
- uint32_t n_lo = n;
- uint32_t n_hi = n >> 32;
- uint64_t res, tmp;
+ u32 m_lo = m;
+ u32 m_hi = m >> 32;
+ u32 n_lo = n;
+ u32 n_hi = n >> 32;
+ u64 res, tmp;
if (!bias) {
- res = ((uint64_t)m_lo * n_lo) >> 32;
+ res = ((u64)m_lo * n_lo) >> 32;
} else if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
/* there can't be any overflow here */
- res = (m + (uint64_t)m_lo * n_lo) >> 32;
+ res = (m + (u64)m_lo * n_lo) >> 32;
} else {
- res = m + (uint64_t)m_lo * n_lo;
+ res = m + (u64)m_lo * n_lo;
tmp = (res < m) ? (1ULL << 32) : 0;
res = (res >> 32) + tmp;
}
if (!(m & ((1ULL << 63) | (1ULL << 31)))) {
/* there can't be any overflow here */
- res += (uint64_t)m_lo * n_hi;
- res += (uint64_t)m_hi * n_lo;
+ res += (u64)m_lo * n_hi;
+ res += (u64)m_hi * n_lo;
res >>= 32;
} else {
- tmp = res += (uint64_t)m_lo * n_hi;
- res += (uint64_t)m_hi * n_lo;
+ tmp = res += (u64)m_lo * n_hi;
+ res += (u64)m_hi * n_lo;
tmp = (res < tmp) ? (1ULL << 32) : 0;
res = (res >> 32) + tmp;
}
- res += (uint64_t)m_hi * n_hi;
+ res += (u64)m_hi * n_hi;
return res;
}
#endif
#ifndef __div64_32
-extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
+extern u32 __div64_32(u64 *dividend, u32 divisor);
#endif
/* The unnecessary pointer compare is there
* to check for type safety (n must be 64bit)
*/
# define do_div(n,base) ({ \
- uint32_t __base = (base); \
- uint32_t __rem; \
- (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \
+ u32 __base = (base); \
+ u32 __rem; \
+ (void)(((typeof((n)) *)0) == ((u64 *)0)); \
if (__builtin_constant_p(__base) && \
is_power_of_2(__base)) { \
__rem = (n) & (__base - 1); \
@@ -212,14 +212,14 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
} else if (__div64_const32_is_OK && \
__builtin_constant_p(__base) && \
__base != 0) { \
- uint32_t __res_lo, __n_lo = (n); \
+ u32 __res_lo, __n_lo = (n); \
(n) = __div64_const32(n, __base); \
/* the remainder can be computed with 32-bit regs */ \
__res_lo = (n); \
__rem = __n_lo - __res_lo * __base; \
} else if (likely(((n) >> 32) == 0)) { \
- __rem = (uint32_t)(n) % __base; \
- (n) = (uint32_t)(n) / __base; \
+ __rem = (u32)(n) % __base; \
+ (n) = (u32)(n) / __base; \
} else \
__rem = __div64_32(&(n), __base); \
__rem; \
@@ -234,9 +234,9 @@ extern uint32_t __div64_32(uint64_t *dividend, uint32_t divisor);
/* Wrapper for do_div(). Doesn't modify dividend and returns
* the result, not remainder.
*/
-static inline uint64_t lldiv(uint64_t dividend, uint32_t divisor)
+static inline u64 lldiv(u64 dividend, u32 divisor)
{
- uint64_t __res = dividend;
+ u64 __res = dividend;
do_div(__res, divisor);
return(__res);
}
diff --git a/include/dm/fdtaddr.h b/include/dm/fdtaddr.h
index c171d9b..3bc2599 100644
--- a/include/dm/fdtaddr.h
+++ b/include/dm/fdtaddr.h
@@ -120,25 +120,4 @@ fdt_addr_t devfdt_get_addr_size_index(struct udevice *dev, int index,
*/
fdt_addr_t devfdt_get_addr_name(struct udevice *dev, const char *name);
-/**
- * dm_set_translation_offset() - Set translation offset
- * @offs: Translation offset
- *
- * Some platforms need a special address translation. Those
- * platforms (e.g. mvebu in SPL) can configure a translation
- * offset in the DM by calling this function. It will be
- * added to all addresses returned in devfdt_get_addr().
- */
-void dm_set_translation_offset(fdt_addr_t offs);
-
-/**
- * dm_get_translation_offset() - Get translation offset
- *
- * This function returns the translation offset that can
- * be configured by calling dm_set_translation_offset().
- *
- * @return translation offset for the device address (0 as default).
- */
-fdt_addr_t dm_get_translation_offset(void);
-
#endif
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 266c582..110aa6a 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -1029,7 +1029,10 @@ int fdtdec_setup_memory_banksize(void);
* @param phandle phandle to set for the given node
* @return 0 on success or a negative error code on failure
*/
-int fdtdec_set_phandle(void *blob, int node, uint32_t phandle);
+static inline int fdtdec_set_phandle(void *blob, int node, uint32_t phandle)
+{
+ return fdt_setprop_u32(blob, node, "phandle", phandle);
+}
/**
* fdtdec_add_reserved_memory() - add or find a reserved-memory node
diff --git a/include/initcall.h b/include/initcall.h
index 3ac01aa..78d15af 100644
--- a/include/initcall.h
+++ b/include/initcall.h
@@ -8,12 +8,11 @@
typedef int (*init_fnc_t)(void);
-#include <common.h>
-#include <initcall.h>
-#include <efi.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
+/*
+ * To enable debugging. add #define DEBUG at the top of the including file.
+ *
+ * To find a symbol, use grep on u-boot.map
+ */
static inline int initcall_run_list(const init_fnc_t init_sequence[])
{
const init_fnc_t *init_fnc_ptr;
@@ -22,13 +21,17 @@ static inline int initcall_run_list(const init_fnc_t init_sequence[])
unsigned long reloc_ofs = 0;
int ret;
- if (gd->flags & GD_FLG_RELOC)
+ /*
+ * Sandbox is relocated by the OS, so symbols always appear at
+ * the relocated address.
+ */
+ if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC))
reloc_ofs = gd->reloc_off;
#ifdef CONFIG_EFI_APP
reloc_ofs = (unsigned long)image_base;
#endif
debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
- if (gd->flags & GD_FLG_RELOC)
+ if (reloc_ofs)
debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
else
debug("\n");
diff --git a/include/os.h b/include/os.h
index 6f33b08..7a4f78b 100644
--- a/include/os.h
+++ b/include/os.h
@@ -364,4 +364,15 @@ int os_write_file(const char *name, const void *buf, int size);
*/
int os_read_file(const char *name, void **bufp, int *sizep);
+/*
+ * os_find_text_base() - Find the text section in this running process
+ *
+ * This tries to find the address of the text section in this running process.
+ * It can be useful to map the address of functions to the address listed in
+ * the u-boot.map file.
+ *
+ * @return address if found, else NULL
+ */
+void *os_find_text_base(void);
+
#endif
diff --git a/include/pci.h b/include/pci.h
index 9668503..066238a 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -405,6 +405,7 @@
#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
+#define PCI_MSI_FLAGS_MASKBIT 0x0100 /* Per-vector masking capable */
#define PCI_MSI_RFU 3 /* Rest of capability flags */
#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
diff --git a/lib/Kconfig b/lib/Kconfig
index 2120216..05f82d4 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -165,6 +165,63 @@ config RBTREE
config BITREVERSE
bool "Bit reverse library from Linux"
+config TRACE
+ bool "Support for tracing of function calls and timing"
+ imply CMD_TRACE
+ help
+ Enables function tracing within U-Boot. This allows recording of call
+ traces including timing information. The command can write data to
+ memory for exporting for analysis (e.g. using bootchart).
+ See doc/README.trace for full details.
+
+config TRACE_BUFFER_SIZE
+ hex "Size of trace buffer in U-Boot"
+ depends on TRACE
+ default 0x01000000
+ help
+ Sets the size of the trace buffer in U-Boot. This is allocated from
+ memory during relocation. If this buffer is too small, the trace
+ history will be truncated, with later records omitted.
+
+ If early trace is enabled (i.e. before relocation), this buffer must
+ be large enough to include all the data from the early trace buffer as
+ well, since this is copied over to the main buffer during relocation.
+
+ A trace record is emitted for each function call and each record is
+ 12 bytes (see struct trace_call). A suggested minimum size is 1MB. If
+ the size is too small then 'trace stats' will show a message saying
+ how many records were dropped due to buffer overflow.
+
+config TRACE_EARLY
+ bool "Enable tracing before relocation"
+ depends on TRACE
+ help
+ Sometimes it is helpful to trace execution of U-Boot before
+ relocation. This is possible by using a arch-specific, fixed buffer
+ position in memory. Enable this option to start tracing as early as
+ possible after U-Boot starts.
+
+config TRACE_EARLY_SIZE
+ hex "Size of early trace buffer in U-Boot"
+ depends on TRACE_EARLY
+ default 0x00100000
+ help
+ Sets the size of the early trace buffer in bytes. This is used to hold
+ tracing information before relocation.
+
+config TRACE_EARLY_ADDR
+ hex "Address of early trace buffer in U-Boot"
+ depends on TRACE_EARLY
+ default 0x00100000
+ help
+ Sets the address of the early trace buffer in U-Boot. This memory
+ must be accessible before relocation.
+
+ A trace record is emitted for each function call and each record is
+ 12 bytes (see struct trace_call). A suggested minimum size is 1MB. If
+ the size is too small then the message which says the amount of early
+ data being coped will the the same as the
+
source lib/dhry/Kconfig
menu "Security support"
diff --git a/lib/div64.c b/lib/div64.c
index 206f582..62933c9 100644
--- a/lib/div64.c
+++ b/lib/div64.c
@@ -25,19 +25,25 @@
#if BITS_PER_LONG == 32
#ifndef __div64_32
-uint32_t __attribute__((weak)) __div64_32(uint64_t *n, uint32_t base)
+/*
+ * Don't instrument this function as it may be called from tracing code, since
+ * it needs to read the timer and this often requires calling do_div(), which
+ * calls this function.
+ */
+uint32_t __attribute__((weak, no_instrument_function)) __div64_32(u64 *n,
+ u32 base)
{
- uint64_t rem = *n;
- uint64_t b = base;
- uint64_t res, d = 1;
- uint32_t high = rem >> 32;
+ u64 rem = *n;
+ u64 b = base;
+ u64 res, d = 1;
+ u32 high = rem >> 32;
/* Reduce the thing a bit first */
res = 0;
if (high >= base) {
high /= base;
- res = (uint64_t) high << 32;
- rem -= (uint64_t) (high*base) << 32;
+ res = (u64)high << 32;
+ rem -= (u64)(high * base) << 32;
}
while ((int64_t)b > 0 && b < rem) {
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 9c9c302..fea44a9 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -1261,13 +1261,6 @@ __weak void *board_fdt_blob_setup(void)
}
#endif
-int fdtdec_set_phandle(void *blob, int node, uint32_t phandle)
-{
- fdt32_t value = cpu_to_fdt32(phandle);
-
- return fdt_setprop(blob, node, "phandle", &value, sizeof(value));
-}
-
static int fdtdec_init_reserved_memory(void *blob)
{
int na, ns, node, err;
diff --git a/lib/trace.c b/lib/trace.c
index bb089c2..9956442 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -183,7 +183,8 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed)
/* Work out how must of the buffer we used */
*needed = ptr - buff;
if (ptr > end)
- return -1;
+ return -ENOSPC;
+
return 0;
}
@@ -227,7 +228,8 @@ int trace_list_calls(void *buff, int buff_size, unsigned *needed)
/* Work out how must of the buffer we used */
*needed = ptr - buff;
if (ptr > end)
- return -1;
+ return -ENOSPC;
+
return 0;
}
@@ -294,7 +296,8 @@ int __attribute__((no_instrument_function)) trace_init(void *buff,
trace_enabled = 0;
hdr = map_sysmem(CONFIG_TRACE_EARLY_ADDR,
CONFIG_TRACE_EARLY_SIZE);
- end = (char *)&hdr->ftrace[hdr->ftrace_count];
+ end = (char *)&hdr->ftrace[min(hdr->ftrace_count,
+ hdr->ftrace_size)];
used = end - (char *)hdr;
printf("trace: copying %08lx bytes of early data from %x to %08lx\n",
used, CONFIG_TRACE_EARLY_ADDR,
@@ -302,7 +305,7 @@ int __attribute__((no_instrument_function)) trace_init(void *buff,
memcpy(buff, hdr, used);
#else
puts("trace: already enabled\n");
- return -1;
+ return -EALREADY;
#endif
}
hdr = (struct trace_hdr *)buff;
@@ -310,7 +313,7 @@ int __attribute__((no_instrument_function)) trace_init(void *buff,
if (needed > buff_size) {
printf("trace: buffer size %zd bytes: at least %zd needed\n",
buff_size, needed);
- return -1;
+ return -ENOSPC;
}
if (was_disabled)
@@ -327,6 +330,7 @@ int __attribute__((no_instrument_function)) trace_init(void *buff,
hdr->depth_limit = 15;
trace_enabled = 1;
trace_inited = 1;
+
return 0;
}
@@ -346,7 +350,7 @@ int __attribute__((no_instrument_function)) trace_early_init(void)
if (needed > buff_size) {
printf("trace: buffer size is %zd bytes, at least %zd needed\n",
buff_size, needed);
- return -1;
+ return -ENOSPC;
}
memset(hdr, '\0', needed);
@@ -361,6 +365,7 @@ int __attribute__((no_instrument_function)) trace_early_init(void)
printf("trace: early enable at %08x\n", CONFIG_TRACE_EARLY_ADDR);
trace_enabled = 1;
+
return 0;
}
#endif
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 421362d..3e6bdf8 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -4401,11 +4401,6 @@ CONFIG_TMU_TIMER
CONFIG_TPL_PAD_TO
CONFIG_TPM_TIS_BASE_ADDRESS
CONFIG_TPS6586X_POWER
-CONFIG_TRACE
-CONFIG_TRACE_BUFFER_SIZE
-CONFIG_TRACE_EARLY
-CONFIG_TRACE_EARLY_ADDR
-CONFIG_TRACE_EARLY_SIZE
CONFIG_TRAILBLAZER
CONFIG_TRATS
CONFIG_TSEC