X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=lib%2Ftrace.c;h=ea8c8e0d406ff86eb0ee0f5f4902b8b2197ecf90;hb=90606da02dffb61195ade325f2be2e170e7c410c;hp=9956442fefe6b422fb5b048f9aa039a0acb44aad;hpb=1c64692df20c1f491ea79de3a732428611bb0ba0;p=oweals%2Fu-boot.git diff --git a/lib/trace.c b/lib/trace.c index 9956442fef..ea8c8e0d40 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,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) { @@ -86,13 +130,13 @@ static void __attribute__((no_instrument_function)) add_textbase(void) } /** - * This is called on every function entry + * __cyg_profile_func_enter() - record function entry * * We add to our tally for this function and add to the list of called * functions. * - * @param func_ptr Pointer to function being entered - * @param caller Pointer to function which called this function + * @func_ptr: pointer to function being entered + * @caller: pointer to function which called this function */ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( void *func_ptr, void *caller) @@ -100,6 +144,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,44 +156,45 @@ 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(); } } /** - * This is called on every function exit - * - * We do nothing here. + * __cyg_profile_func_exit() - record function exit * - * @param func_ptr Pointer to function being entered - * @param caller Pointer to function which called this function + * @func_ptr: pointer to function being entered + * @caller: pointer to function which called this function */ 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(); } } /** - * Produce a list of called functions + * trace_list_functions() - produce a list of called functions * * The information is written into the supplied buffer - a header followed * by a list of function records. * - * @param buff Buffer to place list into - * @param buff_size Size of buffer - * @param needed Returns size of buffer needed, which may be - * greater than buff_size if we ran out of space. - * @return 0 if ok, -1 if space was exhausted + * @buff: buffer to place list into + * @buff_size: size of buffer + * @needed: returns size of buffer needed, which may be + * greater than buff_size if we ran out of space. + * Return: 0 if ok, -ENOSPC 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; @@ -159,7 +205,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; @@ -188,12 +234,24 @@ 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) +/** + * trace_list_functions() - produce a list of function calls + * + * The information is written into the supplied buffer - a header followed + * by a list of function records. + * + * @buff: buffer to place list into + * @buff_size: size of buffer + * @needed: returns size of buffer needed, which may be + * greater than buff_size if we ran out of space. + * Return: 0 if ok, -ENOSPC if space was exhausted + */ +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; @@ -233,7 +291,9 @@ int trace_list_calls(void *buff, int buff_size, unsigned *needed) return 0; } -/* Print basic information about tracing */ +/** + * trace_print_stats() - print basic information about tracing + */ void trace_print_stats(void) { ulong count; @@ -272,10 +332,11 @@ void __attribute__((no_instrument_function)) trace_set_enabled(int enabled) } /** - * Init the tracing system ready for used, and enable it + * trace_init() - initialize the tracing system and enable it * - * @param buff Pointer to trace buffer - * @param buff_size Size of trace buffer + * @buff: Pointer to trace buffer + * @buff_size: Size of trace buffer + * Return: 0 if ok */ int __attribute__((no_instrument_function)) trace_init(void *buff, size_t buff_size) @@ -284,6 +345,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; @@ -327,7 +390,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; @@ -335,6 +398,11 @@ int __attribute__((no_instrument_function)) trace_init(void *buff, } #ifdef CONFIG_TRACE_EARLY +/** + * trace_early_init() - initialize the tracing system for early tracing + * + * Return: 0 if ok, -ENOSPC if not enough memory is available + */ int __attribute__((no_instrument_function)) trace_early_init(void) { ulong func_count = gd->mon_len / FUNC_SITE_SIZE; @@ -361,7 +429,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;