summaryrefslogtreecommitdiffstats
path: root/src/lib/pore_hooks.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pore_hooks.h')
-rwxr-xr-xsrc/lib/pore_hooks.h171
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__
OpenPOWER on IntegriCloud