summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/build/trace/traceHB.py258
-rw-r--r--src/usr/example/example.C2
-rw-r--r--src/usr/trace/test/tracetest.H47
-rw-r--r--src/usr/trace/trace.C201
4 files changed, 442 insertions, 66 deletions
diff --git a/src/build/trace/traceHB.py b/src/build/trace/traceHB.py
index 827c1a2bb..47ed1125b 100755
--- a/src/build/trace/traceHB.py
+++ b/src/build/trace/traceHB.py
@@ -8,63 +8,150 @@
# 1. Load file
# simics> run-python-file <gitrepo>/src/build/trace/traceHB.py
# 2. Display global trace buffer
-# simics> @traceHB("<gitrepo>/img/hbicore.syms", <path>/trexStringFile")
+# simics> @traceHB("<compName1>,<compName2>,...", <git.repo>/img/hbicore.syms", <git.repo>/img/hbotStringFile")
# 3. Display kernel printk buffer
-# simics> @printkHB("<gitrepo>/img/hbicore.syms")
-#
-# Example:
-# run-python-file /gsa/ausgsa/home/c/a/camvanng/HOSTBOOT/src/build/trace/traceHB.py
-# @traceHB("/gsa/ausgsa/home/c/a/camvanng/HOSTBOOT/img/hbicore.syms","/gsa/ausgsa/home/c/a/camvanng/HOSTBOOT/obj/modules/example/example.o.hash")
-# @printkHB("/gsa/ausgsa/home/c/a/camvanng/HOSTBOOT/img/hbicore.syms")
-
-# *** Change History
-#
-# 05/10/2011 camvanng Created
+# simics> @printkHB("<git.repo>/img/hbicore.syms")
import os,sys
import conf
import configuration
import cli
+import binascii
# Function to dump the global trace buffer
-def traceHB(symsFile, trexStringFile):
+def traceHB(compStr, symsFile, stringFile):
+
+ # "constants"
+ DESC_ARRAY_ENTRY_SIZE = 24
+ DESC_ARRAY_ENTRY_ADDR_SIZE = 8
+ DESC_ARRAY_ENTRY_COMP_NAME_SIZE = 16
+ MAX_NUM_BUFFERS = 24
+ MAX_COMP_NAME_SIZE = DESC_ARRAY_ENTRY_COMP_NAME_SIZE - 1 #minus null termination
print
- #Find location of g_trac_global variable from the image's .syms file
- #i.e. grep g_trac_global <gitrepo>/img/hbicore.syms
+ #Find location of g_desc_array variable from the image's .syms file
for line in open(symsFile):
- if "g_trac_global" in line: #if found
+
+ if "g_desc_array" in line: #if found
+
#print line
x = line.split(",")
- addr = int(x[1],16) #address of g_trac_global
- #print "addr = 0x%x"%(addr)
- size = int(x[3],16) #size of g_trac_global
- #print "size = 0x%x"%(size)
+ array_addr = int(x[1],16) #address of g_desc_array
+ #print "g_desc_array addr = 0x%x"%(array_addr)
+ array_size = int(x[3],16) #size of g_desc_array
+ #print "g_desc_array size = 0x%x"%(array_size)
- #get address of global trace buffer
- string = "phys_mem.x 0x%x 0x%x"%(addr,size)
+ # content of g_desc_array
+ #string = "phys_mem.x 0x%x 0x%x"%(array_addr,array_size)
#print string
- result,message = quiet_run_command(string)
+ #result,message = quiet_run_command(string)
#print message
- lst = message.split()
- #print lst
- addr_str = ""
- for i in range(1,5):
- addr_str += lst[i]
- #print addr_str
- addr_global_trace_buffer = int(addr_str,16) #address of global trace buffer
-
- #save global trace buffer to <sandbox>/simics/trace.out
- string = "memory_image_ln0.save trace.out 0x%x 0x1000"%(addr_global_trace_buffer)
- #print string
- result = run_command(string)
- #print result
- #display formatted trace
- string = 'fsp-trace -s %s trace.out'%(trexStringFile)
- #print string
- os.system(string)
+ #flag to indicate if we found any buffer
+ buffer_found = 0;
+
+ #Parse the compStr argument for the list of component buffers requested
+ compList = compStr.split(",")
+ #print compList
+ for compName in compList:
+
+ # Strip all whitespaces and limit to 15 bytes max
+ compName = compName.strip()
+ if (len(compName) > MAX_COMP_NAME_SIZE):
+ compName = compName[0:MAX_COMP_NAME_SIZE]
+ #print compName
+
+ #pointer to first entry of g_desc_array
+ entry_addr = array_addr
+
+ #find the component trace buffer
+ for entry in range (1, MAX_NUM_BUFFERS + 1):
+
+ #print "entry = 0x%x"%(entry)
+ string = "phys_mem.x 0x%x 0x%x"%(entry_addr,DESC_ARRAY_ENTRY_COMP_NAME_SIZE)
+ #print string
+ #example output of phys_mem.x is:
+ #simics> phys_mem.x 0x263c8 0x10
+ #p:0x000263c0 4465 7646 5700 0000 0 DevFW...
+ #p:0x000263d0 0000 0000 0000 0000 0 ........
+ result,message = quiet_run_command(string)
+ #print message
+ lst = message.split()
+ #print lst
+ #example output of lst (lst[1] = '4465'):
+ #['p:0x000263c0', '4465', '7646', '5700', '0000', '0', 'DevFW...',
+ #'p:0x000263d0', '0000', '0000', '0000', '0000', '0', '........']
+
+ # no more entry to search
+ if lst[1]=='0000':
+ break
+
+ # get component name from entry
+ name_str = lst[1]
+ count = 1
+ i = 2
+ while (count < (DESC_ARRAY_ENTRY_COMP_NAME_SIZE/2)):
+ if (lst[i] == '0000'):
+ break
+ if len(lst[i]) == 4:
+ name_str += lst[i]
+ count +=1
+ i += 1
+
+ #1st method:
+ #str = name_str.strip('00')
+ #if (compName.encode("hex")==str):
+ # print "we found the buffer"
+ #2nd method:
+ name_str = binascii.unhexlify(name_str)
+ #print name_str
+ str = name_str.strip('\0')
+
+ #We found the component buffer
+ if ((str == compName) or (len(compName) == 0)):
+
+ #get address of component trace buffer
+ string = "phys_mem.x 0x%x 0x%x"%(entry_addr + DESC_ARRAY_ENTRY_COMP_NAME_SIZE, DESC_ARRAY_ENTRY_ADDR_SIZE)
+ #print string
+ result,message = quiet_run_command(string)
+ #print message
+ lst = message.split()
+ #print lst
+
+ addr_str = ""
+ for i in range(1,(DESC_ARRAY_ENTRY_ADDR_SIZE/2) + 1):
+ addr_str += lst[i]
+ #print addr_str
+ addr_trace_buffer = int(addr_str,16)
+
+ #save trace buffer to <sandbox>/simics/trace.out
+ string = "memory_image_ln0.save tmp.out 0x%x 0x800"%(addr_trace_buffer)
+ #print string
+ result = run_command(string)
+ #print result
+
+ if (buffer_found == 0):
+ fd1 = open('trace.out','wb')
+ buffer_found = 1
+ else:
+ fd1 = open('trace.out','ab')
+ fd2 = open('tmp.out', 'rb')
+ fd1.write(fd2.read())
+ fd1.close()
+ fd2.close()
+
+ if (str == compName):
+ break
+
+ # Increment address to next entry in g_desc_array
+ entry_addr += DESC_ARRAY_ENTRY_SIZE
+
+ if (buffer_found == 1):
+ #display formatted trace
+ string = 'fsp-trace -s %s trace.out'%(stringFile)
+ #print string
+ os.system(string)
print
break
@@ -103,3 +190,96 @@ def printkHB(symsFile):
break
return
+#===============================================================================
+# HOSTBOOT Commands
+#===============================================================================
+default_comp = ""
+default_syms = "hbicore.syms"
+default_stringFile = "hbotStringFile"
+#traceHB_relative_path = "../tools" # relative to $sb
+
+#------------------------------------------------
+#------------------------------------------------
+def hb_trace(str_arg1, str_arg2, str_arg3):
+ if ((str_arg1 == None) or (str_arg1 == "all") or (str_arg1 == "ALL") or (str_arg1 == "All")):
+ str_arg1 = default_comp
+ if str_arg2 == None:
+ if os.environ.has_key("HOSTBOOT_SYMS"):
+ str_arg2 = str(os.environ.get("HOSTBOOT_SYMS"))
+ else:
+ str_arg2 = default_syms
+ if str_arg3 == None:
+ if os.environ.has_key("HOSTBOOT_STRINGFILE"):
+ str_arg3 = str(os.environ.get("HOSTBOOT_STRINGFILE"))
+ else:
+ str_arg3 = default_stringFile
+
+ print "comp=%s" % str(str_arg1)
+
+ print "syms=%s" % str(str_arg2)
+ print "StringFile=%s" % str(str_arg3)
+ traceHB(str_arg1, str_arg2, str_arg3)
+ return None
+
+new_command("hb-trace",
+ hb_trace,
+ [arg(str_t, "comp", "?", None),
+ arg(str_t, "syms", "?", None),
+ arg(str_t, "stringFile", "?", None),
+ ],
+ #alias = "hbt",
+ type = ["hostboot-commands"],
+ #see_also = ["hb_printk"],
+ see_also = [ ],
+ short = "Display the hostboot trace",
+ doc = """
+Parameters: \n
+ in = component name \n
+ in = SYMS file \n
+ in = hostboot string file \n
+
+Defaults: \n
+ 'comp' = all buffers \n
+ 'syms' = './hbicore.syms' \n
+ 'stringFile' = './hbotStringFile' \n\n
+
+Examples: \n
+ hb-trace \n
+ hb-trace all \n
+ hb-trace ERRL ../hbicore.syms <git.repo>/img/hbotStringFile \n
+ """)
+
+#------------------------------------------------
+#------------------------------------------------
+def hb_printk(str_arg1):
+ if str_arg1 == None:
+ if os.environ.has_key("HOSTBOOT_SYMS"):
+ str_arg1 = str(os.environ.get("HOSTBOOT_SYMS"))
+ else:
+ str_arg1 = default_syms
+
+ print "syms=%s" % str(str_arg1)
+ printkHB(str_arg1)
+ return None
+
+new_command("hb-printk",
+ hb_printk,
+ [arg(str_t, "syms", "?", None),
+ ],
+ #alias = "hbt",
+ type = ["hostboot-commands"],
+ #see_also = ["hb-trace"],
+ see_also = [ ],
+ short = "Display the kernel printk buffer",
+ doc = """
+Parameters: \n
+ in = SYMS file \n
+
+Defaults: \n
+ 'syms' = './hbicore.syms' \n\n
+
+Examples: \n
+ hb-printk \n
+ hb-printk ../hbicore.syms \n
+ """)
+
diff --git a/src/usr/example/example.C b/src/usr/example/example.C
index 290d8abc4..287721e5a 100644
--- a/src/usr/example/example.C
+++ b/src/usr/example/example.C
@@ -7,9 +7,11 @@
#include <example/examplerc.H>
#include <errl/errlentry.H>
+#if 0
//static mutex_t value = MUTEX_INITIALIZER;
trace_desc_t *g_trac_test = NULL;
TRAC_INIT(&g_trac_test, "EXAMPLE", 4096);
+#endif
extern "C"
void _start(void *ptr)
diff --git a/src/usr/trace/test/tracetest.H b/src/usr/trace/test/tracetest.H
index 0767352c6..5b8e3d29b 100644
--- a/src/usr/trace/test/tracetest.H
+++ b/src/usr/trace/test/tracetest.H
@@ -10,6 +10,7 @@
#include <cxxtest/TestSuite.H>
//#include <trace/interface.H>
#include <tracinterface.H>
+#include <stdio.h>
class TraceTest : public CxxTest::TestSuite
{
@@ -123,6 +124,52 @@ public:
}
}
}
+
+ /**
+ * @test Test max component name size
+ */
+ void testTracCompName(void)
+ {
+ trace_desc_t *g_trac_test = NULL;
+ char l_comp[] = "EXAMPLE89ABCDEFGHI";
+
+ TRAC_INIT_BUFFER(&g_trac_test, l_comp, 4096);
+
+ if(g_trac_test == NULL)
+ {
+ TS_FAIL("g_trac_test was returned as NULL!");
+ }
+ else
+ {
+ TRACFCOMP(g_trac_test, INFO_MRK"Testing max component name");
+ }
+ }
+
+ /**
+ * @test Test max number of buffers
+ */
+ void testTracMaxBuffers(void)
+ {
+ trace_desc_t *g_trac_test = NULL;
+ char l_comp[8] = "TRACE";
+
+ for (uint32_t i=0; i < 26; i++)
+ {
+ sprintf (l_comp, "TRACE%d", i);
+
+ g_trac_test = NULL;
+ TRAC_INIT_BUFFER(&g_trac_test, l_comp, 4096);
+
+ if(g_trac_test == NULL)
+ {
+ TS_FAIL("g_trac_test was returned as NULL!");
+ }
+ else
+ {
+ TRACFCOMP(g_trac_test, INFO_MRK"Testing max buffers %u", i);
+ }
+ }
+ }
};
#endif
diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C
index 569af1e08..cdad6103c 100644
--- a/src/usr/trace/trace.C
+++ b/src/usr/trace/trace.C
@@ -15,6 +15,7 @@
#include <stdarg.h>
#include <arch/ppc.H>
#include <kernel/console.H>
+#include <kernel/pagemgr.H>
#include <limits.h>
#include <stdlib.h>
#include <sys/task.h>
@@ -37,12 +38,30 @@ const uint32_t TRAC_TIME_REAL = 0; // upper 32 = seconds, lower 32 = microsec
const uint32_t TRAC_TIME_50MHZ = 1;
const uint32_t TRAC_TIME_200MHZ = 2;
const uint32_t TRAC_TIME_167MHZ = 3; // 166666667Hz
-const uint32_t COMP_NAME_SIZE = 16;
+const uint32_t COMP_NAME_SIZE = 16; // NULL terminated string
-const uint64_t TRAC_DEFAULT_BUFFER_SIZE = 0x1000;
+// Initial implementation is to allocate a fixed 2KB buffer to each
+// component on request.
+// NOTE: any change to this value will require change to Trace::initBuffer()
+// since currently malloc() does not work for large allocations/fragmentations
+// and we are using PageManager::allocatePage() to allocate space for two
+// buffers at a time. Once malloc() works, we can remove this constraint.
+const uint64_t TRAC_DEFAULT_BUFFER_SIZE = 0x0800; //2KB
-// Global trace buffer. - Keep global so it can be found in syms file
-trace_desc_t *g_trac_global = NULL;
+// NOTE: This constant should only be changed to an even number for now.
+// Same reason as above.
+const uint64_t TRAC_MAX_NUM_BUFFERS = 24;
+
+const char * const TRAC_DEFAULT_BUFFER_NAME = "DEFAULT";
+
+// Global component trace buffer array. Initially allow for 24 buffers max.
+// Keep global so it can be found in syms file
+typedef struct trace_desc_array {
+ char comp[COMP_NAME_SIZE]; // the buffer name
+ trace_desc_t * td_entry; // pointer to the buffer
+}trace_desc_array_t;
+
+trace_desc_array_t g_desc_array[TRAC_MAX_NUM_BUFFERS];
/******************************************************************************/
// Trace::getTheInstance
@@ -59,10 +78,7 @@ Trace::Trace()
{
mutex_init(&iv_trac_mutex);
- g_trac_global = static_cast<trace_desc_t *>(malloc(TRAC_DEFAULT_BUFFER_SIZE));
-
- initValuesBuffer(g_trac_global,
- "GLOBAL");
+ memset(g_desc_array, 0, sizeof(g_desc_array));
}
/******************************************************************************/
@@ -83,15 +99,125 @@ void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp,
/*------------------------------------------------------------------------*/
/* Local Variables */
/*------------------------------------------------------------------------*/
+ uint32_t i = 0;
+ char * l_td = NULL;
+ char l_comp[COMP_NAME_SIZE] = {'\0'};
/*------------------------------------------------------------------------*/
/* Code */
/*------------------------------------------------------------------------*/
if(*o_td == NULL)
{
- // Just assign it to the global buffer since we only have
- // one buffer
- *o_td = g_trac_global;
+ // Limit component name to 15 characters.
+ // Too bad we don't have strncpy(), strncmp()
+ if (strlen(i_comp) > (COMP_NAME_SIZE -1))
+ {
+ memcpy(l_comp, i_comp, COMP_NAME_SIZE - 1);
+ }
+ else
+ {
+ strcpy(l_comp, i_comp);
+ }
+
+ // CRITICAL REGION START
+ mutex_lock(&iv_trac_mutex);
+
+ // Search through the descriptor array for the first unallocated buffer.
+ // The last buffer is the reserved default buffer for any component
+ // which didn't get its own buffer.
+ for (i = 0; i < (TRAC_MAX_NUM_BUFFERS - 1); i++)
+ {
+ if(!strcmp(l_comp, g_desc_array[i].comp))
+ {
+ //printk("Trace::initBuffer - buffer already allocated %d\n", i);
+
+ // Buffer is already allocated. Return the buffer.
+ *o_td = g_desc_array[i].td_entry;
+
+ break;
+ }
+ else if (strlen(g_desc_array[i].comp) == 0)
+ {
+ //printk("Trace::initBuffer - found unallocated buffer %d\n", i);
+
+ // Found the first unallocated buffer; use this one.
+
+ // Set the component name for the buffer
+ strcpy(g_desc_array[i].comp, l_comp);
+
+ // Allocate memory if needed
+ if (NULL == g_desc_array[i].td_entry)
+ {
+ //printk("Trace::initBuffer - allocate memory\n");
+
+ // Allocate memory for two buffers.
+ // Once malloc() works, we can allocate memory for one
+ // one buffer at a time.
+ l_td = static_cast<char *>(PageManager::allocatePage());
+
+ g_desc_array[i].td_entry =
+ reinterpret_cast<trace_desc_t *>(l_td);
+
+ g_desc_array[i+1].td_entry =
+ reinterpret_cast<trace_desc_t *>(
+ l_td + TRAC_DEFAULT_BUFFER_SIZE);
+ }
+
+ // Initialize the buffer header
+ initValuesBuffer(g_desc_array[i].td_entry,
+ g_desc_array[i].comp);
+
+ // Return the newly allocated buffer
+ *o_td = g_desc_array[i].td_entry;
+
+ break;
+ }
+ }
+
+ if ((TRAC_MAX_NUM_BUFFERS - 1) == i)
+ {
+ //printk("Trace::initBuffer - allocate default buffer %d\n", i);
+
+ // We're out of buffers to allocate.
+ // Use the default buffer reserved for everyone else.
+ // Initialize only once
+ if (strlen(g_desc_array[i].comp) == 0)
+ {
+ // Set the component name for the buffer
+ strcpy(g_desc_array[i].comp, TRAC_DEFAULT_BUFFER_NAME);
+
+ // Allocate memory if needed
+ // Memory should have already been reserved if
+ // TRAC_MAX_NUM_BUFFERS is an even # and we're using
+ // PageManager::allocatePage(). Add check just in
+ // case TRAC_MAC_NUM_BUFFERS is set to an odd number.
+ if (NULL == g_desc_array[i].td_entry)
+ {
+ //printk("Trace::initBuffer - allocate memory\n");
+
+ // Allocate memory for buffer
+ l_td = static_cast<char *>(PageManager::allocatePage());
+
+ // Throw away the last 2KB for now to keep code simple
+ // until we decide to add support for variable-sized
+ // buffers. Also, once we change to use malloc(),
+ // we won't have this problem.
+ g_desc_array[i].td_entry =
+ reinterpret_cast<trace_desc_t *>(l_td);
+ }
+
+ // Initialize the buffer header
+ initValuesBuffer(g_desc_array[i].td_entry,
+ g_desc_array[i].comp);
+ }
+
+ // Return the default buffer
+ *o_td = g_desc_array[i].td_entry;
+ }
+
+ mutex_unlock(&iv_trac_mutex);
+ // CRITICAL REGION END
+
}
return;
@@ -166,7 +292,7 @@ void Trace::trace_adal_write_all(trace_desc_t *io_td,
// need to add that on to total size
l_entry_size += sizeof(uint32_t);
- // Now add on size for acutal number of arguments we're tracing
+ // Now add on size for actual number of arguments we're tracing
l_entry_size += (num_args * sizeof(uint64_t));
// Word align the entry
@@ -407,36 +533,57 @@ void Trace::convertTime(trace_entry_stamp_t *o_entry)
}
/******************************************************************************/
-// getTd - TODO
+// getTd
/******************************************************************************/
trace_desc_t * Trace::getTd(const char *i_comp)
{
/*------------------------------------------------------------------------*/
/* Local Variables */
/*------------------------------------------------------------------------*/
- //uint32_t l_num_des = 0;
- //uint32_t i=0;
- //trace_desc_t * l_td = NULL;
+ uint32_t i=0;
+ trace_desc_t * l_td = NULL;
+ char l_comp[COMP_NAME_SIZE] = {'\0'};
/*------------------------------------------------------------------------*/
/* Code */
/*------------------------------------------------------------------------*/
-#if 0
- l_num_des = sizeof(g_des_array) / sizeof(trace_descriptor_array_t);
-
- for(i=0;i<l_num_des;i++)
+ if (strlen(i_comp) != 0)
{
- if(memcmp(i_comp,(g_des_array[i].entry)->comp,(size_t)COMP_NAME_SIZE) == 0)
+ // Limit component name to 15 characters.
+ if (strlen(i_comp) > (COMP_NAME_SIZE -1))
{
- // Found the component
- l_td = g_des_array[i].entry;
- break;
+ memcpy(l_comp, i_comp, COMP_NAME_SIZE - 1);
+ }
+ else
+ {
+ strcpy(l_comp, i_comp);
+ }
+
+ // Search all allocated component buffers
+ for(i=0;
+ (i < (TRAC_MAX_NUM_BUFFERS - 1)) &&
+ (strlen(g_desc_array[i].comp) != 0);
+ i++)
+ {
+ if(!strcmp(l_comp, g_desc_array[i].comp))
+ {
+ // Found the component buffer
+ l_td = g_desc_array[i].td_entry;
+ break;
+ }
+ }
+
+ if (((TRAC_MAX_NUM_BUFFERS - 1) == i) &&
+ (strlen(g_desc_array[i].comp) != 0))
+
+ {
+ // Must be the default buffer
+ l_td = g_desc_array[i].td_entry;
}
}
-#endif
- // Only one trace buffer currently
- return(g_trac_global);
+
+ return(l_td);
}
/******************************************************************************/
OpenPOWER on IntegriCloud