From 4b2c048529a64a79cbce403e070c5a7c138ba117 Mon Sep 17 00:00:00 2001 From: Sachin Gupta Date: Wed, 19 Oct 2016 16:33:08 -0500 Subject: Temporary Fix for timer Also include fix for changing the behavior on simics CMVC-Prereq: 1009109 Change-Id: Ib191e2c30ac508d2506ea1ed48dd76cc59da62f2 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31519 Tested-by: Jenkins Server Reviewed-by: AMIT J. TENDOLKAR Reviewed-by: RAJA DAS Tested-by: AMIT J. TENDOLKAR --- src/hwpf/src/plat/plat_utils.C | 18 +++++++- src/sbefw/sbefwfiles.mk | 1 + src/sbefw/sbemain.C | 4 ++ src/sbefw/sbeutil.C | 41 +++++++++++++++++ src/sbefw/sbeutil.H | 60 +++++++++++++++++++++++++ src/test/framework/etc/workarounds.postsimsetup | 3 ++ src/test/testcases/testUtil.py | 10 +++-- src/tools/debug/simics-debug-framework.py | 17 +++++++ 8 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 src/sbefw/sbeutil.C (limited to 'src') 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 #include #include +#include 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 ) + -- cgit v1.2.1