diff options
-rwxr-xr-x | src/build/trace/traceHB.py | 258 | ||||
-rw-r--r-- | src/usr/example/example.C | 2 | ||||
-rw-r--r-- | src/usr/trace/test/tracetest.H | 47 | ||||
-rw-r--r-- | src/usr/trace/trace.C | 201 |
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); } /******************************************************************************/ |