summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hwpf/src/plat/plat_utils.C18
-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
-rwxr-xr-xsrc/test/framework/etc/workarounds.postsimsetup3
-rw-r--r--src/test/testcases/testUtil.py10
-rwxr-xr-xsrc/tools/debug/simics-debug-framework.py17
8 files changed, 149 insertions, 5 deletions
diff --git a/src/hwpf/src/plat/plat_utils.C b/src/hwpf/src/plat/plat_utils.C
index 94adc7d6..4b5a60ea 100644
--- a/src/hwpf/src/plat/plat_utils.C
+++ b/src/hwpf/src/plat/plat_utils.C
@@ -34,6 +34,7 @@
#include <return_code.H>
#include <plat_trace.H>
#include <target.H>
+#include <sbeutil.H>
namespace fapi2
{
@@ -72,7 +73,22 @@ namespace fapi2
// The "accurate" version is the next line.
// target_time = pk_timebase_get() + PK_INTERVAL_SCALE(PK_NANOSECONDS(i_nanoSeconds));
- target_time = pk_timebase_get() + PK_INTERVAL_SCALE(PK_NANOSECONDS_SBE(i_nanoSeconds));
+ uint64_t cycles = 0;
+ if( SBE::isSimicsRunning() )
+ {
+ cycles = PK_INTERVAL_SCALE(
+ PK_NANOSECONDS_SBE(i_nanoSeconds));
+ }
+ else
+ {
+ // TODO via RTC 163216
+ // Fix for the timer ( using in cycle mode )
+ // Check what should be the right approach for time calculatin.
+ cycles = PK_INTERVAL_SCALE(
+ PK_NANOSECONDS_SBE(i_nanoSeconds)) * 64;
+ }
+ target_time = pk_timebase_get() + cycles;
+
do
{
current_time = pk_timebase_get();
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
diff --git a/src/test/framework/etc/workarounds.postsimsetup b/src/test/framework/etc/workarounds.postsimsetup
index ac7f3a29..0d29a9e0 100755
--- a/src/test/framework/etc/workarounds.postsimsetup
+++ b/src/test/framework/etc/workarounds.postsimsetup
@@ -42,3 +42,6 @@ mkdir -p $SANDBOXBASE/obj/ppc/simu/scripts/hbfw
cp $BACKING_BUILD/obj/ppc/simu/scripts/hbfw/standalone.simics $SANDBOXBASE/obj/ppc/simu/scripts/hbfw
patch -p0 $SANDBOXBASE/obj/ppc/simu/scripts/hbfw/standalone.simics $SBEROOT/src/test/framework/etc/patches/standalone.simics.patch
+# patch for magic instruction
+mkdir -p $SANDBOXBASE/imics/linux64/lib/
+cp -f /esw/san2/sgupta2m/MagicPatch/ppe.so $SANDBOXBASE/simics/linux64/lib/
diff --git a/src/test/testcases/testUtil.py b/src/test/testcases/testUtil.py
index db8fbfbb..7620ebc5 100644
--- a/src/test/testcases/testUtil.py
+++ b/src/test/testcases/testUtil.py
@@ -26,6 +26,8 @@ import time
import conf
from sim_commands import *
+waitItrCount = 10000000;
+cyclesPerIter = 20000;
#err = False
lbus = conf.p9Proc0.proc_lbus_map
def writeUsFifo( data):
@@ -112,9 +114,9 @@ def writeEntry(obj, address, value ):
if( status[2] & 0x02):
count = count + 1
- runCycles(200000)
+ runCycles(cyclesPerIter)
# This will cause test to fail
- if(count > 50):
+ if(count > waitItrCount):
raise Exception('Timeout. FIFO FULL');
else:
# write entry
@@ -141,9 +143,9 @@ def readEntry(obj, address, size):
loop = 0
else:
count = count + 1
- runCycles(200000)
+ runCycles(cyclesPerIter)
# This will cause test to fail
- if(count > 50):
+ if(count > waitItrCount):
raise Exception('Timeout. Empty FIFO');
return value
diff --git a/src/tools/debug/simics-debug-framework.py b/src/tools/debug/simics-debug-framework.py
index 3e064158..ec925983 100755
--- a/src/tools/debug/simics-debug-framework.py
+++ b/src/tools/debug/simics-debug-framework.py
@@ -83,7 +83,24 @@ def collectTrace ( procNr ):
SIM_run_alone( run_command, cmd3 )
SIM_run_alone( run_command, cmd4 )
+# MAGIC_INSTRUCTION hap handler
+# arg contains the integer parameter n passed to MAGIC_INSTRUCTION(n)
+# See src/include/arch/ppc.H for the definitions of the magic args.
+# SBE magic args should range 8000..8190.
+def sbe_magic_instruction_callback(user_arg, cpu, inst_num):
+ # Check if its for ppe processor
+ if(SIM_get_class_name(SIM_object_class(cpu)) != "ppe"):
+ return;
+
+ if inst_num == 8000: #MAGIC_SIMICS_CHECK
+ iface = SIM_get_interface(cpu, "int_register")
+ iface.write(iface.get_number("r3"), 1)
+ print "SBE::isSimicsRunning = true"
# Run the registration automatically whenever this script is loaded.
register_sbe_debug_framework_tools()
+# Register the magic instruction hap handler (a callback).
+# Currently registering a range does not work on simics for sbe
+SIM_hap_add_callback( "Core_Magic_Instruction", sbe_magic_instruction_callback, None )
+
OpenPOWER on IntegriCloud