diff options
Diffstat (limited to 'src/sbefw/sbeutil.H')
-rw-r--r-- | src/sbefw/sbeutil.H | 60 |
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 |