diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/build/trace/tracehash_hb.pl | 10 | ||||
-rw-r--r-- | src/include/usr/trace/interface.H | 144 | ||||
-rw-r--r-- | src/include/usr/trace/trace.H | 299 | ||||
l--------- | src/include/usr/tracinterface.H | 1 | ||||
-rw-r--r-- | src/makefile | 2 | ||||
-rw-r--r-- | src/usr/example/example.C | 29 | ||||
-rw-r--r-- | src/usr/example/test/exampletest.H | 23 | ||||
-rw-r--r-- | src/usr/trace/makefile | 2 | ||||
-rw-r--r-- | src/usr/trace/test/makefile | 6 | ||||
-rw-r--r-- | src/usr/trace/test/tracetest.H | 129 | ||||
-rw-r--r-- | src/usr/trace/trace.C | 276 | ||||
-rw-r--r-- | src/usr/trace/trace.H | 132 |
12 files changed, 631 insertions, 422 deletions
diff --git a/src/build/trace/tracehash_hb.pl b/src/build/trace/tracehash_hb.pl index 7b5548463..a3c35f08a 100755 --- a/src/build/trace/tracehash_hb.pl +++ b/src/build/trace/tracehash_hb.pl @@ -627,10 +627,12 @@ sub assimilate_file($) { chop $line; # remove EOL # 64 bit support - $line =~ s/\%d/\%lld/; - $line =~ s/\%u/\%llu/; - $line =~ s/\%x/\%llx/; - $line =~ s/\%X/\%llX/; + $line =~ s/\%d/\%lld/g; + $line =~ s/\%u/\%llu/g; + $line =~ s/\%x/\%llx/g; + $line =~ s/\%X/\%llX/g; + $line =~ s/\%p/0x\%llX/g; # Replace pointer format with hex value + $line =~ s/\%c/0x\%02llX/g; # Replace character format with 1 byte hex display #print "line: $line\n"; if($version eq "1") diff --git a/src/include/usr/trace/interface.H b/src/include/usr/trace/interface.H index 6d62efca0..0f340b6cc 100644 --- a/src/include/usr/trace/interface.H +++ b/src/include/usr/trace/interface.H @@ -33,23 +33,21 @@ // Includes /******************************************************************************/ #include <stdint.h> +#include "trace.H" // Internal function and struct definitions /******************************************************************************/ // Globals/Constants /******************************************************************************/ #define ENTER_MRK ">>" #define EXIT_MRK "<<" -#define ERR_MRK "E>" +#define ERR_MRK "E>" #define INFO_MRK "I>" -#define ARG_MRK "A>" +#define ARG_MRK "A>" -#define TRAC_COMP_SIZE 16 // Max component name size -#define TRAC_MAX_ARGS 9 // Max number of arguments in trace +const uint32_t TRACE_DEBUG = 1; //Indicates trace is debug +const uint32_t TRACE_FIELD = 0; //Indicates trace is field -#define TRACE_DEBUG 1 //Indicates trace is debug -#define TRACE_FIELD 0 //Indicates trace is field - // check compatibility of header file/macros and preprocessor tracepp // if tracepp was used #define TRAC_MACROVER 1 @@ -101,7 +99,7 @@ /* a macro w/o the param number suffix. number is calculated from printf string */ #define TRACDCOMP(des,printf_string,args...) \ - TRACE::trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_DEBUG, ##args) + TRACE::theTrace::instance().trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_DEBUG, ##args) /** * @fn void TRACDBIN(des,descString,address,length) @@ -119,7 +117,7 @@ */ #define TRACDBIN(des,printf_string,address,len) \ - TRACE::trace_adal_write_bin(des,__ALL_HASH(printf_string,0), \ + TRACE::theTrace::instance().trace_adal_write_bin(des,__ALL_HASH(printf_string,0), \ __LINE__, \ address, \ len, \ @@ -143,7 +141,7 @@ /* a macro w/o the param number suffix. number is calculated from printf string */ #define TRACFCOMP(des,printf_string,args...) \ - TRACE::trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_FIELD, ##args) + TRACE::theTrace::instance().trace_adal_write_all((des),__ALL_HASH(printf_string,-1),__LINE__,TRACE_FIELD, ##args) /** @@ -161,7 +159,7 @@ * @return void */ #define TRACFBIN(des,printf_string,address,len) \ - TRACE::trace_adal_write_bin(des,__ALL_HASH(printf_string,0), \ + TRACE::theTrace::instance().trace_adal_write_bin(des,__ALL_HASH(printf_string,0), \ __LINE__, \ address, \ len, \ @@ -184,7 +182,7 @@ * @return void */ #define TRAC_INIT_BUFFER(des,comp_name, bufferSize) \ - TRACE::trace_adal_init_buffer((des), (comp_name), (bufferSize)) + TRACE::theTrace::instance().initBuffer((des), (comp_name), (bufferSize)) /******************************************************************************* TRAC_INIT: Class for creating trace descriptor object. @@ -202,127 +200,8 @@ #define TRAC_INIT_LINE(des, name, sz, ln) TRAC_INIT_UNIQ(des, name, sz, ln) #define TRAC_INIT(des, name, sz) TRAC_INIT_LINE(des, name, sz, __LINE__) - -/******************************************************************************/ -// Internals - Not to be called or used directly by host boot code -/******************************************************************************/ - - -typedef uint32_t trace_hash_val; // Hash values are 32 bytes - -/* - * @brief Structure is put at beginning of all trace buffers - */ -typedef struct trace_buf_head { - unsigned char ver; /*!< version of this struct (1) */ - unsigned char hdr_len; /*!< size of this struct in bytes */ - unsigned char time_flg; /*!< meaning of timestamp entry field */ - unsigned char endian_flg; /*!< flag for big ('B') or little ('L') endian*/ - char comp[TRAC_COMP_SIZE]; /*!< the buffer name as specified in init call*/ - uint32_t size; /*!< size of buffer, including this struct */ - uint32_t times_wrap; /*!< how often the buffer wrapped */ - uint32_t next_free; /*!< offset of the byte behind the latest entry*/ - uint32_t te_count; /*!< Updated each time a trace is done */ - uint32_t extracted; /*!< Not currently used */ -}trace_buf_head_t; - -/*! - * @brief Timestamp and thread id for each trace entry. - */ -typedef struct trace_entry_stamp { - //uint32_t tbh; /*!< timestamp upper part */ - //uint32_t tbl; /*!< timestamp lower part */ - uint32_t tb[2]; - //uint64_t tb; - uint32_t tid; /*!< process/thread id */ -}trace_entry_stamp_t; - -/* - * @brief Structure is used by adal app. layer to fill in trace info. - */ -typedef struct trace_entry_head { - uint16_t length; /*!< size of trace entry */ - uint16_t tag; /*!< type of entry: xTRACE xDUMP, (un)packed */ - uint32_t hash; /*!< a value for the (format) string */ - uint32_t line; /*!< source file line number of trace call */ -}trace_entry_head_t; - -/* - * @brief Parameter traces can be all contained in one write. - */ -typedef struct trace_entire_entry { - trace_entry_stamp_t stamp; - trace_entry_head_t head; - uint64_t args[TRAC_MAX_ARGS + 1]; -} trace_entire_entry_t; - - -/* - * @brief Binary first writes header and time stamp. - */ -typedef struct trace_bin_entry { - trace_entry_stamp_t stamp; - trace_entry_head_t head; -} trace_bin_entry_t; - -/** - * @brief New version name of this typedef - */ -typedef trace_buf_head_t trace_desc_t; - namespace TRACE { - -/** - * @brief Initialize a trace buffer - * - * @param o_td[out] Trace descriptor to initialize - * @param i_comp[in] Component name for trace buffer - * @param i_size[in] Size to allocate for trace buffer - * - * @return void - */ -void trace_adal_init_buffer(trace_desc_t **o_td, - const char* i_comp, - const size_t i_size ); - -/** - * @brief Write component trace out to input buffer - * - * @param io_td[inout] Trace descriptor of buffer to write to. - * @param i_hash[in] Descriptive string hash value - * @param i_fmt [in] Formatting string - * @param i_line[in] Line number trace was done at - * @param i_type[in] Type of trace (TRACE_DEBUG, TRACE_FIELD) - * - * @return void - */ -void trace_adal_write_all(trace_desc_t *io_td, - const trace_hash_val i_hash, - const char * i_fmt, - const uint32_t i_line, - const int32_t i_type, ...); - -/** - * @brief Write binary data out to trace buffer - * - * @param io_td[inout] Trace descriptor of buffer to write to. - * @param i_hash[in] Descriptive string hash value - * @param i_line[in] Line number trace was done at - * @param i_ptr[in] Pointer to binary data - * @param i_size[in] Size of binary data - * @param i_type[in] Type of trace (TRACE_DEBUG, TRACE_FIELD) - * - * @return void - */ -void trace_adal_write_bin(trace_desc_t * io_td, - const trace_hash_val i_hash, - const uint32_t i_line, - const void *i_ptr, - const uint32_t i_size, - const int32_t type); - - /******************************************************************************/ // Allow users to init trace buffer outside of a function /******************************************************************************/ @@ -345,6 +224,7 @@ class TracInit }; -}; // Namespace +} + #endif //! -- !defined __TRACE_INTERFACE_H diff --git a/src/include/usr/trace/trace.H b/src/include/usr/trace/trace.H new file mode 100644 index 000000000..e6566c820 --- /dev/null +++ b/src/include/usr/trace/trace.H @@ -0,0 +1,299 @@ +/** + * @file trace.H + * + * Internal trace definitions and functions. External users should + * not directly include or use this file. trace/interface.H is the external + * file. +*/ + +#ifndef __TRACE_TRACE_H +#define __TRACE_TRACE_H + +/******************************************************************************/ +// Includes +/******************************************************************************/ +#include <stdint.h> +#include <trace/interface.H> +#include <util/singleton.H> +#include <sys/mutex.h> + +/******************************************************************************/ +// Globals/Constants +/******************************************************************************/ + +const uint32_t TRACE_BUF_VERSION = 0x01; // Trace buffer version +const uint32_t TRACE_FIELDTRACE = 0x4654; // Field Trace - "FT" +const uint32_t TRACE_FIELDBIN = 0x4644; // Binary Field Trace - "FD" + +const uint32_t TRACE_DEBUG_ON = 1; //Set to this when debug trace on +const uint32_t TRACE_DEBUG_OFF = 0; //Set to this when debug trace off + +const uint32_t TRAC_COMP_SIZE = 16; // Max component name size +const uint32_t TRAC_MAX_ARGS = 9; // Max number of arguments in trace + +/******************************************************************************/ +// Typedef/Enumerations +/******************************************************************************/ + +typedef uint32_t trace_hash_val; // Hash values are 32 bytes + +/* + * @brief Structure is put at beginning of all trace buffers + */ +typedef struct trace_buf_head { + unsigned char ver; /*!< version of this struct (1) */ + unsigned char hdr_len; /*!< size of this struct in bytes */ + unsigned char time_flg; /*!< meaning of timestamp entry field */ + unsigned char endian_flg; /*!< flag for big ('B') or little ('L') endian*/ + char comp[TRAC_COMP_SIZE]; /*!< the buffer name as specified in init call*/ + uint32_t size; /*!< size of buffer, including this struct */ + uint32_t times_wrap; /*!< how often the buffer wrapped */ + uint32_t next_free; /*!< offset of the byte behind the latest entry*/ + uint32_t te_count; /*!< Updated each time a trace is done */ + uint32_t extracted; /*!< Not currently used */ +}trace_buf_head_t; + +/*! + * @brief Timestamp and thread id for each trace entry. + */ +typedef struct trace_entry_stamp { + uint32_t tbh; /*!< timestamp upper part */ + uint32_t tbl; /*!< timestamp lower part */ + uint32_t tid; /*!< process/thread id */ +}trace_entry_stamp_t; + +/* + * @brief Structure is used by adal app. layer to fill in trace info. + */ +typedef struct trace_entry_head { + uint16_t length; /*!< size of trace entry */ + uint16_t tag; /*!< type of entry: xTRACE xDUMP, (un)packed */ + uint32_t hash; /*!< a value for the (format) string */ + uint32_t line; /*!< source file line number of trace call */ +}trace_entry_head_t; + +/* + * @brief Parameter traces can be all contained in one write. + */ +typedef struct trace_entire_entry { + trace_entry_stamp_t stamp; + trace_entry_head_t head; + uint64_t args[TRAC_MAX_ARGS + 1]; /*!< Add 1 for the required buffer size */ +} trace_entire_entry_t; + + +/* + * @brief Binary first writes header and time stamp. + */ +typedef struct trace_bin_entry { + trace_entry_stamp_t stamp; + trace_entry_head_t head; +} trace_bin_entry_t; + +/** + * @brief New version name of this typedef + */ +typedef trace_buf_head_t trace_desc_t; + + +/******************************************************************************/ +// Trace Class +/******************************************************************************/ +namespace TRACE +{ + +// Singleton definition +class Trace; +typedef Singleton<Trace> theTrace; + +/** + * @brief Trace Singleton Class + * + * This class managers the internals of the host boot trace implementation. +*/ +class Trace +{ + +public: + + /** + * @brief Initialize a trace buffer + * + * @param o_td[out] Trace descriptor to initialize + * @param i_comp[in] Component name for trace buffer + * @param i_size[in] Size to allocate for trace buffer + * + * @return void + */ + void initBuffer(trace_desc_t **o_td, + const char* i_comp, + const size_t i_size ); + + /** + * @brief Write component trace out to input buffer + * + * Note that to continue to support tracepp, we must keep the + * name of this function as is. + * + * @param io_td[inout] Trace descriptor of buffer to write to. + * @param i_hash[in] Descriptive string hash value + * @param i_fmt [in] Formatting string + * @param i_line[in] Line number trace was done at + * @param i_type[in] Type of trace (TRACE_DEBUG, TRACE_FIELD) + * + * @return void + */ + void trace_adal_write_all(trace_desc_t *io_td, + const trace_hash_val i_hash, + const char * i_fmt, + const uint32_t i_line, + const int32_t i_type, ...); + + /** + * @brief Write binary data out to trace buffer + * + * Note that to continue to support tracepp, we must keep the + * name of this function as is. + * + * @param io_td[inout] Trace descriptor of buffer to write to. + * @param i_hash[in] Descriptive string hash value + * @param i_line[in] Line number trace was done at + * @param i_ptr[in] Pointer to binary data + * @param i_size[in] Size of binary data + * @param i_type[in] Type of trace (TRACE_DEBUG, TRACE_FIELD) + * + * @return void + */ + void trace_adal_write_bin(trace_desc_t * io_td, + const trace_hash_val i_hash, + const uint32_t i_line, + const void *i_ptr, + const uint32_t i_size, + const int32_t type); + +protected: + + /** + * @brief Constructor for the trace object. + */ + Trace(); + + /** + * @brief Destructor for the trace object. + */ + ~Trace(); + +private: + + /** + * @brief Initialize a new trace buffer + * + * Internal function responsible setting up the defaults in a newly created + * trace buffer. + * + * @param[out] o_buf Trace descriptor of component buffer to initialize. + * @param[in] i_comp Component name + * + * @return void + * + */ + void initValuesBuffer(trace_desc_t *o_buf, + const char *i_comp); + + + /** + * @brief Write the trace data into the buffer + * + * Internal function responsible for copying the trace data into the appropriate + * buffer. + * + * @param[inout] io_td Trace descriptor of component buffer to write to. + * @param[in] i_ptr Pointer to data to copy into the trace buffer. + * @param[in] i_size Size of the i_ptr data to copy into the buffer. + * + * @return void + * + */ + void writeData(trace_desc_t * io_td, + const void *i_ptr, + const uint32_t i_size); + + + /** + * @brief Retrieve full trace buffer for component i_comp + * + * This function assumes memory has already been allocated for + * the full trace buffer in o_data. + * + * @param i_td_ptr Trace descriptor of buffer to retrieve. + * @param o_data Pre-allocated pointer to where data will be stored. + * + * TODO - Not Supported Yet + * + * @return Non-zero return code on error + */ + int32_t getBuffer(const trace_desc_t * i_td_ptr, + void *o_data); + + /** + * @brief Retrieve partial trace buffer for component i_comp + * + * This function assumes memory has already been allocated for + * the trace buffer (size io_size). This function will copy + * in up to io_size in bytes to the buffer and set io_size + * to the exact size that is copied in. + * + * TODO - Not Supported Yet + * + * @param i_td_ptr Trace descriptor of buffer to retrieve. + * @param o_data Pre-allocated pointer to where data will be stored. + * @param io_size Size of trace data to retrieve (input) + * Actual size of trace data stored (output) + * + * @return Non-zero return code on error + */ + int32_t getBufferPartial(const trace_desc_t * i_td_ptr, + void *o_data, + uint32_t *io_size); + + /** + * @brief Retrieve trace descriptor for input component name + * + * @param i_comp Component name to retrieve trace descriptor for. + * + * TODO - Not Supported Yet + * + * @return Valid trace descriptor on success, NULL on failure. + */ + trace_desc_t * getTd(const char *i_comp); + + /** + * @brief Reset all trace buffers + * + * TODO - Not Supported Yet + * + * @return Non-zero return code on error + */ + int32_t resetBuf(void); + + /** + * @brief Convert timestamp + * + * @param [out] o_entry Trace entry stamp to fill in the time info for. + * + * @return Void + */ + void convertTime(trace_entry_stamp_t *o_entry); + + // Disabled copy constructor and assignment operator + Trace(const Trace & right); + Trace & operator=(const Trace & right); + + // Global Mutex + mutex_t iv_trac_mutex; + +}; + +} // namespace TRACE + +#endif diff --git a/src/include/usr/tracinterface.H b/src/include/usr/tracinterface.H new file mode 120000 index 000000000..385432847 --- /dev/null +++ b/src/include/usr/tracinterface.H @@ -0,0 +1 @@ +./trace/interface.H
\ No newline at end of file diff --git a/src/makefile b/src/makefile index b2d63da06..233376531 100644 --- a/src/makefile +++ b/src/makefile @@ -18,7 +18,7 @@ RUNTIME_OBJECTS = BASE_MODULES = trace DIRECT_BOOT_MODULES = example RUNTIME_MODULES = -TESTCASE_MODULES = cxxtest testexample +TESTCASE_MODULES = cxxtest testexample testtrace RELOCATABLE_IMAGE_LDFLAGS = -pie --export-dynamic diff --git a/src/usr/example/example.C b/src/usr/example/example.C index 69291325b..803f719b0 100644 --- a/src/usr/example/example.C +++ b/src/usr/example/example.C @@ -1,11 +1,3 @@ -/* - * Change Log ****************************************************************** - * Flag Defect/Feature User Date Description - * ------ -------------- ---------- ----------- ---------------------------- - * $ag000 andrewg 04/01/2011 Updated - * -*/ - #include <kernel/console.H> #include <sys/mutex.h> #include <sys/vfs.h> @@ -22,25 +14,6 @@ void _start(void*) { printk("Executing example module.\n"); - // Component trace tests - //for(uint32_t i=0;i<100;i++) - //{ - uint32_t i=0; - TRACFCOMP(g_trac_test, "Executing example module: %d", task_gettid()); - TRACFCOMP(g_trac_test, "Test 2: %d %u %c", i,i+1,'a'); - TRACFCOMP(g_trac_test, "Test 3: %d %u 0x%X", i+2,i+3, - 0x123456789ABCDEF0); - //} - - // Pointer trace - //TRACFCOMP(g_trac_test, "Pointer Test: %llp",g_trac_test); - - // Binary Trace - TRACFBIN(g_trac_test,"Binary dump of trace descriptor", - g_trac_test,sizeof(trace_desc_t)); - - - task_end(); } @@ -48,7 +21,7 @@ uint64_t example1_function() { uint64_t l_rc = 0; - TRACFCOMP(g_trac_test, "Someone Called example1_function!"); + //TRACFCOMP(g_trac_test, "Someone Called example1_function!"); return l_rc; } diff --git a/src/usr/example/test/exampletest.H b/src/usr/example/test/exampletest.H index c45aaf4f7..ec2e60dba 100644 --- a/src/usr/example/test/exampletest.H +++ b/src/usr/example/test/exampletest.H @@ -1,9 +1,22 @@ +#ifndef __TEST_EXAMPLETEST_H +#define __TEST_EXAMPLETEST_H + +/** + * @file exampletest.H + * + * @brief Example for people to use when writing test cases for their module. +*/ + #include <cxxtest/TestSuite.H> #include <example/example.H> class ExampleTest: public CxxTest::TestSuite { public: + + /** + * @test Test Description + */ void testExample1(void) { uint64_t l_rc = 0; @@ -13,11 +26,19 @@ public: TS_FAIL("Call to example1_function1 failed!"); } } + + /** + * @test Test Description + */ void testExample2(void) { // Call functions and validate results // TS_FAIL("Failed test call to example2 function"); } + + /** + * @test Test Description + */ void testExample3(void) { // Call functions and validate results @@ -36,3 +57,5 @@ public: }; +#endif + diff --git a/src/usr/trace/makefile b/src/usr/trace/makefile index d963a9895..fa4b14324 100644 --- a/src/usr/trace/makefile +++ b/src/usr/trace/makefile @@ -3,4 +3,6 @@ MODULE = trace OBJS = trace.o tracebuffer.o +SUBDIRS = test.d + include ${ROOTPATH}/config.mk diff --git a/src/usr/trace/test/makefile b/src/usr/trace/test/makefile new file mode 100644 index 000000000..ba38d6f66 --- /dev/null +++ b/src/usr/trace/test/makefile @@ -0,0 +1,6 @@ +ROOTPATH = ../../../.. + +MODULE = testtrace +TESTS = *.H + +include ${ROOTPATH}/config.mk diff --git a/src/usr/trace/test/tracetest.H b/src/usr/trace/test/tracetest.H new file mode 100644 index 000000000..0767352c6 --- /dev/null +++ b/src/usr/trace/test/tracetest.H @@ -0,0 +1,129 @@ +#ifndef __TEST_TRACETEST_H +#define __TEST_TRACETEST_H + +/** + * @file tracetest.H + * + * @brief All unit tests for the trace module in host boot. +*/ + +#include <cxxtest/TestSuite.H> +//#include <trace/interface.H> +#include <tracinterface.H> + +class TraceTest : public CxxTest::TestSuite +{ +public: + + /** + * @test Test Component Trace Interfaces + */ + void testTracComp(void) + { + trace_desc_t *g_trac_test = NULL; + TRAC_INIT_BUFFER(&g_trac_test, "EXAMPLE", 4096); + + if(g_trac_test == NULL) + { + TS_FAIL("g_trac_test was returned as NULL!"); + } + else + { + // Component trace tests - There is no easy way to validate these + // are working but we can at least ensure we don't cause host boot + // to crash when running them. + + for(uint32_t i=0;i<100;i++) + { + TRACFCOMP(g_trac_test, "Thread ID: %d", task_gettid()); + TRACFCOMP(g_trac_test, "Validate all number types (c,u,X,d): %c %u 0x%X %d", + 'a',i,i+1,i+2); + + TRACFCOMP(g_trac_test, "Validate pointer type (p): %p", + g_trac_test); + + TRACFCOMP(g_trac_test, "64 Bit Value Test - 0x123456789ABCDEF0: 0x%X", + 0x123456789ABCDEF0); + + // Do a debug trace + TRACDCOMP(g_trac_test,"This is a debug trace"); + + // Need to run a formatting test, but I know it will fail. + } + + // Be sure a NULL trace descriptor does not cause a failure + TRACFCOMP(NULL,"This trace should never show up"); + + } + } + + /** + * @test Test Binary Trace Interface + */ + void testTracBinary(void) + { + trace_desc_t *g_trac_test = NULL; + TRAC_INIT_BUFFER(&g_trac_test, "EXAMPLE", 4096); + + if(g_trac_test == NULL) + { + TS_FAIL("g_trac_test was returned as NULL!"); + } + else + { + // Binary trace tests - There is no easy way to validate these + // are working but we can at least ensure we don't cause host boot + // to crash when running them. + TRACFBIN(g_trac_test,"Binary dump of trace descriptor", + g_trac_test,sizeof(trace_desc_t)); + + TRACDBIN(g_trac_test,"Unaligned Debug binary trace of the trace descriptor", + g_trac_test,9); + + // Be sure a NULL trace descriptor does not cause a failure + TRACFBIN(NULL,"This trace should never show up", + g_trac_test,sizeof(trace_desc_t)); + + // Be sure it handles a size of 0 + TRACFBIN(NULL,"This trace should never show up - 0 size", + g_trac_test,0); + } + } + + /** + * @test Test a mix of traces + */ + void testTracMix(void) + { + trace_desc_t *g_trac_test = NULL; + TRAC_INIT_BUFFER(&g_trac_test, "EXAMPLE", 4096); + + if(g_trac_test == NULL) + { + TS_FAIL("g_trac_test was returned as NULL!"); + } + else + { + uint32_t l_size = 0; + + for(uint32_t i=0;i<100;i++) + { + + TRACFCOMP(g_trac_test, INFO_MRK"Validate all number types (c,u,X,d): %c %u 0x%X %d", + 'a',i,i+1,i+2); + + l_size = i % sizeof(trace_desc_t); + + TRACFBIN(g_trac_test,"Unaligned Binary dump of trace descriptor", + g_trac_test,l_size); + + TRACFCOMP(g_trac_test, "64 Bit Value Test - 0x123456789ABCDEF0: 0x%X", + 0x123456789ABCDEF0); + + } + } + } +}; + +#endif + diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C index 33a3de888..b5105a654 100644 --- a/src/usr/trace/trace.C +++ b/src/usr/trace/trace.C @@ -1,7 +1,9 @@ /* TODO - * - Add support in for debug traces - * - Time support + * - Add support in for debug trace enable/disable * - FORMAT_PRINTF support + * - %s support + * - Multiple buffer support + * - Prolog * * */ @@ -17,8 +19,9 @@ #include <stdlib.h> #include <sys/task.h> #include <sys/mutex.h> +#include <string.h> -#include "trace.H" +#include <trace/trace.H> /******************************************************************************/ // Namespace @@ -30,28 +33,43 @@ namespace TRACE // Globals/Constants /******************************************************************************/ -#define TRAC_TIME_REAL 0 // upper 32 = seconds, lower 32 = microseconds -#define TRAC_TIME_50MHZ 1 -#define TRAC_TIME_200MHZ 2 -#define TRAC_TIME_167MHZ 3 // 166666667Hz -#define COMP_NAME_SIZE 16 +const uint32_t TRAC_TIME_REAL = 0; // upper 32 = seconds, lower 32 = microseconds +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; -// Global value used as a "timer" to provide tracing point32_t of reference -uint32_t g_trac_time_high = 0; -uint32_t g_trac_time_low = 0; +const uint64_t TRAC_DEFAULT_BUFFER_SIZE = 0x1000; -// Global Mutex -mutex_t g_trac_mutex; - -// Global buffer +// Global trace buffer. - Keep global so it can be found in syms file trace_desc_t *g_trac_global = NULL; +/******************************************************************************/ +// Trace::Trace +/******************************************************************************/ +Trace::Trace() +{ + iv_trac_mutex = mutex_create(); + + g_trac_global = static_cast<trace_desc_t *>(malloc(TRAC_DEFAULT_BUFFER_SIZE)); + + initValuesBuffer(g_trac_global, + "GLOBAL"); +} + +/******************************************************************************/ +// Trace::~Trace +/******************************************************************************/ +Trace::~Trace() +{ + +} /******************************************************************************/ // trace_adal_init_buffer /******************************************************************************/ -void trace_adal_init_buffer(trace_desc_t **o_td, const char* i_comp, +void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp, const size_t i_size ) { /*------------------------------------------------------------------------*/ @@ -63,35 +81,18 @@ void trace_adal_init_buffer(trace_desc_t **o_td, const char* i_comp, /*------------------------------------------------------------------------*/ if(*o_td == NULL) { - if(g_trac_global == NULL) - { - // TODO - How do I make this pre-emption/mutli-threading safe? - g_trac_mutex = mutex_create(); - - printk("Global trace buffer is NULL so create and init it!\n"); - - g_trac_global = (trace_desc_t *)(malloc(PAGE_SIZE)); - char l_g_comp[TRAC_COMP_SIZE] = "GLOBAL"; - trace_init_values_buffer(g_trac_global, - l_g_comp); - - } - // Just assign it to the global buffer since we only have // one buffer *o_td = g_trac_global; - printk("Assigned input trace descriptor to global buffer\n"); } - printk("*td = %lu\n",(unsigned long int)*o_td); - return; } /******************************************************************************/ -// trace_init_values_buffer +// initValuesBuffer /******************************************************************************/ -void trace_init_values_buffer(trace_desc_t *o_buf,const char *i_comp) +void Trace::initValuesBuffer(trace_desc_t *o_buf,const char *i_comp) { /*------------------------------------------------------------------------*/ /* Local Variables */ @@ -102,16 +103,16 @@ void trace_init_values_buffer(trace_desc_t *o_buf,const char *i_comp) /*------------------------------------------------------------------------*/ // Initialize it to all 0's - memset(o_buf,0,(size_t)PAGE_SIZE); + memset(o_buf,0,(size_t)TRAC_DEFAULT_BUFFER_SIZE); - (o_buf)->ver = TRACE_BUF_VERSION; - (o_buf)->hdr_len = sizeof(trace_buf_head_t); - (o_buf)->time_flg = TRAC_TIME_167MHZ; - (o_buf)->endian_flg = 'B'; // Big Endian - memcpy((o_buf)->comp,i_comp,(size_t)COMP_NAME_SIZE); - (o_buf)->size = PAGE_SIZE; - (o_buf)->times_wrap = 0; - (o_buf)->next_free = sizeof(trace_buf_head_t); + o_buf->ver = TRACE_BUF_VERSION; + o_buf->hdr_len = sizeof(trace_buf_head_t); + o_buf->time_flg = TRAC_TIME_REAL; + o_buf->endian_flg = 'B'; // Big Endian + strcpy(o_buf->comp,i_comp); + o_buf->size = TRAC_DEFAULT_BUFFER_SIZE; + o_buf->times_wrap = 0; + o_buf->next_free = sizeof(trace_buf_head_t); return; } @@ -119,11 +120,11 @@ void trace_init_values_buffer(trace_desc_t *o_buf,const char *i_comp) /******************************************************************************/ // trace_adal_write_all /******************************************************************************/ -void trace_adal_write_all(trace_desc_t *io_td, - const trace_hash_val i_hash, - const char * i_fmt, - const uint32_t i_line, - const int32_t i_type, ...) +void Trace::trace_adal_write_all(trace_desc_t *io_td, + const trace_hash_val i_hash, + const char * i_fmt, + const uint32_t i_line, + const int32_t i_type, ...) { /*------------------------------------------------------------------------*/ /* Local Variables */ @@ -146,11 +147,7 @@ void trace_adal_write_all(trace_desc_t *io_td, _fmt++; } - if(num_args > TRAC_MAX_ARGS) - { - printk ("Too many arguments: %u",num_args); - } - else if(io_td != NULL) + if((num_args <= TRAC_MAX_ARGS) && (io_td != NULL)) { // Calculate total space needed @@ -169,7 +166,7 @@ void trace_adal_write_all(trace_desc_t *io_td, l_entry_size = (l_entry_size + 3) & ~3; // Fill in the entry structure - l_entry.stamp.tid = (uint32_t)task_gettid(); // What is response to this in AME code? + l_entry.stamp.tid = static_cast<uint32_t>(task_gettid()); // Length is equal to size of data l_entry.head.length = (num_args * sizeof(uint64_t)); @@ -178,7 +175,7 @@ void trace_adal_write_all(trace_desc_t *io_td, l_entry.head.line = i_line; // Time stamp - *(l_entry.stamp.tb) = getTB(); + convertTime(&l_entry.stamp); uint64_t* data = &l_entry.args[0]; @@ -193,42 +190,37 @@ void trace_adal_write_all(trace_desc_t *io_td, // Now put total size at end of buffer // Note that fsp-trace assumes this to be a 32 bit long word - uint32_t *l_size = (uint32_t *)&(l_entry.args[num_args]); + uint32_t *l_size = reinterpret_cast<uint32_t *> + (&(l_entry.args[num_args])); *l_size = l_entry_size; - printk("l_entry_size = %u ttid = %u\n",l_entry_size,l_entry.stamp.tid); - // We now have total size and need to reserve a part of the trace // buffer for this // CRITICAL REGION START - l_rc = mutex_lock(g_trac_mutex); + l_rc = mutex_lock(iv_trac_mutex); if(l_rc != 0) { - printk("trace_adal_write_all: Failed to get mutex"); + // This will assert so we'll never hit this code. } else { // Update the entry count io_td->te_count++; - trace_write_data(io_td, - (void *)&l_entry, - l_entry_size); + writeData(io_td, + static_cast<void *>(&l_entry), + l_entry_size); - l_rc = mutex_unlock(g_trac_mutex); + l_rc = mutex_unlock(iv_trac_mutex); if(l_rc != 0) { // Badness - printk("trace_adal_write_all: Failed to release mutex"); + // This will assert so we'll never hit this code. } } // CRITICAL REGION END } - else - { - printk("trace_adal_write_all: User passed invalid parameter"); - } return; } @@ -236,11 +228,11 @@ void trace_adal_write_all(trace_desc_t *io_td, /******************************************************************************/ // trace_adal_write_bin /******************************************************************************/ -void trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_hash, - const uint32_t i_line, - const void *i_ptr, - const uint32_t i_size, - const int32_t type) +void Trace::trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_hash, + const uint32_t i_line, + const void *i_ptr, + const uint32_t i_size, + const int32_t type) { /*------------------------------------------------------------------------*/ /* Local Variables */ @@ -276,7 +268,7 @@ void trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_hash, l_entry_size = (l_entry_size + 3) & ~3; // Fill in the entry structure - l_entry.stamp.tid = (uint32_t)task_gettid(); // What is response to this in AME code? + l_entry.stamp.tid = static_cast<uint32_t>(task_gettid()); // Length is equal to size of data l_entry.head.length = i_size; @@ -288,41 +280,41 @@ void trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_hash, // buffer for this // Time stamp - *(l_entry.stamp.tb) = getTB(); + convertTime(&l_entry.stamp); // CRITICAL REGION START - l_rc = mutex_lock(g_trac_mutex); + l_rc = mutex_lock(iv_trac_mutex); if(l_rc != 0) { - printk("trace_adal_write_bin: Failed to get mutex"); + // This will assert so we'll never hit this code. } else { // Increment trace counter - io_td->te_count++;; + io_td->te_count++; // First write the header - trace_write_data(io_td, - (void *)&l_entry, - sizeof(l_entry)); + writeData(io_td, + static_cast<void *>(&l_entry), + sizeof(l_entry)); // Now write the actual binary data - trace_write_data(io_td, - i_ptr, - i_size); + writeData(io_td, + i_ptr, + i_size); // Now write the size at the end - trace_write_data(io_td, - (void *)&l_entry_size, - sizeof(l_entry_size)); + writeData(io_td, + static_cast<void *>(&l_entry_size), + sizeof(l_entry_size)); // CRITICAL REGION END - l_rc = mutex_unlock(g_trac_mutex); + l_rc = mutex_unlock(iv_trac_mutex); if(l_rc != 0) { // Badness - printk("trace_adal_write_bin: Failed to release mutex"); + // This will assert so we'll never hit this code. } } @@ -332,9 +324,9 @@ void trace_adal_write_bin(trace_desc_t *io_td,const trace_hash_val i_hash, } /******************************************************************************/ -// trace_write_data +// writeData /******************************************************************************/ -void trace_write_data(trace_desc_t *io_td, +void Trace::writeData(trace_desc_t *io_td, const void *i_ptr, const uint32_t i_size) { @@ -344,6 +336,7 @@ void trace_write_data(trace_desc_t *io_td, uint32_t l_total_size = i_size; void *l_buf_ptr = NULL; uint32_t l_offset = 0; + uint64_t l_align = 0; /*------------------------------------------------------------------------*/ /* Code */ @@ -352,19 +345,26 @@ void trace_write_data(trace_desc_t *io_td, do { - if(i_size > PAGE_SIZE) + if(i_size > (io_td->size-sizeof(trace_buf_head_t))) { - printk("trace_write_data: Input size to large!"); break; } - if((io_td->next_free + l_total_size) > PAGE_SIZE) + + if((io_td->next_free + l_total_size) > io_td->size) { - // copy what we can to end - l_buf_ptr = (char *)io_td + io_td->next_free; - l_buf_ptr = (void *) ( ((uint64_t) l_buf_ptr + 3) & ~3); - l_offset = PAGE_SIZE-io_td->next_free; - memcpy(l_buf_ptr,i_ptr,(size_t)l_offset); + // Get the pointer to current location in buffer + l_buf_ptr = reinterpret_cast<char *>(io_td) + io_td->next_free; + // Figure out the alignment + l_align = ( (reinterpret_cast<uint64_t>(l_buf_ptr) + 3) & ~3) - + reinterpret_cast<uint64_t>(l_buf_ptr); + // Add on the alignment + l_buf_ptr = reinterpret_cast<void *>(reinterpret_cast<uint64_t> + (l_buf_ptr) + l_align); + // Ensure offset accounts for the alignment + l_offset = io_td->size-io_td->next_free - l_align; + // Copy in what fits + memcpy(l_buf_ptr,i_ptr,static_cast<size_t>(l_offset)); l_total_size -= l_offset; @@ -373,17 +373,23 @@ void trace_write_data(trace_desc_t *io_td, io_td->next_free = io_td->hdr_len; } - l_buf_ptr = (char *)io_td + io_td->next_free; - - // Word align the write - total size includes this allignment - l_buf_ptr = (void *) ( ((uint64_t) l_buf_ptr + 3) & ~3); + // Get the pointer to current location in buffer + l_buf_ptr = reinterpret_cast<char *>(io_td) + io_td->next_free; + // Figure out the alignment + l_align = ( (reinterpret_cast<uint64_t>(l_buf_ptr) + 3) & ~3) - + reinterpret_cast<uint64_t>(l_buf_ptr); + // Add on the alignment + l_buf_ptr = reinterpret_cast<void *>(reinterpret_cast<uint64_t> + (l_buf_ptr) + l_align); - memcpy(l_buf_ptr,(char *)i_ptr + l_offset,l_total_size); + memcpy(l_buf_ptr,reinterpret_cast<const char *>(i_ptr) + l_offset, + l_total_size); - // Make sure size is correct for word allignment + // Make sure size is correct for word alignment // Note that this works with binary trace because only the binary data // has the potential to be un-word aligned. If two parts of the binary // trace had this problem then this code would not work. + // Note that fsp-trace will ignore garbage data in the unaligned areas. l_total_size = (l_total_size + 3) & ~3; io_td->next_free += l_total_size; @@ -394,9 +400,34 @@ void trace_write_data(trace_desc_t *io_td, } /******************************************************************************/ -// TRAC_get_td - TODO +// convertTime +/******************************************************************************/ +void Trace::convertTime(trace_entry_stamp_t *o_entry) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + // TODO - Future Sprint will collect proc frequency and correctly + // calculate this. + uint64_t l_time = getTB(); + //o_entry->tbh = l_time && 0xFFFFFFFF00000000; + //o_entry->tbl = l_time && 0x00000000FFFFFFFF; + + // This basically supports SIMICS, but will look weird on real hw + o_entry->tbh = (l_time / 512000000); + o_entry->tbl = ((l_time - (o_entry->tbh * 512000000)) / 512); + +} + +/******************************************************************************/ +// getTd - TODO /******************************************************************************/ -trace_desc_t * trace_get_td(const char *i_comp) +trace_desc_t * Trace::getTd(const char *i_comp) { /*------------------------------------------------------------------------*/ /* Local Variables */ @@ -427,9 +458,9 @@ trace_desc_t * trace_get_td(const char *i_comp) } /******************************************************************************/ -// trace_get_buffer - TODO +// getBuffer - TODO /******************************************************************************/ -int32_t trace_get_buffer(const trace_desc_t *i_td_ptr, +int32_t Trace::getBuffer(const trace_desc_t *i_td_ptr, void *o_data) { /*------------------------------------------------------------------------*/ @@ -446,11 +477,10 @@ int32_t trace_get_buffer(const trace_desc_t *i_td_ptr, // Get the lock // TODO Mutex #if 0 - l_rc = UTIL_MUTEX_GET(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT); + l_rc = UTIL_MUTEX_GET(&iv_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT); if(l_rc != 0) { // Badness - printk("TRAC_get_buffer: Failed to get mutex"); } else { @@ -458,15 +488,11 @@ int32_t trace_get_buffer(const trace_desc_t *i_td_ptr, } #endif // Copy it's buffer into temp one - memcpy(o_data,i_td_ptr,(size_t)PAGE_SIZE); + memcpy(o_data,i_td_ptr,(size_t)TRAC_DEFAULT_BUFFER_SIZE); // Always try to release even if error above // TODO - mutex - //UTIL_MUTEX_PUT(&g_trac_mutex); - } - else - { - printk("TRAC_get_buffer: Invalid parameter passed by caller"); + //UTIL_MUTEX_PUT(&iv_trac_mutex); } return(l_rc); @@ -474,10 +500,10 @@ int32_t trace_get_buffer(const trace_desc_t *i_td_ptr, #if 0 /******************************************************************************/ -// trace_get_buffer_partial - TODO +// getBufferPartial - TODO /******************************************************************************/ // TODO -int32_t trace_get_buffer_partial(const trace_desc_t *i_td_ptr, +int32_t Trace::getBufferPartial(const trace_desc_t *i_td_ptr, void *o_data, uint32_t *io_size) { @@ -633,9 +659,9 @@ int32_t trace_get_buffer_partial(const trace_desc_t *i_td_ptr, #endif /******************************************************************************/ -// trace_reset_buf - TODO +// resetBuf - TODO /******************************************************************************/ -int32_t trace_reset_buf() +int32_t Trace::resetBuf() { /*------------------------------------------------------------------------*/ /* Local Variables */ @@ -651,7 +677,7 @@ int32_t trace_reset_buf() // Get mutex so no one traces #if 0 // TODO - l_rc = UTIL_MUTEX_GET(&g_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT); + l_rc = UTIL_MUTEX_GET(&iv_trac_mutex,TRAC_INTF_MUTEX_TIMEOUT); if(l_rc != TX_SUCCESS) { printk("trace_reset_buf: Failure trying to get mutex"); @@ -677,7 +703,7 @@ int32_t trace_reset_buf() #endif // Always try to release even if fail above // TODO - mutex - //UTIL_MUTEX_PUT(&g_trac_mutex); + //UTIL_MUTEX_PUT(&iv_trac_mutex); return(l_rc); } diff --git a/src/usr/trace/trace.H b/src/usr/trace/trace.H deleted file mode 100644 index 8087e6c32..000000000 --- a/src/usr/trace/trace.H +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file trace.H - * - * @brief Internal trace definitions and functions -*/ - -#ifndef __TRACE_TRACE_H -#define __TRACE_TRACE_H - -/******************************************************************************/ -// Includes -/******************************************************************************/ -#include <stdint.h> -#include <trace/interface.H> - -namespace TRACE -{ - -/******************************************************************************/ -// Globals/Constants -/******************************************************************************/ - -#define TRACE_BUF_VERSION 0x01; // Trace buffer version -#define TRACE_FIELDTRACE 0x4654 // Field Trace - "FT" -#define TRACE_FIELDBIN 0x4644 // Binary Field Trace - "FD" - -#define TRACE_DEBUG_ON 1 //Set to this when debug trace on -#define TRACE_DEBUG_OFF 0 //Set to this when debug trace off - - -/******************************************************************************/ -// Typedef/Enumerations -/******************************************************************************/ - -/******************************************************************************/ -// Function Prototypes -/******************************************************************************/ - -/** - * @brief Initialize a new trace buffer - * - * Internal function responsible setting up the defaults in a newly created - * trace buffer. - * - * @param[out] o_buf Trace descriptor of component buffer to initialize. - * @param[in] i_comp Component name - * - * @return void - * - */ -void trace_init_values_buffer(trace_desc_t *o_buf, - const char *i_comp); - - -/** - * @brief Write the trace data into the buffer - * - * Internal function responsible for copying the trace data into the appropriate - * buffer. - * - * @param[inout] io_td Trace descriptor of component buffer to write to. - * @param[in] i_ptr Pointer to data to copy into the trace buffer. - * @param[in] i_size Size of the i_ptr data to copy into the buffer. - * - * @return void - * - */ -void trace_write_data(trace_desc_t * io_td, - const void *i_ptr, - const uint32_t i_size); - - -/** - * @brief Retrieve full trace buffer for component i_comp - * - * This function assumes memory has already been allocated for - * the full trace buffer in o_data. - * - * @param i_td_ptr Trace descriptor of buffer to retrieve. - * @param o_data Pre-allocated pointer to where data will be stored. - * - * TODO - Not Supported Yet - * - * @return Non-zero return code on error - */ -int32_t trace_get_buffer(const trace_desc_t * i_td_ptr, - void *o_data); - -/** - * @brief Retrieve partial trace buffer for component i_comp - * - * This function assumes memory has already been allocated for - * the trace buffer (size io_size). This function will copy - * in up to io_size in bytes to the buffer and set io_size - * to the exact size that is copied in. - * - * TODO - Not Supported Yet - * - * @param i_td_ptr Trace descriptor of buffer to retrieve. - * @param o_data Pre-allocated pointer to where data will be stored. - * @param io_size Size of trace data to retrieve (input) - * Actual size of trace data stored (output) - * - * @return Non-zero return code on error - */ -int32_t trace_get_buffer_partial(const trace_desc_t * i_td_ptr, - void *o_data, - uint32_t *io_size); - -/** - * @brief Retrieve trace descriptor for input component name - * - * @param i_comp Component name to retrieve trace descriptor for. - * - * TODO - Not Supported Yet - * - * @return Valid trace descriptor on success, NULL on failure. - */ -trace_desc_t * trace_get_td(const char *i_comp); - -/** - * @brief Reset all trace buffers - * - * TODO - Not Supported Yet - * - * @return Non-zero return code on error - */ -int32_t trace_reset_buf(void); - -} // namespace TRACE - -#endif |