Various minor sandbox iumprovements

Fixes for tracing with sandbox
 Refactoring for boot_get_fdt()
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAlzAfvkACgkQfxc6PpAI
 reYu9AgAjaFmydXjE8DxkSB3rR7DHZFTs1erVKAAL2v+Tdf7LDmz+j6u1M3v55WY
 6r54f/gZ1UX5TEmQgEAKLa7QvvRO/lNvSGQnLHhZhv2IVWo7uWCKAUPdQ6XVZnUK
 zO5v+ucs9Ne4HxQJHMC509HUIIBbydiRvUm8W0SeBZy4kEyJDuub4L+rpARkXNks
 IZfKuY+VS4FK73D4M9PIhoXSubZgVS4AEcapakU1DvEz0kjsN4wr4idGrp3lutPC
 455imz83JBq2+mx1oxclOGedkIDzTCq+nWQAwSftMehrJpGrp7RLNo0v4QZZUf4V
 LIXRqObIYse9yQLkYPpeBdePMc8/tQ==
 =0NJ2
 -----END PGP SIGNATURE-----

Merge tag 'pull-24apr19' of git://git.denx.de/u-boot-dm

Various minor sandbox iumprovements
Fixes for tracing with sandbox
Refactoring for boot_get_fdt()
This commit is contained in:
Tom Rini 2019-04-24 12:27:29 -04:00
commit 7d99406742
29 changed files with 335 additions and 152 deletions

View File

@ -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

View File

@ -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();

View File

@ -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;
}

View File

@ -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);

View File

@ -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>

View File

@ -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)
=
--

View File

@ -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

View File

@ -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

View File

@ -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++;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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,
};

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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) */

View File

@ -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"

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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