diff options
author | Jaymes Wilks <mjwilks@us.ibm.com> | 2016-02-17 14:08:22 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-05-10 11:30:41 -0400 |
commit | 6b5cbe4f6329a608a916b74cf5a2dff12546827e (patch) | |
tree | abe0d913c7f5d7212c082462133069c168cd602a /src/usr/trace/service.C | |
parent | 9f8d0889827da64842444c8ba5a0d26e38520b2c (diff) | |
download | talos-hostboot-6b5cbe4f6329a608a916b74cf5a2dff12546827e.tar.gz talos-hostboot-6b5cbe4f6329a608a916b74cf5a2dff12546827e.zip |
Output native trace data to console
Trace data is printed as ascii hex values to console when turned on.
Traces can now be recreated using a command line tool and the
hbotStringFile.
Change-Id: I8e8a95945002a9acbe555d1e75482d289c7ef8fa
BackPort: no
RTC:143820
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/21593
Tested-by: Jenkins Server
Tested-by: FSP CI Jenkins
Reviewed-by: Stephen M. Cprek <smcprek@us.ibm.com>
Tested-by: Jenkins OP Build CI
Tested-by: Jenkins OP HW
Reviewed-by: Elizabeth K. Liner <eliner@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24218
Reviewed-by: Jay M. Azurin <jmazurin@us.ibm.com>
Diffstat (limited to 'src/usr/trace/service.C')
-rw-r--r-- | src/usr/trace/service.C | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/src/usr/trace/service.C b/src/usr/trace/service.C index d2922b302..aeafc929d 100644 --- a/src/usr/trace/service.C +++ b/src/usr/trace/service.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ @@ -41,6 +41,8 @@ #include <console/consoleif.H> #include <stdio.h> #include <ctype.h> +#include <util/sprintf.H> + namespace TRACE { @@ -50,6 +52,9 @@ namespace TRACE iv_buffers[BUFFER_SLOW] = new Buffer(iv_daemon, Buffer::UNLIMITED); iv_buffers[BUFFER_FAST] = new Buffer(iv_daemon); iv_compList = &(Singleton<ComponentList>::instance()); + + // initialize tracelite setting to off + iv_traceLite = 0; } Service::~Service() @@ -58,6 +63,26 @@ namespace TRACE assert(0); } + void Service::setTraceLite(uint8_t i_isEnabled) + { + iv_traceLite = i_isEnabled; + } + + void setTraceLite(uint8_t i_isEnabled) + { + Singleton<Service>::instance().setTraceLite(i_isEnabled); + } + + uint8_t Service::getTraceLite() + { + return iv_traceLite; + } + + uint8_t getTraceLite() + { + return Singleton<Service>::instance().getTraceLite(); + } + void Service::writeEntry(ComponentDesc* i_td, trace_hash_val i_hash, const char * i_fmt, @@ -92,6 +117,10 @@ namespace TRACE } #endif + // copy args for use with openpower trace lite + va_list l_tl_args; + va_copy(l_tl_args, i_args); + do { // Get the right buffer for this component. @@ -187,6 +216,62 @@ namespace TRACE l_binEntry->head.hash = i_hash; l_binEntry->head.line = i_line; + // Define a buffer class to hold the formatting for tracelite. + // This is needed to avoid heap allocation of the tracelite + // format string. This code is called many times per second + // regardless of whether tracelite is enabled. We prefer not to + // increase the number of page faults occuring in this code path. + // Using std::string is a no-no as it calls new behind the scenes. + // This class should not be separated from its methods in a header + // file because: + // 1. It needs to be inline (for performance). + // 2. It is a special purpose class and should not be called + // anywhere else due to its buffer overflow potential + // if used incorrectly. + class CharBuffer { + char a[TRAC_MAX_ARGS * 8 + 20]; + // TRAC_MAX_ARGS is the number of arguments allowed + // an arg's format is 8 characters worst case. ex: "%.16llX " + // the string "trace_lite " is 11 characters + // the hash plus a space is 9 characters + char* s; // position + public: + CharBuffer() + { + s = a; + } + void append(const char* str) + { + const char *c = str; + // strcat cannot be used here because it does not give us + // the length of string so we'd need to recompute + while(*c != '\0') + { + // will not overrun because of TRAC_MAX_ARGS limit + *s++ = *c++; + } + } + char* operator*() + { + *s = '\0'; + return a; + } + }; + + // use this buffer to hold the formatting for tracelite output + CharBuffer l_cb; + + // use the string "trace_lite " to indicate to the receiving tool + // that we are about to send a hash and some arguments + l_cb.append("trace_lite "); + + { // allocate 10 bytes on the stack + char hashstring[10]; // 8 characters plus space plus null char + sprintf(hashstring,"%.8X ",i_hash); + l_cb.append(hashstring); + } // free 10 bytes on the stack + + const char* l_s = NULL; // pointer to format string to append // Copy arguments into the 'fsp-trace' entry's data section. char* l_dataOut = reinterpret_cast<char*>(&l_binEntry->data[0]); @@ -199,6 +284,9 @@ namespace TRACE uint32_t strSize = strlen(str); memcpy(l_dataOut, str, strSize+1); + + l_s = "\"%s\" "; // format string fragment for tracelite + l_dataOut += ALIGN_4(strSize + 1); } // Single character. @@ -207,12 +295,17 @@ namespace TRACE *(reinterpret_cast<uint32_t*>(l_dataOut)) = va_arg(i_args, uint32_t); l_dataOut += sizeof(uint32_t); + + l_s = "%.8X "; // set formatting for tracelite } // Doubles. else if (l_double_map & (1 << i)) { *(reinterpret_cast<double*>(l_dataOut)) = va_arg(i_args, double); + + l_s = "%.16llX "; // set formatting for tracelite + l_dataOut += sizeof(double); } // All others (as uint64_t's). @@ -220,14 +313,30 @@ namespace TRACE { *(reinterpret_cast<uint64_t*>(l_dataOut)) = va_arg(i_args, uint64_t); + + l_s = "%.16llX "; // set formatting for tracelite + l_dataOut += sizeof(uint64_t); } + l_cb.append(l_s); // append to format string for tracelite } +#ifdef CONFIG_CONSOLE_TRACE_LITE + CONSOLE::vdisplayf(i_td->iv_compName, *l_cb, l_tl_args); +#else + if (iv_traceLite) + { + CONSOLE::vdisplayf(i_td->iv_compName, *l_cb, l_tl_args); + } +#endif + // "Commit" entry to buffer. l_buffer->commitEntry(l_entry); } while(0); + + va_end(l_tl_args); // for trace lite + } void Service::writeBinEntry(ComponentDesc* i_td, |