From a2fa38da200cbd454bcb8dc7659bde00044302f7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 2 Jun 2019 13:05:08 +0200 Subject: trace: conserve gd register An UEFI application may change the value of the register that gd lives in. But some of our functions like get_ticks() access this register. So we have to set the gd register to the U-Boot value when entering a trace point and set it back to the application value when exiting the trace point. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/trace.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'lib/trace.c') diff --git a/lib/trace.c b/lib/trace.c index 9956442fef..a13e5bf228 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -56,6 +56,49 @@ static inline uintptr_t __attribute__((no_instrument_function)) return offset / FUNC_SITE_SIZE; } +#ifdef CONFIG_EFI_LOADER + +/** + * trace_gd - the value of the gd register + */ +static volatile void *trace_gd; + +/** + * trace_save_gd() - save the value of the gd register + */ +static void __attribute__((no_instrument_function)) trace_save_gd(void) +{ + trace_gd = gd; +} + +/** + * trace_swap_gd() - swap between U-Boot and application gd register value + * + * An UEFI application may change the value of the register that gd lives in. + * But some of our functions like get_ticks() access this register. So we + * have to set the gd register to the U-Boot value when entering a trace + * point and set it back to the application value when exiting the trace point. + */ +static void __attribute__((no_instrument_function)) trace_swap_gd(void) +{ + volatile void *temp_gd = trace_gd; + + trace_gd = gd; + gd = temp_gd; +} + +#else + +static void __attribute__((no_instrument_function)) trace_save_gd(void) +{ +} + +static void __attribute__((no_instrument_function)) trace_swap_gd(void) +{ +} + +#endif + static void __attribute__((no_instrument_function)) add_ftrace(void *func_ptr, void *caller, ulong flags) { @@ -100,6 +143,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( if (trace_enabled) { int func; + trace_swap_gd(); add_ftrace(func_ptr, caller, FUNCF_ENTRY); func = func_ptr_to_num(func_ptr); if (func < hdr->func_count) { @@ -111,6 +155,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( hdr->depth++; if (hdr->depth > hdr->depth_limit) hdr->max_depth = hdr->depth; + trace_swap_gd(); } } @@ -126,8 +171,10 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit( void *func_ptr, void *caller) { if (trace_enabled) { + trace_swap_gd(); add_ftrace(func_ptr, caller, FUNCF_EXIT); hdr->depth--; + trace_swap_gd(); } } @@ -284,6 +331,8 @@ int __attribute__((no_instrument_function)) trace_init(void *buff, size_t needed; int was_disabled = !trace_enabled; + trace_save_gd(); + if (!was_disabled) { #ifdef CONFIG_TRACE_EARLY char *end; -- cgit v1.2.1 From da0fb5fdd430abef136bc5e1636f8d1855cf0008 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 2 Jun 2019 13:30:09 +0200 Subject: trace: make call depth limit customizable Up to now we had hard coded values for the call depth up to which trace records are created: 200 for early tracing, 15 thereafter. UEFI applications reach a call depth of 80 or above. Provide customizing settings for the call trace depth limit and the early call trace depth limit. Use the old values as defaults. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/trace.c') diff --git a/lib/trace.c b/lib/trace.c index a13e5bf228..04780f59d3 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -376,7 +376,7 @@ int __attribute__((no_instrument_function)) trace_init(void *buff, add_textbase(); puts("trace: enabled\n"); - hdr->depth_limit = 15; + hdr->depth_limit = CONFIG_TRACE_CALL_DEPTH_LIMIT; trace_enabled = 1; trace_inited = 1; @@ -410,7 +410,7 @@ int __attribute__((no_instrument_function)) trace_early_init(void) hdr->ftrace = (struct trace_call *)((char *)hdr + needed); hdr->ftrace_size = (buff_size - needed) / sizeof(*hdr->ftrace); add_textbase(); - hdr->depth_limit = 200; + hdr->depth_limit = CONFIG_TRACE_EARLY_CALL_DEPTH_LIMIT; printf("trace: early enable at %08x\n", CONFIG_TRACE_EARLY_ADDR); trace_enabled = 1; -- cgit v1.2.1 From 2b7a3882e0f70d253fb6a2da5682c94aea4c46f1 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 14 Jun 2019 21:50:55 +0200 Subject: trace: do not limit trace buffer to 2GiB There is no good reason to limit the trace buffer to 2GiB on a 64bit system. Adjust the types of the relevant parameters. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/trace.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/trace.c') diff --git a/lib/trace.c b/lib/trace.c index 04780f59d3..f2402b9359 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -190,12 +190,12 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit( * greater than buff_size if we ran out of space. * @return 0 if ok, -1 if space was exhausted */ -int trace_list_functions(void *buff, int buff_size, unsigned int *needed) +int trace_list_functions(void *buff, size_t buff_size, size_t *needed) { struct trace_output_hdr *output_hdr = NULL; void *end, *ptr = buff; - int func; - int upto; + size_t func; + size_t upto; end = buff ? buff + buff_size : NULL; @@ -206,7 +206,7 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed) /* Add information about each function */ for (func = upto = 0; func < hdr->func_count; func++) { - int calls = hdr->call_accum[func]; + size_t calls = hdr->call_accum[func]; if (!calls) continue; @@ -235,12 +235,12 @@ int trace_list_functions(void *buff, int buff_size, unsigned int *needed) return 0; } -int trace_list_calls(void *buff, int buff_size, unsigned *needed) +int trace_list_calls(void *buff, size_t buff_size, size_t *needed) { struct trace_output_hdr *output_hdr = NULL; void *end, *ptr = buff; - int rec, upto; - int count; + size_t rec, upto; + size_t count; end = buff ? buff + buff_size : NULL; -- cgit v1.2.1