summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVan Lee <vanlee@us.ibm.com>2012-02-22 17:45:18 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-03-03 10:02:45 -0600
commit5e39cbfb113f2af65a17fde4317231e248051ac8 (patch)
treee2b7729f542574791413aa998de8d0a560451946 /src
parent6dea332771095c9a5891e2e7dea051cfc9e4f22d (diff)
downloadtalos-hostboot-5e39cbfb113f2af65a17fde4317231e248051ac8.tar.gz
talos-hostboot-5e39cbfb113f2af65a17fde4317231e248051ac8.zip
VPO continuous trace support for VBU (AWAN) execution environemt
Change-Id: Ib304cb0e203e4a4b69a07e824cb88581462463e2 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/687 Tested-by: Jenkins Server Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/build/debug/simics-debug-framework.py31
-rw-r--r--src/include/usr/trace/trace.H12
-rw-r--r--src/usr/trace/trace.C170
3 files changed, 175 insertions, 38 deletions
diff --git a/src/build/debug/simics-debug-framework.py b/src/build/debug/simics-debug-framework.py
index d29fb1bdc..9453440a6 100755
--- a/src/build/debug/simics-debug-framework.py
+++ b/src/build/debug/simics-debug-framework.py
@@ -234,6 +234,10 @@ def register_hb_debug_framework_tools():
pattern = re.compile("[^\._]");
files = [f for f in files if pattern.match(f)]
+ # Filter out modules written for vbu only
+ pattern = re.compile("AutoIpl|ContTrace");
+ files = [f for f in files if not pattern.match(f)]
+
# Remove the .pm extension from the tool modules.
files = [re.sub("\.pm","",f) for f in files];
@@ -291,6 +295,14 @@ def readLongLong(address):
hexlist = dumpSimicsMemory(address,8)
return hexDumpToNumber(hexlist)
+def readLong(address):
+ hexlist = dumpSimicsMemory(address,4)
+ return hexDumpToNumber(hexlist)
+
+def writeLong(address,datvalue):
+ conf.phys_mem.memory[[address,address+3]] = [0,0,0,datvalue]
+ return
+
# Write simics memory. address is an integer.
@@ -335,15 +347,26 @@ def magic_instruction_callback(user_arg, cpu, arg):
pTracBinaryBuffer = readLongLong(tracBinaryInfoAddr)
# Read the count of bytes used in the tracBinary buffer
cbUsed = readLongLong(tracBinaryInfoAddr+8)
+ triggerActive = readLong(tracBinaryInfoAddr+16)
+ if triggerActive == 0 and cbUsed == 1:
+ pTracBinaryBuffer = readLongLong(tracBinaryInfoAddr+24)
+ cbUsed = readLongLong(tracBinaryInfoAddr+32)
+ writeLong(tracBinaryInfoAddr+40,0)
+ # Reset the buffer byte count in Simics memory to 1, preserving
+ # the byte at offset 0 of the buffer which contains a 0x02 in
+ # fsp-trace style.
+ writeLongLong(tracBinaryInfoAddr+32,1)
+ else:
+ writeLong(tracBinaryInfoAddr+16,0)
+ # Reset the buffer byte count in Simics memory to 1, preserving
+ # the byte at offset 0 of the buffer which contains a 0x02 in
+ # fsp-trace style.
+ writeLongLong(tracBinaryInfoAddr+8,1)
# Save the tracBinary buffer to a file named tracBINARY in current dir
saveCommand = "memory_image_ln0.save tracBINARY 0x%x %d"%(pTracBinaryBuffer,cbUsed)
SIM_run_alone(run_command, saveCommand )
# Run fsp-trace on tracBINARY file (implied), append output to tracMERG
os.system( "fsp-trace ./ -s hbotStringFile >>tracMERG 2>/dev/null" )
- # Reset the buffer byte count in Simics memory to 1, preserving the byte
- # at offset 0 of the buffer which contains a 0x02 in fsp-trace style.
- writeLongLong(tracBinaryInfoAddr+8, 1 )
-
# Continuous trace: Open the symbols and find the address for
# "g_tracBinaryInfo" Convert to a number and save in tracBinaryInfoAddr
diff --git a/src/include/usr/trace/trace.H b/src/include/usr/trace/trace.H
index c894157fc..b8656ee3e 100644
--- a/src/include/usr/trace/trace.H
+++ b/src/include/usr/trace/trace.H
@@ -388,6 +388,16 @@ private:
const uint32_t i_size,
const int32_t i_type);
+ /**
+ * @brief This function manages the usage of the two ping-pong buffers
+ * for handling the continuous trace support under VPO/VBU.
+ *
+ * @param [in] i_cbRequired number of bytes needed for the trace entry
+ * to be added to the active continuous trace buffer
+ *
+ * @return void
+ */
+ void ManageContTraceBuffers(uint64_t i_cbRequired);
// Mutex protecting/serializing writes to trace buffers.
mutex_t iv_trac_mutex;
@@ -395,6 +405,8 @@ private:
// Controls writing to tracBinary
bool iv_ContinuousTrace;
+ // VPO/VBU continuous trace active buffer index
+ uint8_t iv_CurBuf;
};
} // namespace TRACE
diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C
index 29e7f7771..e2484ad35 100644
--- a/src/usr/trace/trace.C
+++ b/src/usr/trace/trace.C
@@ -51,6 +51,7 @@
#include <sys/sync.h>
#include <string_ext.h>
#include <util/align.H>
+#include <assert.h>
#include <trace/trace.H>
@@ -67,7 +68,7 @@ namespace TRACE
// Globals/Constants
/******************************************************************************/
-const uint32_t TRAC_TIME_REAL = 0; // upper 32 = seconds, lower 32 = microseconds
+const uint32_t TRAC_TIME_REAL = 0; // upper 32 = secs, lower 32 = microsecs
const uint32_t TRAC_TIME_50MHZ = 1;
const uint32_t TRAC_TIME_200MHZ = 2;
const uint32_t TRAC_TIME_167MHZ = 3; // 166666667Hz
@@ -115,11 +116,32 @@ struct mixed_trace_info
{
char * pBuffer;
uint64_t cbUsed;
+ uint32_t TriggerActive;
+ uint32_t LostTraceCount;
};
typedef struct mixed_trace_info mixed_trace_info_t;
const uint64_t TRAC_BINARY_SIZE = 4096;
-mixed_trace_info_t g_tracBinaryInfo;
+mixed_trace_info_t g_tracBinaryInfo[2];
+struct vpo_con_trigger_t
+{
+ uint64_t trig; // bit0 = trigger signalling bit1:63 = trace buffer addr
+ uint64_t len; // length of trace buffer with valid trace data.
+};
+
+struct vpo_cont_support_t
+{
+ vpo_con_trigger_t triggers[2];
+ uint64_t disable; // clear by VPO script to enable continous trace
+};
+
+// This structure is monitored by VPO script. The disable variable is set
+// at compile time to 1. The VPO script clears the disable variable at thei
+// start to enable the continuous trace support for VPO. It then montiors the
+// trigger active bit of each buffer and take action.
+vpo_cont_support_t g_cont_trace_trigger_info = { { { 0, 0 }, { 0, 0 } }, 1 };
+
+const uint64_t TRIGGER_ACTIVE_BIT = 0x8000000000000000;
/******************************************************************************/
// TracInit::TracInit()
@@ -155,16 +177,26 @@ 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;
+ for (size_t i = 0; i < 2; i++)
+ {
+ g_tracBinaryInfo[i].pBuffer =
+ static_cast<char*>(malloc(TRAC_BINARY_SIZE));
+ g_tracBinaryInfo[i].pBuffer[0] = 2;
+ g_tracBinaryInfo[i].cbUsed = 1;
+ g_tracBinaryInfo[i].TriggerActive = 0;
+ g_tracBinaryInfo[i].LostTraceCount = 0;
+ g_cont_trace_trigger_info.triggers[i].trig =
+ reinterpret_cast<uint64_t>(g_tracBinaryInfo[i].pBuffer);
+ }
// 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;
+
+ // select buffer0 initially
+ iv_CurBuf = 0;
}
/******************************************************************************/
@@ -308,6 +340,67 @@ void Trace::initValuesBuffer( trace_desc_t *o_buf,
return;
}
+/******************************************************************************/
+// ManageContTraceBuffers
+// This function manages the usage of the two ping-pong buffers for handling
+// the continuous trace support.
+/******************************************************************************/
+void Trace::ManageContTraceBuffers(uint64_t i_cbRequired)
+{
+ uint8_t l_AltBuf = (iv_CurBuf + 1) % 2;
+
+ // Reset TriggerActive if the buffer has been offloaded by VPO
+ // script when running under VBU Awan environment
+ for (size_t i = 0; (!(g_cont_trace_trigger_info.disable)) && (i < 2); i++)
+ {
+ if ((g_tracBinaryInfo[i].TriggerActive != 0) &&
+ (!(g_cont_trace_trigger_info.triggers[i].trig &
+ TRIGGER_ACTIVE_BIT)))
+ {
+ g_tracBinaryInfo[i].TriggerActive = 0;
+ }
+ }
+
+ // we should never have the current buffer in the trigger state
+ assert (g_tracBinaryInfo[iv_CurBuf].TriggerActive == 0);
+
+ // current buffer is not in trigger state
+ // and adding this trace will exceed the size
+ if ((g_tracBinaryInfo[iv_CurBuf].cbUsed + i_cbRequired)
+ > TRAC_BINARY_SIZE)
+ {
+ // current buffer entering trigger state
+ g_tracBinaryInfo[iv_CurBuf].TriggerActive = 1;
+
+ if (!(g_cont_trace_trigger_info.disable))
+ {
+ // Turn on the current buffer's trigger
+ g_cont_trace_trigger_info.triggers[iv_CurBuf].trig |=
+ TRIGGER_ACTIVE_BIT;
+ // If the alternate buffer's trigger is active and
+ // the buffer will now be reused, so reset the trigger
+ if (g_cont_trace_trigger_info.triggers[l_AltBuf].trig &
+ TRIGGER_ACTIVE_BIT)
+ {
+ g_cont_trace_trigger_info.triggers[l_AltBuf].trig &=
+ ~TRIGGER_ACTIVE_BIT;
+ }
+ }
+
+ // If the alternate buffer is in trigger state, move it out of
+ // the trigger state and keep track of lost trace count.
+ if (g_tracBinaryInfo[l_AltBuf].TriggerActive == 1)
+ {
+ g_tracBinaryInfo[l_AltBuf].LostTraceCount++;
+ g_tracBinaryInfo[l_AltBuf].TriggerActive = 0;
+ }
+ // Now switching to alternate buffer and reset the usage count
+ iv_CurBuf = l_AltBuf;
+ g_tracBinaryInfo[iv_CurBuf].cbUsed = 1;
+
+ MAGIC_INSTRUCTION(MAGIC_CONTINUOUS_TRACE);
+ }
+}
/******************************************************************************/
@@ -562,26 +655,27 @@ void Trace::_trace_adal_write_all(trace_desc_t *io_td,
// Write to the combined trace buffer, a stream of traces.
- if( iv_ContinuousTrace )
+ 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 ) +
- l_data_size;
+ uint64_t l_cbRequired = l_cbCompName + sizeof(l_entry) +
+ l_data_size;
- if( (g_tracBinaryInfo.cbUsed + l_cbRequired) > TRAC_BINARY_SIZE )
+ if (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;
+ // caller is logging more binary data than the
+ // maximum size of the current tracBinary buffer.
+ // TODO need to increase the buffer size, or else
+ // document its limits.
+ break;
}
+ ManageContTraceBuffers(l_cbRequired);
+
// Copy the entry piecemeal to the destination.
- char * l_pchDest = g_tracBinaryInfo.pBuffer + g_tracBinaryInfo.cbUsed;
+ char * l_pchDest = g_tracBinaryInfo[iv_CurBuf].pBuffer +
+ g_tracBinaryInfo[iv_CurBuf].cbUsed;
// component name and its trailing nil byte
strcpy( l_pchDest, io_td->comp );
@@ -595,7 +689,17 @@ void Trace::_trace_adal_write_all(trace_desc_t *io_td,
memcpy( l_pchDest, l_buffer, l_data_size );
// adjust for next time
- g_tracBinaryInfo.cbUsed += l_cbRequired;
+ g_tracBinaryInfo[iv_CurBuf].cbUsed += l_cbRequired;
+
+ // maintain the buffer's actually used bytes for VPO script
+ if ((!g_cont_trace_trigger_info.disable))
+ {
+ g_cont_trace_trigger_info.triggers[iv_CurBuf].len =
+ g_tracBinaryInfo[iv_CurBuf].cbUsed;
+ }
+
+ // break from while() which was used much like an if()
+ break;
}
@@ -710,31 +814,22 @@ void Trace::_trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_has
{
// 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;
+ 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.
+ // maximum size of the current 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;
- }
+ ManageContTraceBuffers(l_cbRequired);
// Copy the entry piecemeal to the destination.
- char * l_pchDest = g_tracBinaryInfo.pBuffer + g_tracBinaryInfo.cbUsed;
+ char * l_pchDest = g_tracBinaryInfo[iv_CurBuf].pBuffer +
+ g_tracBinaryInfo[iv_CurBuf].cbUsed;
// component name and its trailing nil byte
strcpy( l_pchDest, io_td->comp );
@@ -748,7 +843,14 @@ void Trace::_trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_has
memcpy( l_pchDest, i_ptr, i_size );
// adjust for next time
- g_tracBinaryInfo.cbUsed += l_cbRequired;
+ g_tracBinaryInfo[iv_CurBuf].cbUsed += l_cbRequired;
+
+ // maintain the buffer's actually used bytes for VPO script
+ if ((!g_cont_trace_trigger_info.disable))
+ {
+ g_cont_trace_trigger_info.triggers[iv_CurBuf].len =
+ g_tracBinaryInfo[iv_CurBuf].cbUsed;
+ }
// break from while() which was used much like an if()
break;
OpenPOWER on IntegriCloud