From 6b5cbe4f6329a608a916b74cf5a2dff12546827e Mon Sep 17 00:00:00 2001 From: Jaymes Wilks Date: Wed, 17 Feb 2016 14:08:22 -0600 Subject: 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 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Elizabeth K. Liner Reviewed-by: Daniel M. Crowell Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/24218 Reviewed-by: Jay M. Azurin --- src/usr/trace/HBconfig | 7 +++ src/usr/trace/service.C | 111 +++++++++++++++++++++++++++++++++++++++++++++++- src/usr/trace/service.H | 14 +++++- 3 files changed, 130 insertions(+), 2 deletions(-) (limited to 'src/usr/trace') diff --git a/src/usr/trace/HBconfig b/src/usr/trace/HBconfig index 6aacf8ddb..9d523d3f1 100644 --- a/src/usr/trace/HBconfig +++ b/src/usr/trace/HBconfig @@ -4,6 +4,13 @@ config CONSOLE_OUTPUT_TRACE help Enables output of trace to console. +config CONSOLE_TRACE_LITE + default n + depends on CONSOLE + help + Enables lightweight binary trace to console. + The binary data can be piped through a tool to make it readable. + config CONSOLE_OUTPUT_TRACE_COMP_NAME default n depends on CONSOLE_OUTPUT_TRACE 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 #include #include +#include + 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::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::instance().setTraceLite(i_isEnabled); + } + + uint8_t Service::getTraceLite() + { + return iv_traceLite; + } + + uint8_t getTraceLite() + { + return Singleton::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(&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(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(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(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, diff --git a/src/usr/trace/service.H b/src/usr/trace/service.H index e32dc1792..52cc81399 100644 --- a/src/usr/trace/service.H +++ b/src/usr/trace/service.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2015 */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -145,6 +145,16 @@ namespace TRACE */ void flushBuffers(); + /** @brief Sets TraceLite as enabled or disabled. + * @param[in] i_isEnabled - 1 for enabled, 0 for disabled + */ + void setTraceLite(uint8_t i_isEnabled); + + /** @brief Gets TraceLite setting (either enabled or disabled). + * @return 1 for enabled, 0 for disabled + */ + uint8_t getTraceLite(); + friend class TRACEDAEMON::Daemon; private: @@ -160,6 +170,8 @@ namespace TRACE static Service* getGlobalInstance(); /** Copy the current time into the timestamp. */ void _createTimeStamp(trace_entry_stamp_t* o_entry); + /** tracelite enabled **/ + uint8_t iv_traceLite; #endif }; } -- cgit v1.2.1