summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorMonte Copeland <copelanm@us.ibm.com>2012-01-10 11:18:17 -0600
committerMIKE J. JONES <mjjones@us.ibm.com>2012-01-11 08:25:29 -0600
commit5ee1ae9ca220345b5780ece69ed1c9888a1996a1 (patch)
tree32ad66cb9562f779cd730a9eae286e296e23d2cd /src/usr
parent7a8bc7106aee3772bb978ff9d4f0a33ab7e8e90f (diff)
downloadtalos-hostboot-5ee1ae9ca220345b5780ece69ed1c9888a1996a1.tar.gz
talos-hostboot-5ee1ae9ca220345b5780ece69ed1c9888a1996a1.zip
Simics continuous trace
Change-Id: I5f5d9c30b4cc0f0d8704fb99c10757e0f41018bf Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/603 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Reviewed-by: Mark W. Wenning <wenning@us.ibm.com> Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/trace/makefile2
-rw-r--r--src/usr/trace/trace.C162
2 files changed, 141 insertions, 23 deletions
diff --git a/src/usr/trace/makefile b/src/usr/trace/makefile
index b18e48661..c025957c0 100644
--- a/src/usr/trace/makefile
+++ b/src/usr/trace/makefile
@@ -23,7 +23,7 @@
ROOTPATH = ../../..
MODULE = trace
-OBJS = trace.o tracebuffer.o assert.o
+OBJS = trace.o assert.o
SUBDIRS = test.d
diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C
index bb3ca81e5..6efe9fbd6 100644
--- a/src/usr/trace/trace.C
+++ b/src/usr/trace/trace.C
@@ -75,7 +75,7 @@ const uint32_t TRAC_TIME_167MHZ = 3; // 166666667Hz
-// WARNING: Changing the size of the trace buffer name string requires a
+// WARNING: Changing the size of the trace buffer name string requires a
// changing OFFSET_BUFFER_ADDRESS in src/build/debug/Hostboot/Trace.pm.
const uint32_t COMP_NAME_SIZE = 16; // includes NULL terminator, so 15 max
@@ -87,15 +87,15 @@ const uint64_t TRAC_DEFAULT_BUFFER_SIZE = 0x0800; //2KB
// The number of trace buffers.
// NOTE: This constant should only be changed to an even number for now.
-// WARNING: Changing the count of buffers requires a co-req change
+// WARNING: Changing the count of buffers requires a co-req change
// in src/build/debug/Hostboot/Trace.pm which has this count hard coded.
const uint64_t TRAC_MAX_NUM_BUFFERS = 48;
// An array of these structs accounts for all the trace buffers in Hostboot.
-// WARNING: Changing the size of trace_desc_array requires a co-req change
+// WARNING: Changing the size of trace_desc_array requires a co-req change
// in src/build/debug/Hostboot/Trace.pm which has hard-coded the size of
-// this structure.
-typedef struct trace_desc_array
+// this structure.
+typedef struct trace_desc_array
{
char comp[COMP_NAME_SIZE]; // the buffer name
trace_desc_t * td_entry; // pointer to the buffer
@@ -105,6 +105,21 @@ typedef struct trace_desc_array
trace_desc_array_t g_desc_array[TRAC_MAX_NUM_BUFFERS];
+// Set up a structure to hold information about the mixed-trace
+// or continuous-trace buffer, aka tracBINARY.
+
+// WARNING: Changes to this structure will require co-req changes to
+// src/build/debug/simics-debug-framework.py which contains the simics
+// hap handler for extracting this buffer.
+struct mixed_trace_info
+{
+ char * pBuffer;
+ uint64_t cbUsed;
+};
+typedef struct mixed_trace_info mixed_trace_info_t;
+const uint64_t TRAC_BINARY_SIZE = 4096;
+mixed_trace_info_t g_tracBinaryInfo;
+
/******************************************************************************/
// TracInit::TracInit()
@@ -139,6 +154,17 @@ Trace::Trace()
// compiler inits global vars to zero
// memset(g_desc_array, 0, sizeof(g_desc_array));
+
+ g_tracBinaryInfo.pBuffer = static_cast<char*>(malloc(TRAC_BINARY_SIZE));
+
+ // fsp-trace convention expects a 2 in the first byte of tracBINARY
+ g_tracBinaryInfo.pBuffer[0] = 2;
+ g_tracBinaryInfo.cbUsed = 1;
+
+ // tracBINARY buffer appending is always on.
+ // TODO figure a way to control continuous trace on/off, perhaps
+ // unregister the hap handler for it.
+ iv_ContinuousTrace = 1;
}
/******************************************************************************/
@@ -428,22 +454,18 @@ void Trace::_trace_adal_write_all(trace_desc_t *io_td,
l_entry.head.hash = i_hash;
l_entry.head.line = i_line;
- // Time stamp
- convertTime(&l_entry.stamp);
// Calculate total space needed for the entry, which is a
// combination of the data size from above, the entry
// headers, and an overall length field.
- l_entry_size = l_data_size;
- l_entry_size += sizeof(trace_entry_stamp_t);
- l_entry_size += sizeof(trace_entry_head_t);
-
- // We always add the size of the entry at the end of the trace entry
- // so the parsing tool can easily walk the trace buffer stack so we
- // need to add that on to total size
- l_entry_size += sizeof(uint32_t);
-
- // Word align the entry
+ l_entry_size = l_data_size +
+ sizeof(trace_entry_stamp_t) +
+ sizeof(trace_entry_head_t) +
+ // Allow for a uint32 at the end of the trace entry
+ // so parsers may walk the trace buffer backwards
+ sizeof(uint32_t);
+
+ // Round up the size to the next word boundary
l_entry_size = ALIGN_4(l_entry_size);
// Allocate buffer for the arguments we're tracing
@@ -502,12 +524,14 @@ void Trace::_trace_adal_write_all(trace_desc_t *io_td,
va_end(l_args);
- // We now have total size and need to reserve a part of the trace
- // buffer for this
+ // Write entry to the trace buffer.
// CRITICAL REGION START
mutex_lock(&iv_trac_mutex);
+ // time stamp the entry with time-base register
+ convertTime(&l_entry.stamp);
+
// Update the entry count
io_td->te_count++;
@@ -527,6 +551,46 @@ void Trace::_trace_adal_write_all(trace_desc_t *io_td,
static_cast<void *>(&l_entry_size),
sizeof(l_entry_size));
+
+
+ // Write to the combined trace buffer, a stream of traces.
+ if( iv_ContinuousTrace )
+ {
+ // This entry requires this many bytes to fit.
+ uint64_t l_cbCompName = 1 + strlen( io_td->comp );
+ uint64_t l_cbRequired = l_cbCompName +
+ sizeof( l_entry ) +
+ l_data_size;
+
+ if( (g_tracBinaryInfo.cbUsed + l_cbRequired) > TRAC_BINARY_SIZE )
+ {
+ // does not fit, so call somebody to collect it.
+ // TODO how to do this in VBU
+ MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE);
+
+ // start over
+ g_tracBinaryInfo.cbUsed = 1;
+ }
+
+ // Copy the entry piecemeal to the destination.
+ char * l_pchDest = g_tracBinaryInfo.pBuffer + g_tracBinaryInfo.cbUsed;
+
+ // component name and its trailing nil byte
+ strcpy( l_pchDest, io_td->comp );
+ l_pchDest += l_cbCompName;
+
+ // trace entry
+ memcpy( l_pchDest, &l_entry, sizeof(l_entry));
+ l_pchDest += sizeof(l_entry);
+
+ // trace entry data
+ memcpy( l_pchDest, l_buffer, l_data_size );
+
+ // adjust for next time
+ g_tracBinaryInfo.cbUsed += l_cbRequired;
+ }
+
+
mutex_unlock(&iv_trac_mutex);
// CRITICAL REGION END
@@ -606,12 +670,13 @@ void Trace::_trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_has
// We now have total size and need to reserve a part of the trace
// buffer for this
- // Time stamp
- convertTime(&l_entry.stamp);
-
// CRITICAL REGION START
mutex_lock(&iv_trac_mutex);
+
+ // time stamp the entry with time-base register
+ convertTime(&l_entry.stamp);
+
// Increment trace counter
io_td->te_count++;
@@ -630,6 +695,58 @@ void Trace::_trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_has
static_cast<void *>(&l_entry_size),
sizeof(l_entry_size));
+ // Write to the combined trace buffer, a stream of traces.
+ // A while() here affords use of break to break out on
+ // an error condition.
+ while( iv_ContinuousTrace )
+ {
+ // This entry requires this many bytes to fit.
+ uint64_t l_cbCompName = 1 + strlen( io_td->comp );
+ uint64_t l_cbRequired = l_cbCompName +
+ sizeof( l_entry ) +
+ i_size;
+
+ if( l_cbRequired > TRAC_BINARY_SIZE )
+ {
+ // caller is logging more binary data than the
+ // size of the tracBinary buffer.
+ // TODO need to increase the buffer size, or else
+ // document its limits.
+ break;
+ }
+
+ if( (g_tracBinaryInfo.cbUsed + l_cbRequired) > TRAC_BINARY_SIZE )
+ {
+ // does not fit, so call somebody to collect it.
+ // TODO
+ MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE);
+
+ // start over
+ g_tracBinaryInfo.cbUsed = 1;
+ }
+
+ // Copy the entry piecemeal to the destination.
+ char * l_pchDest = g_tracBinaryInfo.pBuffer + g_tracBinaryInfo.cbUsed;
+
+ // component name and its trailing nil byte
+ strcpy( l_pchDest, io_td->comp );
+ l_pchDest += l_cbCompName;
+
+ // trace entry
+ memcpy( l_pchDest, &l_entry, sizeof(l_entry));
+ l_pchDest += sizeof(l_entry);
+
+ // trace entry data
+ memcpy( l_pchDest, i_ptr, i_size );
+
+ // adjust for next time
+ g_tracBinaryInfo.cbUsed += l_cbRequired;
+
+ // break from while() which was used much like an if()
+ break;
+ }
+
+
// CRITICAL REGION END
mutex_unlock(&iv_trac_mutex);
@@ -745,6 +862,7 @@ void Trace::convertTime(trace_entry_stamp_t *o_entry)
+
/******************************************************************************/
// findTdByName
/******************************************************************************/
OpenPOWER on IntegriCloud