diff options
Diffstat (limited to 'src/lib/pore_hooks.h')
-rwxr-xr-x | src/lib/pore_hooks.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/lib/pore_hooks.h b/src/lib/pore_hooks.h new file mode 100755 index 0000000..f278acb --- /dev/null +++ b/src/lib/pore_hooks.h @@ -0,0 +1,171 @@ +#ifndef __PORE_HOOKS_H__ +#define __PORE_HOOKS_H__ + +// $Id: pore_hooks.h,v 1.1.1.1 2013/12/11 20:49:20 bcbrock Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/p8/working/procedures/lib/pore_hooks.h,v $ +//----------------------------------------------------------------------------- +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//----------------------------------------------------------------------------- + +/// \file pore_hooks.h +/// \brief Support for PORE hooks in Simics +/// +/// Our Simics model of the PORE supports "hooks", that is, special forms of +/// comments that include C++ code that is extracted and made available at +/// simulation time in the Simics environment. +/// +/// Besides hooks that do simple printf() type tracing, logging and tracing +/// hooks are also provided that make use of the Simics log-level facility. +/// This allows precise control over which PORE objects are logged/traced, and +/// at which level. +/// +/// In the Simics environment, hook routines have the following prototype: +/// +/// void f(const PoreAddress& i_address, +/// const HookType i_type, +/// PoreSimics& io_pore); + +// Define the "1-liner" syntax + +#define HOOK_MARKER HOOK_INSERT_MARKER(#,#) +#define HOOK_INSERT_MARKER(x,y) x##y##1@ + + +/// \defgroup standard_io_hooks Standard I/O Logging and Tracing Hooks +/// +/// Standard I/O printing. The *TRACE* forms prefix the output with the file +/// name and line number. +/// +/// @{ + +#define PORE_PRINTF(...) HOOK_MARKER printf(__VA_ARGS__); + +#define PORE_FPRINTF(stream, ...) HOOK_MARKER fprintf(stream, __VA_ARGS__); + +#define PORE_TRACEF(fmt, ...) \ + HOOK_MARKER printf("%s:d:" fmt, __FILE__, __LINE__, ##__VA_ARGS__); + +#define PORE_FTRACEF(stream, fmt, ...) \ + HOOK_MARKER printf(stream, "%s:d:" fmt, __FILE__, __LINE__, ##__VA_ARGS__); + +/// @} + +/// \defgroup quickie_debugging_prints Quickie Debugging Print Hooks +/// +/// Quickie debugging prints. You provide a register name and string (w/o +/// newline), the macro formats the data. +/// +/// @{ + +#define PORE_PRINT_REG(msg, reg, fmt, fn) \ + PORE_PRINTF(msg " : " #reg " = " FMT_##fmt "\n", fn) + +#define PORE_TRACE_REG(msg, reg, fmt, fn) \ + PORE_TRACEF(msg " : " #reg " = " FMT_##fmt "\n", fn) + +#define PORE_PRINT_D0(msg) PORE_PRINT_REG(msg, D0, DX, d0()) +#define PORE_PRINT_D1(msg) PORE_PRINT_REG(msg, D1, DX, d1()) +#define PORE_PRINT_A0(msg) PORE_PRINT_REG(msg, A0, AX, a0()) +#define PORE_PRINT_A1(msg) PORE_PRINT_REG(msg, A1, AX, a1()) +#define PORE_PRINT_P0(msg) PORE_PRINT_REG(msg, P0, PX, p0()) +#define PORE_PRINT_P1(msg) PORE_PRINT_REG(msg, P1, PX, p1()) +#define PORE_PRINT_CTR(msg) PORE_PRINT_REG(msg, CTR, CTR, ctr()) +#define PORE_PRINT_SPRG0(msg) PORE_PRINT_REG(msg, SPRG0, SPRG0, sprg0()) +#define PORE_PRINT_STATUS(msg) PORE_PRINT_REG(msg, STATUS, STATUS, status()) +#define PORE_PRINT_CONTROL(msg) PORE_PRINT_REG(msg, CONTROL, CONTROL, control()) + +#define PORE_TRACE_D0(msg) PORE_TRACE_REG(msg, D0, DX, d0()) +#define PORE_TRACE_D1(msg) PORE_TRACE_REG(msg, D1, DX, d1()) +#define PORE_TRACE_A0(msg) PORE_TRACE_REG(msg, A0, AX, a0()) +#define PORE_TRACE_A1(msg) PORE_TRACE_REG(msg, A1, AX, a1()) +#define PORE_TRACE_P0(msg) PORE_TRACE_REG(msg, P0, PX, p0()) +#define PORE_TRACE_P1(msg) PORE_TRACE_REG(msg, P1, PX, p1()) +#define PORE_TRACE_CTR(msg) PORE_TRACE_REG(msg, CTR, CTR, ctr()) +#define PORE_TRACE_SPRG0(msg) PORE_TRACE_REG(msg, SPRG0, SPRG0, sprg0()) +#define PORE_TRACE_STATUS(msg) PORE_TRACE_REG(msg, STATUS, STATUS, status()) +#define PORE_TRACE_CONTROL(msg) PORE_TRACE_REG(msg, CONTROL, CONTROL, control()) + +/// @} + +/// \defgroup simics_style_logging Simics-style Logging Hooks +/// +/// Simics-style logging. All of these will produce a Simics prefix detailing +/// the unit that failed. The *_TRACE_* forms add the file name and line number +/// to the Simics info, print a newline and then format the trace message on +/// the following line. +/// +/// @{ + +#define SIM_LOG_INFO(level, group, ...) HOOK_MARKER \ + SIM_log_info(level, io_pore.d_log, group, __VA_ARGS__); + +#define SIM_LOG_ERROR(group, ...) HOOK_MARKER \ + SIM_log_error(io_pore.d_log, group, __VA_ARGS__); + +#define SIM_TRACE_INFO(level, group, fmt, ...) HOOK_MARKER \ + SIM_log_info(level, io_pore.d_log, group, \ + "%s:%d\n" fmt, __FILE__, __LINE__,## __VA_ARGS__); + +#define SIM_TRACE_ERROR(group, fmt, ...) HOOK_MARKER \ + SIM_log_error(io_pore.d_log, group, \ + "%s:%d\n" fmt, __FILE__, __LINE__, ##__VA_ARGS__); + +/// @} + +/// \defgroup vcl_style_3_level_printing VCL-style 3-Level Logging Hooks +/// +/// Define VCL-style 3-level logging and tracing, with programmable Simics +/// log-level selection. All logs are controlled by (?) group 0. Note that +/// setting the Simics log-level to 4 produces gobs of output from every part +/// of the system, however here at the debug level of 3 we only get messages +/// from hooks. +/// +/// @{ + +#ifndef SIMICS_LOG_LEVEL_OUTPUT +#define SIMICS_LOG_LEVEL_OUTPUT 1 +#endif + +#ifndef SIMICS_LOG_LEVEL_INFO +#define SIMICS_LOG_LEVEL_INFO 2 +#endif + +#ifndef SIMICS_LOG_LEVEL_DEBUG +#define SIMICS_LOG_LEVEL_DEBUG 3 +#endif + +#define PORE_LOG_OUTPUT(...) SIM_LOG_INFO(SIMICS_LOG_LEVEL_OUTPUT, 0, __VA_ARGS__) +#define PORE_LOG_INFO(...) SIM_LOG_INFO(SIMICS_LOG_LEVEL_INFO, 0, __VA_ARGS__) +#define PORE_LOG_DEBUG(...) SIM_LOG_INFO(SIMICS_LOG_LEVEL_DEBUG, 0, __VA_ARGS__) + +#define PORE_LOG_ERROR(...) SIM_LOG_ERROR(0, __VA_ARGS__) + +#define PORE_TRACE_OUTPUT(...) SIM_TRACE_INFO(SIMICS_LOG_LEVEL_OUTPUT, 0, __VA_ARGS__) +#define PORE_TRACE_INFO(...) SIM_TRACE_INFO(SIMICS_LOG_LEVEL_INFO, 0, __VA_ARGS__) +#define PORE_TRACE_DEBUG(...) SIM_TRACE_INFO(SIMICS_LOG_LEVEL_DEBUG, 0, __VA_ARGS__) + +#define PORE_TRACE_ERROR(...) SIM_TRACE_ERROR(0, __VA_ARGS__) + +/// @} + +/// Break Simics simulation +#define SIM_BREAK_SIMULATION(msg) \ + HOOK_MARKER SIM_break_simulation(msg); io_pore.dumpAll(); + + +/// A PORE Assertion +#define PORE_ASSERT(assertion) \ + HOOK_MARKER \ + if (!(assertion)) { \ + SIM_log_error(io_pore.d_log, 0, \ + "Assertion below failed\n" #assertion); \ + SIM_break_simulation("Assertion failure"); \ + } + + +/// Dump the PORE state +#define PORE_DUMP(...) LOG_OUTPUT(__VA_ARGS__) io_pore.dumpAll(); + +#endif // __PORE_HOOKS_H__ |