summaryrefslogtreecommitdiffstats
path: root/src/sbefw
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbefw')
-rw-r--r--src/sbefw/sbefwfiles.mk1
-rw-r--r--src/sbefw/sbemain.C4
-rw-r--r--src/sbefw/sbeutil.C41
-rw-r--r--src/sbefw/sbeutil.H60
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
OpenPOWER on IntegriCloud