diff options
Diffstat (limited to 'src/sbefw')
-rw-r--r-- | src/sbefw/sbefwfiles.mk | 1 | ||||
-rw-r--r-- | src/sbefw/sbemain.C | 4 | ||||
-rw-r--r-- | src/sbefw/sbeutil.C | 41 | ||||
-rw-r--r-- | src/sbefw/sbeutil.H | 60 |
4 files changed, 106 insertions, 0 deletions
diff --git a/src/sbefw/sbefwfiles.mk b/src/sbefw/sbefwfiles.mk index b82f09ab..28e484b2 100644 --- a/src/sbefw/sbefwfiles.mk +++ b/src/sbefw/sbefwfiles.mk @@ -44,6 +44,7 @@ SBEFW-CPP-SOURCES += sbecmdringaccess.C SBEFW-CPP-SOURCES += sbescom.C SBEFW-CPP-SOURCES += sbecmdmpipl.C SBEFW-CPP-SOURCES += sbefapiutil.C +SBEFW-CPP-SOURCES += sbeutil.C SBEFW-C-SOURCES = SBEFW-S-SOURCES = diff --git a/src/sbefw/sbemain.C b/src/sbefw/sbemain.C index 7f1d25ec..83a02185 100644 --- a/src/sbefw/sbemain.C +++ b/src/sbefw/sbemain.C @@ -345,6 +345,10 @@ uint32_t main(int argc, char **argv) break; } + if(SBE::isSimicsRunning()) + { + SBE_INFO("SBE is running on simics"); + } // Start running the highest priority thread. // This function never returns pk_start_threads(); diff --git a/src/sbefw/sbeutil.C b/src/sbefw/sbeutil.C new file mode 100644 index 00000000..ac1eeacd --- /dev/null +++ b/src/sbefw/sbeutil.C @@ -0,0 +1,41 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/sbefw/sbeutil.C $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include "sbeutil.H" +namespace SBE +{ + bool isSimics() __attribute__((alias("__isSimicsRunning"))); + extern "C" void __isSimicsRunning() __attribute__ ((noinline)); + + void __isSimicsRunning() + { + asm volatile("li 3, 0"); + SBE_MAGIC_INSTRUCTION(MAGIC_SIMICS_CHECK); + } + + bool isSimicsRunning() + { + static bool simics = isSimics(); + return simics; + } +} 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 |