summaryrefslogtreecommitdiffstats
path: root/src/sbefw/sbeutil.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw/sbeutil.H')
-rw-r--r--src/sbefw/sbeutil.H60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/sbefw/sbeutil.H b/src/sbefw/sbeutil.H
index 89ee9ed0..e8e3e281 100644
--- a/src/sbefw/sbeutil.H
+++ b/src/sbefw/sbeutil.H
@@ -41,6 +41,55 @@ if ((l_rc) != SBE_SEC_OPERATION_SUCCESSFUL) \
// To handle unused variables compilation error
static inline void UNUSED(int dummy, ...) {}
+// Magic instruction
+
+/** @brief This is a special assembler instruction that is a nop on
+ * regular hardware, but has special meaning to Simics. Code that
+ * executes this instruction in Simics will cause a "hap," a
+ * Simics term. If there is no hap handler registered, and magic
+ * breakpoints have not been enabled with
+ * simics> enable-magic-breakpoint
+ * then this instruction is also a nop in Simics.
+ *
+ * If magic breakpoints are enabled, and there is no hap handler, then
+ * when SBE code executes this instruction in Simics, Simics will
+ * stop the simulation. (Prompt changes from running> to simics> )
+ *
+ * If a hap is registered, then Simics will call the hap handler. Hap
+ * handlers are written in Python, and the best place for them is
+ *
+ * src/tools/debug//simics-debug-framework.py
+ *
+ * Sample code to register the hap handler:
+ * # arg contains the integer parameter n passed to MAGIC_INSTRUCTION(n)
+ * def magic_instruction_callback(user_arg, cpu, arg):
+ * # print to console works...
+ * print "Hit magic instruction ", arg
+ * # Or else stop the simulation...
+ * SIM_break_simulation( "Stopped at magic instruction" )
+ *
+ * # Register the magic instruction callback.
+ * SIM_hap_add_callback( "Core_Magic_Instruction",
+ * magic_instruction_callback, None )
+ *
+ * # Better to register the SBE range 8000-8190
+ * # so that PHYP and others won't be affected.
+ * SIM_hap_add_callback_range( "Core_Magic_Instruction",
+ * magic_instruction_callback, None, 8000, 8190 )
+ *
+ * The argument n is an integer from 0..8191 which Simics passes to the hap
+ * handler in parameter 3, or "arg" in the sample code above.
+ */
+__attribute__((always_inline))
+inline void SBE_MAGIC_INSTRUCTION(int _n)
+{
+ register int n = _n;
+ asm volatile("rlwimi %0,%0,0,%1,%2" \
+ :: "i" (((n) >> 8) & 0x1f), \
+ "i" (((n) >> 4) & 0xf), \
+ "i" ((((n) >> 0) & 0xf) | 16));
+}
+
// Macro to execute HWP
#ifdef SEEPROM_IMAGE
#define SBE_EXEC_HWP_NOARG(...) SBE_EXEC_HWP(__VA_ARGS__)
@@ -70,6 +119,11 @@ void sbeHandlePsuResponse (const uint32_t i_rc);
namespace SBE
{
+ // enum for magic instructions
+ enum
+ {
+ MAGIC_SIMICS_CHECK = 8000, // check if code is running on simics
+ };
// Nest to SBE frequency ratio
static const uint8_t SBE_TO_NEST_FREQ_FACTOR = 4;
@@ -106,5 +160,11 @@ namespace SBE
return (uint32_t)(MASK_ZERO_H32B_UINT64(i_lWord));
}
+ /*@brief - checks if sbe is running on simics
+ *
+ * @return - True if sbe is running on simics , false otherwise
+ */
+ bool isSimicsRunning();
+
} // namespace SBE
#endif //SBE_UTIL_H
OpenPOWER on IntegriCloud