diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2019-06-02 13:05:08 +0200 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2019-07-10 16:52:58 -0600 |
commit | a2fa38da200cbd454bcb8dc7659bde00044302f7 (patch) | |
tree | dc3068e5466c4582bbc037c3d52800fce802496d /lib | |
parent | 7ef8e9b09a74567c529f168a4da5c1d5cffd58c2 (diff) | |
download | u-boot-a2fa38da200cbd454bcb8dc7659bde00044302f7.zip u-boot-a2fa38da200cbd454bcb8dc7659bde00044302f7.tar.gz u-boot-a2fa38da200cbd454bcb8dc7659bde00044302f7.tar.bz2 |
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 <xypron.glpk@gmx.de>
Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/trace.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/trace.c b/lib/trace.c index 9956442..a13e5bf 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; |