mtd: nand: Get rid of busw parameter
[platform/kernel/u-boot.git] / lib / trace.c
index ad5e07b..505a318 100644 (file)
@@ -1,19 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (c) 2012 The Chromium OS Authors.
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <mapmem.h>
+#include <time.h>
 #include <trace.h>
+#include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/sections.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static char trace_enabled __attribute__((section(".data")));
-static char trace_inited __attribute__((section(".data")));
+static char trace_enabled __section(".data");
+static char trace_inited __section(".data");
 
 /* The header block at the start of the trace memory area */
 struct trace_hdr {
@@ -57,6 +58,49 @@ static inline uintptr_t __attribute__((no_instrument_function))
        return offset / FUNC_SITE_SIZE;
 }
 
+#if defined(CONFIG_EFI_LOADER) && (defined(CONFIG_ARM) || defined(CONFIG_RISCV))
+
+/**
+ * trace_gd - the value of the gd register
+ */
+static volatile gd_t *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 gd_t *temp_gd = trace_gd;
+
+       trace_gd = gd;
+       set_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)
 {
@@ -87,13 +131,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)
@@ -101,6 +145,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) {
@@ -112,44 +157,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;
 
@@ -160,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;
@@ -184,16 +230,29 @@ 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;
 }
 
-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;
 
@@ -228,11 +287,14 @@ 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;
 }
 
-/* Print basic information about tracing */
+/**
+ * trace_print_stats() - print basic information about tracing
+ */
 void trace_print_stats(void)
 {
        ulong count;
@@ -271,10 +333,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)
@@ -283,6 +346,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;
@@ -295,7 +360,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,
@@ -303,7 +369,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;
@@ -311,7 +377,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)
@@ -325,13 +391,19 @@ 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;
+
        return 0;
 }
 
 #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;
@@ -347,7 +419,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);
@@ -358,10 +430,11 @@ 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;
+
        return 0;
 }
 #endif