diff options
author | Terry J. Opie <opiet@us.ibm.com> | 2012-06-18 16:48:20 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-07-12 15:46:23 -0500 |
commit | d40d08c719c845213844323ead282a748486d466 (patch) | |
tree | 15b2ec8cdcd9da21b11d1a4c373c10ea9de74c4a /src/usr/initservice/istepdispatcher | |
parent | ec56bbb81f64a52ab2668befd33fef926a0170b6 (diff) | |
download | blackbird-hostboot-d40d08c719c845213844323ead282a748486d466.tar.gz blackbird-hostboot-d40d08c719c845213844323ead282a748486d466.zip |
Istep sync point message support
- Refactor IStepDispatcher for more robust msg handling
- Modify sptask to act like real Fsp
- Move all Istep Mbox Msg handling to Initservice
- Add send sync point interface
- Add wait on sync point interface
- Modify start_payload istep to use new interfaces
- Fix for Istep.pm
Change-Id: Ib28b89cd916b9c0a0d15016996dbf1b88a8f79eb
RTC: 43554
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1255
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/initservice/istepdispatcher')
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepWorker.C | 244 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepWorker.H | 81 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istep_mbox_msgs.H | 126 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.C | 1176 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/istepdispatcher.H | 235 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/makefile | 6 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/splesscommon.C | 12 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/splesscommon.H | 12 | ||||
-rw-r--r-- | src/usr/initservice/istepdispatcher/sptask.C | 60 |
9 files changed, 1161 insertions, 791 deletions
diff --git a/src/usr/initservice/istepdispatcher/istepWorker.C b/src/usr/initservice/istepdispatcher/istepWorker.C new file mode 100644 index 000000000..445d988e3 --- /dev/null +++ b/src/usr/initservice/istepdispatcher/istepWorker.C @@ -0,0 +1,244 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/initservice/istepdispatcher/istepWorker.C $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +/** + * @file istepWorker.C + * + * IStep Dispatcher worker thread. + * + */ + +/******************************************************************************/ +// Includes +/******************************************************************************/ +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include <sys/msg.h> + +#include <errl/errlentry.H> + +#include <isteps/istepmasterlist.H> + +#include "../baseinitsvc/initservice.H" + +//#include <initservice/initsvcudistep.H> // InitSvcUserDetailsIstep + +#include "istep_mbox_msgs.H" +#include "istepWorker.H" + +// ----- namespace INITSERVICE ------------------------------------------- +namespace INITSERVICE +{ +/******************************************************************************/ +// Globals/Constants +/******************************************************************************/ +extern trace_desc_t *g_trac_initsvc; + + +// ---------------------------------------------------------------------------- +// startIStepWorkerThread +// ---------------------------------------------------------------------------- +void startIStepWorkerThread ( void * io_args ) +{ + TRACFCOMP( g_trac_initsvc, + ENTER_MRK"startIStepWorkerThread()" ); + + // detach from main istep dispatcher thread + task_detach(); + + // Worker thread entry + iStepWorkerThread( io_args ); + + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"startIStepWorkerThread()" ); + + // Shutdown. + task_end(); +} + + +// ---------------------------------------------------------------------------- +// iStepWorkerThread() +// ---------------------------------------------------------------------------- +void iStepWorkerThread ( void * i_msgQ ) +{ + errlHndl_t err = NULL; + msg_q_t theQ = static_cast<msg_q_t>( i_msgQ ); + msg_t * theMsg = NULL; + uint32_t istep = 0x0; + uint32_t substep = 0x0; + uint64_t progressCode = 0x0; + + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"iStepWorkerThread()" ); + + while( 1 ) + { + // Send More Work Needed msg to the main thread. + theMsg = msg_allocate(); + theMsg->type = MORE_WORK_NEEDED; + theMsg->data[0] = 0x0; + theMsg->data[1] = 0x0; + theMsg->extra_data = err; + err = NULL; + + // Wait here until the main thread has work for us. + msg_sendrecv( theQ, + theMsg ); + + // Got a response... The step/substep to execute are in data[0] + istep = ((theMsg->data[0] & 0xFF00) >> 8); + substep = (theMsg->data[0] & 0xFF); + + // Post the Progress Code + // TODO - Covered with RTC: 34046 + InitService::getTheInstance().setProgressCode( progressCode ); + + // Get the Task Info for this step + const TaskInfo * theStep = findTaskInfo( istep, + substep ); + + if( NULL != theStep ) + { + TRACFCOMP( g_trac_initsvc, + "IStepDispatcher (worker): Run Istep (%d), substep(%d), " + "- %s", + istep, substep, theStep->taskname ); + + err = InitService::getTheInstance().executeFn( theStep, + NULL ); + + if( err ) + { + TRACFCOMP( g_trac_initsvc, + "IStepDipspatcher (worker): Istep %s returned " + "errlog=%p", + theStep->taskname, err ); + } + } + else + { + // Nothing to do for this step. + TRACDCOMP( g_trac_initsvc, + INFO_MRK"Empty Istep, nothing to do!" ); + } + + msg_free( theMsg ); + theMsg = NULL; + } + + // Something bad happened... this thread should never exit once started + assert( 0 ); + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"iStepWorkerThread()" ); +} + + +// ---------------------------------------------------------------------------- +// findTaskInfo() +// ---------------------------------------------------------------------------- +const TaskInfo * findTaskInfo( const uint32_t i_IStep, + const uint32_t i_SubStep ) +{ + // default return is NULL + const TaskInfo *l_pistep = NULL; + /** + * @todo + * everything calling this should feed into the "real" istep/substep + * numbers ( starting at 1 ) - this routine should translate to index into + * the isteplists ( starting at 0 ) + * + * int32_t l_istepIndex = i_IStep-1; + * int32_t l_substepIndex = i_SubStep-1; + * + * assert( l_istepIndex >= 0 ); + * assert( l_substepIndex >= 0 ); + */ + + // apply filters + do + { + // Sanity check / dummy IStep + if( g_isteps[i_IStep].pti == NULL) + { + TRACDCOMP( g_trac_initsvc, + "g_isteps[%d].pti == NULL (substep=%d)", + i_IStep, + i_SubStep ); + break; + } + + // check input range - IStep + if( i_IStep >= INITSERVICE::MaxISteps ) + { + TRACDCOMP( g_trac_initsvc, + "IStep %d out of range. (substep=%d) ", + i_IStep, + i_SubStep ); + break; // break out with l_pistep set to NULL + } + + // check input range - ISubStep + if( i_SubStep >= g_isteps[i_IStep].numitems ) + { + TRACDCOMP( g_trac_initsvc, + "IStep %d Substep %d out of range.", + i_IStep, + i_SubStep ); + break; // break out with l_pistep set to NULL + } + + // check for end of list. + if( g_isteps[i_IStep].pti[i_SubStep].taskflags.task_type + == END_TASK_LIST ) + { + TRACDCOMP( g_trac_initsvc, + "IStep %d SubStep %d task_type==END_TASK_LIST.", + i_IStep, + i_SubStep ); + break; + } + + // check to see if the pointer to the function is NULL. + // This is possible if some of the substeps aren't working yet + // and are just placeholders. + if( g_isteps[i_IStep].pti[i_SubStep].taskfn == NULL ) + { + TRACDCOMP( g_trac_initsvc, + "IStep %d SubStep %d fn ptr is NULL.", + i_IStep, + i_SubStep ); + break; + } + + // we're good, set the istep & return it to caller + l_pistep = &( g_isteps[i_IStep].pti[i_SubStep] ); + } while( 0 ); + + return l_pistep; +} + + +} // namespace diff --git a/src/usr/initservice/istepdispatcher/istepWorker.H b/src/usr/initservice/istepdispatcher/istepWorker.H new file mode 100644 index 000000000..f9ed47e24 --- /dev/null +++ b/src/usr/initservice/istepdispatcher/istepWorker.H @@ -0,0 +1,81 @@ +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/initservice/istepdispatcher/istepWorker.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ +#ifndef __ISTEPWORKER_H +#define __ISTEPWORKER_H +/** + * @file istepWorker.H + * + * IStep Dispatcher Worker thread + */ + +/******************************************************************************/ +// Includes +/******************************************************************************/ +#include <stdint.h> + +#include <initservice/initsvcstructs.H> + + +namespace INITSERVICE +{ + +/** +* @brief This function is called to start the task. +* +* @param[in/out] io_args - This is a void pointer, but the code expects that +* this will be the msg queue to communicate with the main thread. +* +* @return NONE. +*/ +void startIStepWorkerThread ( void * io_args ); + +/** +* @brief This function is the main loop for the Istep dispatcher worker +* thread. +* +* @param[in] i_msgQ - The message queue to talk to the main thread. +* +* @return NONE. + */ +void iStepWorkerThread ( void * i_msgQ ); + +/** + * @brief This function will be used to query the istep master list and the + * other istep headers to know what functions/tasks need to be started + * for the Istep/Substep that we are in. + * + * @param[in] i_IStep - The Istep to run. + * + * @param[in] i_SubStep - The SubStep to run. + * + * @return TaskInfo - The task info for the task to start as a result of the + * requested Istep/Substep. + */ +const TaskInfo * findTaskInfo ( const uint32_t i_IStep, + const uint32_t i_SubStep ); + + +} // namespace + +#endif diff --git a/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H b/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H index ae3ca45ff..e002a7aba 100644 --- a/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H +++ b/src/usr/initservice/istepdispatcher/istep_mbox_msgs.H @@ -1,62 +1,100 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/istepdispatcher/istep_mbox_msgs.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2012 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG + * This is an automatically generated prolog. + * + * $Source: src/usr/initservice/istepdispatcher/istep_mbox_msgs.H $ + * + * IBM CONFIDENTIAL + * + * COPYRIGHT International Business Machines Corp. 2012 + * + * p1 + * + * Object Code Only (OCO) source materials + * Licensed Internal Code Source Materials + * IBM HostBoot Licensed Internal Code + * + * The source code for this program is not published or other- + * wise divested of its trade secrets, irrespective of what has + * been deposited with the U.S. Copyright Office. + * + * Origin: 30 + * + * IBM_PROLOG_END_TAG + */ #ifndef __INITSERVICE_ISTEP_MBOX_MSGS_H #define __INITSERVICE_ISTEP_MBOX_MSGS_H +#include <mbox/mbox_queues.H> + /** * @file istep_mbox_msgs.H * * @brief Mailbox types used by IStepDisp to communicate with FSP/SP * */ +namespace INITSERVICE +{ -#include "splesscommon.H" +const uint32_t SPLESS_MSG = 0x000F0000; +const uint32_t ISTEP_WORKER_MSG = 0x00F00000; -namespace INITSERVICE +// ------------------------------------------------------------------ +// HwSvr Msg Type Enums +enum { + HWSVR_BREAKPOINT = 0x00, + HWSVR_SYNC_POINT = 0x10, +}; +// ------------------------------------------------------------------ +// Worker Thread Msg Type Enums enum { - // TODO - I'm not changing this file, but I would really like to put the - // SYNC_POINT_REACHED message here. Since its related to Isteps and - // syncing Hostboot and Fsp. But to do that, this needs to be in the - // src/include/usr side of things. - // - // Plus, I think its weird that this file uses definitions from - // splesscommon.H. It should be the other way around. Define them here - // and use them from splesscommon. Issue 42491 has been opened to - // discuss this further. - // - // I am going to define my own message in the code that I'm writing until - // we get something figured out. - SINGLE_STEP_TYPE = MBOX::FIRST_SECURE_MSG | - SPLESS::SPLESS_SINGLE_ISTEP_CMD, - CLEAR_TRACE_TYPE = MBOX::FIRST_SECURE_MSG | - SPLESS::SPLESS_CLEAR_TRACE_CMD, - SHUTDOWN_TYPE = MBOX::FIRST_SECURE_MSG | - SPLESS::SPLESS_SHUTDOWN_CMD, - BREAKPOINT_TYPE = MBOX::FIRST_UNSECURE_MSG | - SPLESS::SPLESS_AT_BREAK_POINT + WORKER_MORE_WORK_NEEDED = 0x00, + WORKER_BREAKPOINT = 0x01, +}; + +// ------------------------------------------------------------------ +// SPLess Msg Type Enums +enum +{ + // Randomly picked 0xAA since SPLess mode looks at this to know whether it + // got a shutdown. originall was 0x0, and shutdown every time. + // TODO - need to check if the simics script needs to know this value. + // Opened Issue 45042 to have this as well as hb-istep support of shutdown + // removed. + SPLESS_SHUTDOWN_CMD = 0xAA, +}; + +// ------------------------------------------------------------------ +// Msgs that IstepDispatcher can accept +enum +{ + // -------------------------------------------------------------- + // General Messages from all sources + // -------------------------------------------------------------- + SYNC_POINT_REACHED = MBOX::FIRST_UNSECURE_MSG | + HWSVR_SYNC_POINT, + BREAKPOINT = MBOX::FIRST_UNSECURE_MSG | + HWSVR_BREAKPOINT, + + // -------------------------------------------------------------- + // Worker Thread Messages + // -------------------------------------------------------------- + MORE_WORK_NEEDED = MBOX::FIRST_SECURE_MSG | + ISTEP_WORKER_MSG | + WORKER_MORE_WORK_NEEDED, + BREAKPOINT_WORKER = MBOX::FIRST_SECURE_MSG | + ISTEP_WORKER_MSG | + WORKER_BREAKPOINT, + + // -------------------------------------------------------------- + // SPLess Messages + // -------------------------------------------------------------- + SHUTDOWN_SPLESS = MBOX::FIRST_SECURE_MSG | + SPLESS_MSG | + SPLESS_SHUTDOWN_CMD, + }; } // namespace diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 38f838871..649b6e3d1 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -38,25 +38,17 @@ #include <stdio.h> #include <string.h> - #include <kernel/console.H> // printk status -// turn on clearAllBuffers() -#define __HIDDEN_TRACEIF_CLEARBUFFER -#include <vfs/vfs.H> // load_module #include <sys/task.h> // tid_t, task_create, etc -#include <sys/time.h> // nanosleep -#include <sys/misc.h> // shutdown - -#include <trace/interface.H> // trace support #include <errl/errlentry.H> // errlHndl_t + #include <devicefw/userif.H> // targeting #include <initservice/isteps_trace.H> // ISTEPS_TRACE buffer #include <initservice/initsvcudistep.H> // InitSvcUserDetailsIstep -#include <initservice/taskargs.H> // TASK_ENTRY_MACRO - +#include <initservice/taskargs.H> // TASK_ENTRY_MACRO #include <targeting/common/attributes.H> // ISTEP_MODE attribute #include <targeting/common/targetservice.H> @@ -64,13 +56,13 @@ #include <mbox/mbox_queues.H> // HB_ISTEP_MSGQ #include <mbox/mboxif.H> // register mailbox +#include <isteps/istepmasterlist.H> + #include "istepdispatcher.H" +#include "istepWorker.H" #include "splesscommon.H" -#include <isteps/istepmasterlist.H> -#include <targeting/common/attributes.H> - // ----- namespace ISTEPS_TRACE --------------------------------------- namespace ISTEPS_TRACE { @@ -94,752 +86,782 @@ using namespace SPLESS; // SingleStepMode /******************************************************************************/ extern trace_desc_t *g_trac_initsvc; +const MBOX::queue_id_t HWSVRQ = MBOX::IPL_SERVICE_QUEUE; + /** * _start() task entry procedure using the macro in taskargs.H */ TASK_ENTRY_MACRO( IStepDispatcher::getTheInstance().init ); +// ---------------------------------------------------------------------------- +// IstepDispatcher() +// ---------------------------------------------------------------------------- +IStepDispatcher::IStepDispatcher () + : iv_workerMsg( NULL ) +{ + SPLESS::initIStepMode(); + mutex_init( &iv_bkPtMutex ); + mutex_init( &iv_syncMutex ); + mutex_init( &iv_stepMutex ); + sync_cond_init( &iv_syncHit ); + + iv_curIStep = 0x0; + iv_curSubStep = 0x0; + iv_sync = false; + // init mailbox / message Q. + iv_msgQ = msg_q_create(); +} -void IStepDispatcher::init( errlHndl_t &io_rtaskRetErrl ) +// ---------------------------------------------------------------------------- +// ~IstepDispatcher() +// ---------------------------------------------------------------------------- +IStepDispatcher::~IStepDispatcher () { - errlHndl_t l_errl = NULL; +} - // initialize (and declare) ISTEPS_TRACE here, the rest of the isteps will use it. - ISTEPS_TRACE::g_trac_isteps_trace = NULL; - printk( "IstepDispatcher entry.\n" ); +// ---------------------------------------------------------------------------- +// IstepDispatcher::getTheInstance() +// ---------------------------------------------------------------------------- +IStepDispatcher& IStepDispatcher::getTheInstance () +{ + return Singleton<IStepDispatcher>::instance(); +} - TRACFCOMP( g_trac_initsvc, - "IStep Dispatcher entry." ); +// ---------------------------------------------------------------------------- +// IStepDispatcher::init() +// ---------------------------------------------------------------------------- +void IStepDispatcher::init ( errlHndl_t &io_rtaskRetErrl ) +{ + errlHndl_t err = NULL; + + // initialize (and declare) ISTEPS_TRACE here, the rest of the isteps will + // use it. + ISTEPS_TRACE::g_trac_isteps_trace = NULL; TRAC_INIT(&ISTEPS_TRACE::g_trac_isteps_trace, "ISTEPS_TRACE", 2048 ); + printk( "IstepDispatcher entry.\n" ); + TRACFCOMP( g_trac_initsvc, + "IStep Dispatcher entry." ); - if ( getIStepMode() == true ) + do { - printk( "IStep single-step\n" ); - TRACFCOMP( g_trac_initsvc, - "IStep single-step" ); + if( !(SPLESS::SPLessAttached()) ) + { + // register message Q with FSP Mailbox - only if Fsp attached. + err = MBOX::msgq_register( MBOX::HB_ISTEP_MSGQ, + iv_msgQ ); + + if( err ) + { + break; + } + } - if ( SPLESS::SPLessAttached( ) ) + // Spawn off the Worker thread + tid_t l_workerTid = task_create( startIStepWorkerThread, + iv_msgQ ); + assert( l_workerTid > 0 ); + + // Check for SPLess operation + if( SPLESS::SPLessAttached() ) { // SPless user console is attached, // launch SPTask. - TRACFCOMP( g_trac_initsvc, - "IStep single-step enable (SPLESS)" ); + "IStep single-step enable (SPLESS)" ); - tid_t l_spTaskTid = task_create( spTask, iv_msgQ ); - // should never happen... + tid_t l_spTaskTid = task_create( spTask, + iv_msgQ ); assert( l_spTaskTid > 0 ); + } - // sptask will turn on the ready bit when it is up. + if( err ) + { + TRACFCOMP( g_trac_initsvc, + "ERROR: Failed to register mailbox, terminating" ); - // IStep single-step - singleStepISteps( io_rtaskRetErrl ); + break; } - else + + if( getIStepMode() ) { + printk( "IStep single-step\n" ); TRACFCOMP( g_trac_initsvc, - "IStep single-step enable (FSP)" ); + "IStep single-step" ); - // register message Q with FSP Mailbox - l_errl = MBOX::msgq_register( - MBOX::HB_ISTEP_MSGQ, - iv_msgQ ) ; - if ( l_errl ) + err = msgHndlr(); + if( err ) { - TRACFCOMP( g_trac_initsvc, - "ERROR: Failed to register mailbox, terminating" ); - // fall through and report errorlog - io_rtaskRetErrl = l_errl; + break; } - else + } + else + { + printk( "IStep run-all\n" ); + TRACFCOMP( g_trac_initsvc, + "IStep run all" ); + + // Execute all Isteps sequentially in 'normal' mode + err = executeAllISteps(); + if( err ) { - // IStep single-step - singleStepISteps( io_rtaskRetErrl ); + break; } } - } - else - { - printk( "IStep run-all\n" ); - - TRACFCOMP( g_trac_initsvc, - "IStep run all" ); - - // Run all the ISteps sequentially - runAllISteps( io_rtaskRetErrl ); - } // endelse - + } while( 0 ); TRACFCOMP( g_trac_initsvc, "IStepDispatcher finished."); - printk( "IStepDispatcher exit.\n" ); - - task_end2( io_rtaskRetErrl ); + task_end2( err ); } -void IStepDispatcher::runAllISteps( errlHndl_t &io_rtaskRetErrl ) + +// ---------------------------------------------------------------------------- +// IStepDispatcher::executeAllISteps() +// ---------------------------------------------------------------------------- +errlHndl_t IStepDispatcher::executeAllISteps ( void ) { - errlHndl_t l_errl = NULL; - uint32_t l_IStep = 0; - uint32_t l_SubStep = 0; - const TaskInfo *l_pistep = NULL; - uint64_t l_progresscode = 0; + errlHndl_t err = NULL; + msg_t * theMsg = NULL; + TRACFCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::executeAllISteps()" ); - for ( l_IStep=0; - l_IStep<INITSERVICE::MaxISteps; - l_IStep++ ) + do { - TRACDCOMP( g_trac_initsvc, - "runAllISteps: IStep %d: %d entries", - l_IStep, - g_isteps[l_IStep].numitems ); - - for ( l_SubStep=0; - l_SubStep < g_isteps[l_IStep].numitems; - l_SubStep++) + // Sequentially loop through all isteps, executing each by replying to + // work needed msg from worker thread. + uint32_t prevIstep = 0; + uint32_t prevSubStep = 0; + for( size_t istep = 0; + istep < MaxISteps; + istep++ ) { - /** - * @todo refactor - replace the following block with - * processSingleIStepCmd() - */ - - l_pistep = findTaskInfo( - l_IStep, - l_SubStep ); - if ( l_pistep == NULL ) + // Run until num items +1, to be sure we know the last step + // finished + for( size_t substep = 0; + substep < (g_isteps[istep].numitems + 1); + substep++ ) { - // continue to end of list - continue; - } + // Before we can do anything, we need to be sure the worker thread is + // ready to start + theMsg = msg_wait( iv_msgQ ); + + // check for sync msgs + if( theMsg->type == SYNC_POINT_REACHED ) + { + TRACFCOMP( g_trac_initsvc, + INFO_MRK"Got sync msg (0x%08x)", + theMsg->type ); + handleSyncPointReachedMsg(); + + // We didn't really do anything for this substep + substep--; + continue; + } + + // If we just got the msg that the last step finished, break + // out + if( substep == (g_isteps[istep].numitems + 1) ) + { + TRACFCOMP( g_trac_initsvc, + INFO_MRK"Last Step, exit" ); + break; + } + + // Look for an errlog in extra_data + if( NULL != theMsg->extra_data ) + { + TRACFCOMP( g_trac_initsvc, + ERR_MRK"Error returned from istep(%d), substep(%d)", + prevIstep, prevSubStep ); + + err = ((errlHndl_t)theMsg->extra_data); + + break; + } + + TRACFCOMP( g_trac_initsvc, + INFO_MRK"executeAllSteps(0x%08x), istep: %d, substep: %d", + theMsg->type, istep, substep ); - // @todo placeholder until progress codes are defined and - // progress code driver is implemented. - l_progresscode = 0; - InitService::getTheInstance().setProgressCode( l_progresscode ); + // Set the Istep info + prevIstep = istep; + prevSubStep = substep; + uint16_t istepInfo = ((istep << 8 ) | substep); + setIstepInfo( istepInfo ); - // print out what we are running - TRACFCOMP( g_trac_initsvc, - "IStepDisp: Run IStep %d.%d %s", - l_IStep, - l_SubStep, - l_pistep->taskname ); + // Put the step/substep into data[0] for the worker thread + theMsg->data[0] = istepInfo; + msg_respond( iv_msgQ, + theMsg ); - l_errl = InitService::getTheInstance().executeFn( - l_pistep, - NULL ); + theMsg = NULL; + } - // check for errors - if ( l_errl ) + if( err ) { - TRACFCOMP( g_trac_initsvc, - "IStepDisp: istep %s returned errlog=%p", - l_pistep->taskname, - l_errl ); - // if we have an errorlog, break out of the inner loop - // and handle it. break; } - } // endfor l_SubStep + } - if ( l_errl ) + if( err ) { - // something left an error log in the inner loop, breakout break; } - } // endfor l_IStep - - - /** - * @todo detect Can-Continue condition here and reset/rerun ISteps. - * For now this is pushed to a later sprint. - */ - - // - if ( l_errl ) - { - TRACFCOMP( g_trac_initsvc, - "IStepDisp ERROR: errorlog %p", - l_errl ); + } while ( 0 ); - // return to _start() with the errorlog set, parent should do shutdown - io_rtaskRetErrl = l_errl; - } + TRACFCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::executeAllISteps()" ); - // return to init with io_rtaskRetErrl set + return err; } -void IStepDispatcher::singleStepISteps( errlHndl_t &io_rtaskRetErrl ) +// ---------------------------------------------------------------------------- +// IStepDispatcher::msgHndlr() +// ---------------------------------------------------------------------------- +errlHndl_t IStepDispatcher::msgHndlr ( void ) { - uint32_t l_Type = 0; - uint32_t l_IStep = 0; - uint32_t l_Substep = 0; - bool l_quitflag = false; - uint32_t l_RetSts = 0; - errlHndl_t l_errl = NULL; - uint32_t l_PLID = 0; + errlHndl_t err = NULL; + msg_t * theMsg = NULL; - mutex_lock(&iv_poll_mutex); // make sure this is only poller + // TODO - Issue 45012 + // There is enough common code between this path and executeAllISteps() + // that the issue above will be used to combine the 2 paths into one + // commone code path. - while ( 1 ) + TRACFCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::msgHndlr()" ); + + // We will stay in this loop unless there is a failure or other reason to + // exit out and terminate. This loop is the main handler for the Istep + // Dispatcher. It receives all messages from the Fsp, Child worker + // thread, and the SPLess task. + while( 1 ) { + theMsg = msg_wait( iv_msgQ ); TRACDCOMP( g_trac_initsvc, - "IStepDisp wait for message." ); - - // wait for message from FSP or Dispatcher - iv_pMsg = msg_wait( iv_msgQ ); + INFO_MRK"Got Msg - Type: 0x%08x", + theMsg->type ); - // unblocked - if ( msg_is_async( iv_pMsg ) ) + switch( theMsg->type ) { - // should not receive async messages here, drop it, post errorlog - // and go back to waiting. - TRACFCOMP( g_trac_initsvc, - "singleStepISteps: ERROR async msg type 0x%x, msg 0x%x.%x", - iv_pMsg->type, - static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ), - static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) ); - - /*@ errorlog tag - * @errortype ERRL_SEV_INFORMATIONAL - * @moduleid ISTEP_INITSVC_MOD_ID - * @reasoncode ISTEP_SINGLESTEP_ASYNC_RCVD - * @userdata1 type of packet - * @userdata2 first data word - * - * @devdesc IStepDisp singleStepISteps was expecting a - * synchronous message and received an asynchonous - * message. - * - */ - errlHndl_t l_errlAsync = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - INITSERVICE::ISTEP_INITSVC_MOD_ID, - INITSERVICE::ISTEP_SINGLESTEP_ASYNC_RCVD, - iv_pMsg->type, - iv_pMsg->data[0] ); - - errlCommit( l_errlAsync, INITSVC_COMP_ID ); - - msg_free(iv_pMsg); - iv_pMsg = NULL; - - continue; - } - - - l_Type = iv_pMsg->type; - l_IStep = static_cast<uint32_t>( iv_pMsg->data[0] >>32 ) ; - l_Substep = static_cast<uint32_t>( iv_pMsg->data[0] & 0x0FFFFFFFF ); - - TRACDCOMP( g_trac_initsvc, - "IStepDisp recv msg type 0x%x, 0x%x.%x", - l_Type, - l_IStep, - l_Substep ); - - // Clear Status and PLID fields for response msg - l_RetSts = 0; - l_PLID = 0; - - switch( l_Type ) - { - case SINGLE_STEP_TYPE: - mutex_unlock(&iv_poll_mutex); - // command 0: run istep/substep - TRACDCOMP( g_trac_initsvc, - "Run istep %d.%d ", - l_IStep, - l_Substep ); - l_errl = processSingleIStepCmd( l_IStep, l_Substep, l_RetSts ); - mutex_lock(&iv_poll_mutex); + case SYNC_POINT_REACHED: + // Sync point reached from Fsp + iv_Msg = theMsg; + handleSyncPointReachedMsg(); break; - case BREAKPOINT_TYPE: // not at break point here - TRACDCOMP( g_trac_initsvc, - "Not at break point." ); - l_RetSts = SPLESS_NOT_AT_BREAK_POINT; + case MORE_WORK_NEEDED: + // Worker thread is ready for more work. + iv_workerMsg = theMsg; + handleMoreWorkNeededMsg(); break; - case CLEAR_TRACE_TYPE: - TRAC_CLEAR_BUFFERS(); - TRACFCOMP( g_trac_initsvc, - "Cleared all trace buffers." ); - l_RetSts = SPLESS_TRACE_BUFFERS_CLEARED; - break; + case SHUTDOWN_SPLESS: + // Creat errorlog to return as part of the shutdown. + /*@ + * @errortype + * @reasoncode INITSERVICE::ISTEP_SHUTDOWN + * @severity ERRORLOG::ERRL_SEV_INFORMATIONAL + * @moduleid INITSERVICE::ISTEP_INITSVC_MOD_ID + * @userdata1 <UNUSED> + * @userdata2 <UNUSED> + * @devdesc Istep initiated Shutdown. + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL, + INITSERVICE::ISTEP_INITSVC_MOD_ID, + INITSERVICE::ISTEP_SHUTDOWN, + 0, 0 ); - case SHUTDOWN_TYPE: - TRACFCOMP( g_trac_initsvc, - "Shutting down HostBoot. " ); - l_RetSts = SPLESS_SHUTTING_DOWN; - l_quitflag = true; break; default: - TRACFCOMP( g_trac_initsvc, - "ERROR: invalid command 0x%x ", - l_Type ); - l_RetSts = SPLESS_INVALID_COMMAND; + // Default Message + // This SHOULD be a message from the Fsp with the Step/substep + // to be executed. + // Gotta check to make sure Fsp hadn't sent us a 2nd Istep + // request for some reason, if so, its an error. + if( iv_Msg ) + { + TRACFCOMP( g_trac_initsvc, + ERR_MRK"ERROR: IStep Dispatcher already has another " + "Istep request for step: 0x%02x, substep: 0x%02x", + ((iv_Msg->type & 0xFF00) >> 8), + (iv_Msg->type & 0xFF) ); + + /*@ + * @errortype + * @reasoncode ISTEP_MULTIPLE_ISTEP_REQ + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid ISTEP_INITSVC_MOD_ID + * @userdata1 Current Istep + * @userdata2 Current SubStep + * @devdesc A Second Istep request has been made + * and we are still working on a + * previous Istep. + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_INITSVC_MOD_ID, + ISTEP_MULTIPLE_ISTEP_REQ, + ((iv_Msg->type & 0xFF00) >> 8), + (iv_Msg->type & 0xFF) ); + + break; + } + + iv_Msg = theMsg; + handleIStepRequestMsg(); break; - } // end switch + }; - if ( l_errl ) + if( err ) { - // tell the user console that the IStep returned an errorlog - l_RetSts = SPLESS_TASKRC_RETURNED_ERRLOG; - // get the platform log identifier (PLID) to send to FSP - l_PLID = l_errl->plid(); - - // go ahead and commit the child errorlog - errlCommit( l_errl, INITSVC_COMP_ID ); + // Breaking here will be a BAD thing... It means that we are + // exiting not just Istep Dispatcher, but all of Hostboot. There + // are 2 cases where we would exit here: + // 1. Shutdown requested via istep (SPLESS) + // 2. Error during an Istep. + errlCommit( err, + INITSVC_COMP_ID ); } + } - iv_pMsg->type = l_Type; - // Return l_RetSts as hi word of data[0] - // Return l_PLID as lo word of data[0] - iv_pMsg->data[0] = - ( static_cast<uint64_t>( l_RetSts ) << 32 ) | - static_cast<uint64_t>( l_PLID ) ; + TRACFCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::msgHndlr()" ); - iv_pMsg->data[1] = 0; - iv_pMsg->extra_data = NULL; + return err; +} - TRACDCOMP( g_trac_initsvc, - "IStepDisp send msg type 0x%x, 0x%x.%x", - iv_pMsg->type, - static_cast<uint32_t>( iv_pMsg->data[0] >> 32), - static_cast<uint32_t>( iv_pMsg->data[0] & 0xFFFFFFFF )); - // send status back - msg_respond( iv_msgQ, iv_pMsg ); +// ---------------------------------------------------------------------------- +// waitForSyncPoint() +// IStepDispatcher::waitForSyncPoint() +// ---------------------------------------------------------------------------- +void waitForSyncPoint ( void ) +{ + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"waitForSyncPoint()" ); + IStepDispatcher::getTheInstance().waitForSyncPoint(); - if ( l_quitflag == true ) - { - // shutdown command issued, break out of loop - - /*@ errorlog tag - * @errortype ERRL_SEV_INFORMATIONAL - * @moduleid ISTEP_INITSVC_MOD_ID - * @reasoncode ISTEP_SINGLESTEP_SHUTDOWN - * @userdata1 0 - * @userdata2 0 - * - * @devdesc hb-istep terminated - * - */ - l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - INITSERVICE::ISTEP_INITSVC_MOD_ID, - INITSERVICE::ISTEP_SINGLESTEP_SHUTDOWN, - 0, - 0 ); - break; - } + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"waitForSyncPoint()" ); +} + +void IStepDispatcher::waitForSyncPoint ( void ) +{ + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::waitForSyncPoint()" ); - } // end while + if( getIStepMode() || + spLess() ) + { + TRACFCOMP( g_trac_initsvc, + INFO_MRK"Istep mode or SPless, no wait for sync point allowed" ); + return; + } - // fell out of loop, return with rtaskRetErrl set - mutex_unlock(&iv_poll_mutex); - io_rtaskRetErrl = l_errl; + // Lock here to hold off all additional callers + TRACFCOMP( g_trac_initsvc, + INFO_MRK"Wait for sync point" ); + mutex_lock( &iv_syncMutex ); + while( !iv_sync ) + { + sync_cond_wait( &iv_syncHit, + &iv_syncMutex ); + } + iv_sync = false; + mutex_unlock( &iv_syncMutex ); + TRACDCOMP( g_trac_initsvc, + INFO_MRK"Sync point hit." ); + + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::waitForSyncPoint()" ); } +// ---------------------------------------------------------------------------- +// sendSyncPoint() +// IStepDispatcher::sendSyncPoint() +// ---------------------------------------------------------------------------- +errlHndl_t sendSyncPoint ( void ) +{ + TRACFCOMP( g_trac_initsvc, + ENTER_MRK"sendSyncPoint()" ); + + return IStepDispatcher::getTheInstance().sendSyncPoint(); +} -errlHndl_t IStepDispatcher::processSingleIStepCmd( - const uint32_t i_IStep, - const uint32_t i_Substep, - uint32_t &o_rSts ) +errlHndl_t IStepDispatcher::sendSyncPoint ( void ) { - errlHndl_t l_errl = NULL; - const TaskInfo *l_pistep = NULL; + errlHndl_t err = NULL; - o_rSts = 0; + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::sendSyncPoint()" ); - // look up istep+substep - l_pistep = IStepDispatcher::getTheInstance().findTaskInfo( - i_IStep, - i_Substep ); - do + if( getIStepMode() ) { - if ( l_pistep == NULL ) - { - // invalid istep, return error - TRACDCOMP( g_trac_initsvc, - "processSingleIStepCmd: Invalid IStep %d.%d\n", - i_IStep, - i_Substep ); + TRACFCOMP( g_trac_initsvc, + INFO_MRK"Istep mode, no sending sync point allowed" ); + return err; + } - o_rSts = SPLESS_INVALID_COMMAND; - break; - } + msg_t * myMsg = msg_allocate(); + myMsg->type = SYNC_POINT_REACHED; + uint64_t tmpVal = iv_curIStep; + tmpVal = tmpVal << 32; + tmpVal |= iv_curSubStep; + myMsg->data[0] = tmpVal; + myMsg->data[1] = 0x0; + myMsg->extra_data = NULL; + err = sendMboxMsg( ISTEP_ASYNC, + myMsg ); + + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::sendSyncPoint()" ); - /** - * @todo placeholder - set progress code before starting - * This will not be finalized until the progress code driver - * is designed and implemented. - */ - uint64_t l_progresscode = 0; - InitService::getTheInstance().setProgressCode( l_progresscode ); + return err; +} +// ---------------------------------------------------------------------------- +// sendIstepCompleteMsg() +// IStepDispatcher::sendIstepCompleteMsg() +// ---------------------------------------------------------------------------- +errlHndl_t sendIstepCompleteMsg ( void ) +{ + TRACFCOMP( g_trac_initsvc, + ENTER_MRK"sendIstepCompleteMsg()" ); - TRACFCOMP( g_trac_initsvc, - "processSingleIStepCmd: Run IStep=%d.%d %s", - i_IStep, - i_Substep, - l_pistep->taskname ); + return IStepDispatcher::getTheInstance().sendIstepCompleteMsg(); +} + +errlHndl_t IStepDispatcher::sendIstepCompleteMsg ( void ) +{ + errlHndl_t err = NULL; - // launch the istep - l_errl = InitService::getTheInstance().executeFn( - l_pistep, - NULL ); + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::sendIstepCompleteMsg()" ); - if ( l_errl ) + do + { + // We just need to respond back to the outstanding iv_Msg we should + // already have + if( iv_Msg ) + { + iv_Msg->data[0] = 0x0; + msg_respond( iv_msgQ, + iv_Msg ); + iv_Msg = NULL; + } + else { - // @todo post informational errl here? + TRACFCOMP( g_trac_initsvc, + ERR_MRK"Request to send Istep complete, but no outstanding " + "message from Fsp found!!" ); + + /*@ + * @errortype + * @reasoncode NO_MSG_PRESENT + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid ISTEP_INITSVC_MOD_ID + * @userdata1 Current Istep + * @userdata2 Current SubStep + * @devdesc Request to send Istep Complete msg to Fsp, but no + * outstanding message from Fsp found. + */ + err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, + ISTEP_INITSVC_MOD_ID, + NO_MSG_PRESENT, + iv_curIStep, + iv_curSubStep ); break; } - } while(0); + } while( 0 ); + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::sendIstepCompleteMsg()" ); - return l_errl; + return err; } - -const TaskInfo *IStepDispatcher::findTaskInfo( - const uint32_t i_IStep, - const uint32_t i_SubStep ) const +// ---------------------------------------------------------------------------- +// IStepDispatcher::sendMboxMsg() +// ---------------------------------------------------------------------------- +errlHndl_t IStepDispatcher::sendMboxMsg ( IStepSync_t i_sendSync, + msg_t * i_msg ) { - // default return is NULL - const TaskInfo *l_pistep = NULL; - /** - * @todo - * everything calling this should feed into the "real" istep/substep - * numbers ( starting at 1 ) - this routine should translate to index into - * the isteplists ( starting at 0 ) - * - * int32_t l_istepIndex = i_IStep-1; - * int32_t l_substepIndex = i_SubStep-1; - * - * assert( l_istepIndex >= 0 ); - * assert( l_substepIndex >= 0 ); - */ - - // apply filters + errlHndl_t err = NULL; + + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::sendMboxMsg()" ); + do { - // Sanity check / dummy IStep - if ( g_isteps[i_IStep].pti == NULL) + if( ISTEP_SYNC == i_sendSync ) { - TRACDCOMP( g_trac_initsvc, - "g_isteps[%d].pti == NULL (substep=%d)", - i_IStep, - i_SubStep ); - break; + err = MBOX::sendrecv( HWSVRQ, + i_msg ); } - - // check input range - IStep - if ( i_IStep >= INITSERVICE::MaxISteps ) + else if( ISTEP_ASYNC == i_sendSync ) { - TRACDCOMP( g_trac_initsvc, - "IStep %d out of range. (substep=%d) ", - i_IStep, - i_SubStep ); - break; // break out with l_pistep set to NULL + err = MBOX::send( HWSVRQ, + i_msg ); } - - // check input range - ISubStep - if ( i_SubStep >= g_isteps[i_IStep].numitems ) + else { - TRACDCOMP( g_trac_initsvc, - "IStep %d Substep %d out of range.", - i_IStep, - i_SubStep ); - break; // break out with l_pistep set to NULL + // should never get here, but if we do, just return back... + // Nothing to send. } - // check for end of list. - if ( g_isteps[i_IStep].pti[i_SubStep].taskflags.task_type - == END_TASK_LIST ) + if( err ) { - TRACDCOMP( g_trac_initsvc, - "IStep %d SubStep %d task_type==END_TASK_LIST.", - i_IStep, - i_SubStep ); break; } + } while( 0 ); - // check to see if the pointer to the function is NULL. - // This is possible if some of the substeps aren't working yet - // and are just placeholders. - if ( g_isteps[i_IStep].pti[i_SubStep].taskfn == NULL ) - { - TRACDCOMP( g_trac_initsvc, - "IStep %d SubStep %d fn ptr is NULL.", - i_IStep, - i_SubStep ); - break; - } + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::sendMboxMsg()" ); + + return err; +} - // we're good, set the istep & return it to caller - l_pistep = &( g_isteps[i_IStep].pti[i_SubStep] ); +// ---------------------------------------------------------------------------- +// IStepDispatcher::getIstepInfo() +// ---------------------------------------------------------------------------- +void IStepDispatcher::getIstepInfo ( uint8_t & o_iStep, + uint8_t & o_subStep ) +{ + mutex_lock( &iv_stepMutex ); + o_iStep = iv_curIStep; + o_subStep = iv_curSubStep; + mutex_unlock( &iv_stepMutex ); +} - } while ( 0 ); - return l_pistep; +// ---------------------------------------------------------------------------- +// IStepDispatcher::setIstepInfo() +// ---------------------------------------------------------------------------- +void IStepDispatcher::setIstepInfo ( uint16_t i_type ) +{ + mutex_lock( &iv_stepMutex ); + iv_curIStep = ((i_type & 0xFF00) >> 8); + iv_curSubStep = (i_type & 0xFF); + mutex_unlock( &iv_stepMutex ); } -bool IStepDispatcher::getIStepMode( ) const +// ---------------------------------------------------------------------------- +// IStepDispatcher::handleSyncPointReachedMsg() +// ---------------------------------------------------------------------------- +void IStepDispatcher::handleSyncPointReachedMsg ( void ) { - using namespace TARGETING; - Target* l_pTopLevel = NULL; - bool l_istepmodeflag = false; - TargetService& l_targetService = targetService(); + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::handleSyncPointReachedMsg()" ); - (void) l_targetService.getTopLevelTarget(l_pTopLevel); - if (l_pTopLevel == NULL) - { - TRACFCOMP( g_trac_initsvc, "Top level handle was NULL" ); - l_istepmodeflag = false; - } - else + do { - l_istepmodeflag = l_pTopLevel->getAttr<ATTR_ISTEP_MODE> (); - // printk( "IStep Mode flag = 0x%x\n", l_istepmodeflag ); - } + // Indicate we hit a sync point, and get anyone waiting moving. + mutex_lock( &iv_syncMutex ); + iv_sync = true; + sync_cond_signal( &iv_syncHit ); + mutex_unlock( &iv_syncMutex ); + } while( 0 ); - return l_istepmodeflag; + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::handleSyncPointReachedMsg()" ); } -bool IStepDispatcher::getCanContinueProcedure( const TaskInfo &i_failingIStep, - errlHndl_t &i_failingError, - TaskInfo &io_nextIstep - ) const +// ---------------------------------------------------------------------------- +// IStepDispatcher::handleMoreWorkNeededMsg() +// ---------------------------------------------------------------------------- +void IStepDispatcher::handleMoreWorkNeededMsg ( void ) { + TRACDCOMP( g_trac_initsvc, + ENTER_MRK"IStepDispatcher::handleMoreWorkNeededMsg()" ); - return false; -} + // Clear out current Istep/substep values. Since worker thread told us + // its done, nothing is running right now. + iv_curIStep = 0x0; + iv_curSubStep = 0x0; + // Only something to do if we've gotten a request from Fsp or SPLESS + if( iv_Msg ) + { + // Send response back to caller? + if( !msg_is_async( iv_Msg ) ) + { + // TODO - Is data[0] status?? Not in HwSvr Doc. + iv_Msg->data[0] = 0x0; + // Send a possible errlog back to Fsp. + iv_Msg->extra_data = iv_workerMsg->extra_data; + msg_respond( iv_msgQ, + iv_Msg ); + iv_Msg = NULL; + } + } + else + { + // We should never be here... Worker message should only be doing + // something if it got a request from outside. + } -IStepDispatcher& IStepDispatcher::getTheInstance() -{ - return Singleton<IStepDispatcher>::instance(); + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::handleMoreWorkNeededMsg()" ); } -void IStepDispatcher::handleBreakPoint( uint32_t i_info ) +// ---------------------------------------------------------------------------- +// iStepBreakPoint() +// ---------------------------------------------------------------------------- +void iStepBreakPoint ( uint32_t i_info ) { - msg_t *l_pBpMsg = msg_allocate(); - errlHndl_t l_errl = NULL; - - // need to be the only poller - mutex_lock(&iv_poll_mutex); - + TRACFCOMP( g_trac_initsvc, + ENTER_MRK"handleBreakpointMsg()" ); + IStepDispatcher::getTheInstance().handleBreakpoint( i_info ); +} - l_pBpMsg->type = BREAKPOINT_TYPE; - l_pBpMsg->data[0] = - ( static_cast<uint64_t>( i_info ) << 32 ) | - static_cast<uint64_t>( 0 ) ; - l_pBpMsg->data[1] = 0; - l_pBpMsg->extra_data = NULL; - // send new message to FSP +// ---------------------------------------------------------------------------- +// IStepDispatcher::handleBreakpoint() +// ---------------------------------------------------------------------------- +void IStepDispatcher::handleBreakpoint ( uint32_t i_info ) +{ + // Throttle the breakpoints by locking here. + mutex_lock( &iv_bkPtMutex ); + errlHndl_t err = NULL; TRACDCOMP( g_trac_initsvc, - "handleBreakPoint: FSP: send sts type 0x%x, msg 0x%x.%x", - l_pBpMsg->type, - static_cast<uint32_t>( l_pBpMsg->data[0] >> 32 ), - static_cast<uint32_t>( l_pBpMsg->data[0] & 0xffffffff ) ); - - // send status to FSP - l_errl = MBOX::sendrecv( MBOX::HB_ISTEP_MSGQ, l_pBpMsg ); - if ( l_errl ) + ENTER_MRK"IStepDispatcher::handleBreakpointMsg()" ); + + // Send Breakpoint msg to Fsp. + msg_t * myMsg = msg_allocate(); + myMsg->type = BREAKPOINT; + uint64_t tmpVal = 0x0; + tmpVal = tmpVal & i_info; + myMsg->data[0] = (tmpVal << 32); // TODO - Is this really a Fsp requirement? + myMsg->data[1] = 0x0; + myMsg->extra_data = NULL; + + if( !(SPLESS::SPLessAttached()) ) { - TRACFCOMP( g_trac_initsvc, - "handleBreakPoint: ERROR on MBOX sendrecv" ); - errlCommit( l_errl, INITSVC_COMP_ID ); - - // If sendrecv fails for some reason, error will be logged and - // breakpoint will resume anyway. + // FSP Attached + // Wait for Fsp to respond. + err = sendMboxMsg( ISTEP_SYNC, + myMsg ); + // TODO - Do we care what they sent back? Not sure... HwSvr + // has no documentation on this... + if( err ) + { + errlCommit( err, + INITSVC_COMP_ID ); + } + } + else + { + // SPLESS + msg_respond( iv_msgQ, + myMsg ); + + // Now wait for spless code to respond that we're done with the + // breakpoint + msg_t * rspMsg; + rspMsg = msg_wait( iv_msgQ ); } - // unblocked + msg_free( myMsg ); TRACDCOMP( g_trac_initsvc, - "handleBreakPoint exit: receive msg type 0x%x, msg 0x%x.%x", - l_pBpMsg->type, - static_cast<uint32_t>( l_pBpMsg->data[0] >> 32 ), - static_cast<uint32_t>( l_pBpMsg->data[0] & 0xffffffff ) ); - - msg_free( l_pBpMsg ); - mutex_unlock(&iv_poll_mutex); + EXIT_MRK"IStepDispatcher::handleBreakpointMsg()" ); + mutex_unlock( &iv_bkPtMutex ); } -void IStepDispatcher::handleSPlessBreakPoint( uint32_t i_info ) +// ---------------------------------------------------------------------------- +// IStepDispatcher::handleIStepRequestMsg() +// ---------------------------------------------------------------------------- +void IStepDispatcher::handleIStepRequestMsg ( void ) { - - TRACDCOMP( g_trac_initsvc, - "handleBreakPoint: hijacking message Q" ); - - // need to be the only poller - mutex_lock(&iv_poll_mutex); - - - iv_pMsg->type = BREAKPOINT_TYPE; - iv_pMsg->data[0] = - ( static_cast<uint64_t>( i_info ) << 32 ) | - static_cast<uint64_t>( 0 ) ; - iv_pMsg->data[1] = 0; - iv_pMsg->extra_data = NULL; - TRACDCOMP( g_trac_initsvc, - "handleBreakPoint: send sts msg type 0x%x, msg 0x%x.%x", - iv_pMsg->type, - static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ), - static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) ); + ENTER_MRK"IStepDispatcher::handleIStepRequestMsg()" ); - // respond to SPtask - msg_respond( iv_msgQ, iv_pMsg ); - - // Poll for cmd to resume - while( 1 ) + // Only something to do, if the worker thread is ready for work + if( iv_workerMsg ) { + // Set new istep/substep info + uint16_t stepInfo = ((iv_Msg->data[0] & 0x000000FF00000000) >> 24); + stepInfo = (stepInfo | (iv_Msg->data[0] & 0xFF) ); + setIstepInfo( stepInfo ); - // wait for message from SPtask - iv_pMsg = msg_wait( iv_msgQ ); - - // unblocked + TRACFCOMP( g_trac_initsvc, + INFO_MRK"Istep req: 0x%04x", + stepInfo ); - if ( msg_is_async( iv_pMsg ) ) - { - // should not receive async messages here, drop it, post errorlog - // and go back to waiting. - TRACFCOMP( g_trac_initsvc, - "handleBreakPoint: ERROR async msg type 0x%x, msg 0x%x.%x", - iv_pMsg->type, - static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ), - static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) ); - - /*@ errorlog tag - * @errortype ERRL_SEV_INFORMATIONAL - * @moduleid ISTEP_INITSVC_MOD_ID - * @reasoncode ISTEP_BKPOINT_ASYNC_RCVD - * @userdata1 type of packet - * @userdata2 first data word - * - * @devdesc IStepDisp handleSPlessBreakPoint was expecting a - * synchronous message and received an asynchonous - * message. - * - */ - errlHndl_t l_errlAsync = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - INITSERVICE::ISTEP_INITSVC_MOD_ID, - INITSERVICE::ISTEP_BKPOINT_ASYNC_RCVD, - iv_pMsg->type, - iv_pMsg->data[0] ); - - errlCommit( l_errlAsync, INITSVC_COMP_ID ); - - msg_free( iv_pMsg ); - iv_pMsg = NULL; - continue; - } + // Set step/substep in data[0]; + iv_workerMsg->data[0] = stepInfo; + msg_respond( iv_msgQ, + iv_workerMsg ); - TRACDCOMP( g_trac_initsvc, - "handleBreakPoint: receive msg type 0x%x, msg 0x%x.%x", - iv_pMsg->type, - static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ), - static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) ); + iv_workerMsg = NULL; + } - // only expect this command - if ( iv_pMsg->type == BREAKPOINT_TYPE ) - { - // correct response, return to istep - break; - } - else - { - // all other commands are not valid here, return the same status - iv_pMsg->type = BREAKPOINT_TYPE; - iv_pMsg->data[0] = - ( static_cast<uint64_t>( i_info ) << 32 ) | - static_cast<uint64_t>( 0 ) ; - iv_pMsg->data[1] = 0; - iv_pMsg->extra_data = NULL; - - TRACDCOMP( g_trac_initsvc, - "handleBreakPoint: send sts msg type 0x%x, msg 0x%x.%x", - iv_pMsg->type, - static_cast<uint32_t>( iv_pMsg->data[0] >> 32 ), - static_cast<uint32_t>( iv_pMsg->data[0] & 0xffffffff ) ); - - // reply back FSP/console - msg_respond( iv_msgQ, iv_pMsg ); - } // end else - } // end while - - mutex_unlock(&iv_poll_mutex); + TRACDCOMP( g_trac_initsvc, + EXIT_MRK"IStepDispatcher::handleIStepRequestMsg()" ); } -// route to SPless or FSP depending on what's attached -void iStepBreakPoint(uint32_t i_info) + +// ---------------------------------------------------------------------------- +// IStepDispatcher::getIStepMode() +// ---------------------------------------------------------------------------- +bool IStepDispatcher::getIStepMode( ) const { - if ( SPLESS::SPLessAttached() ) + using namespace TARGETING; + Target* l_pTopLevel = NULL; + bool l_istepmodeflag = false; + TargetService& l_targetService = targetService(); + + (void)l_targetService.getTopLevelTarget( l_pTopLevel ); + if( l_pTopLevel == NULL ) { - IStepDispatcher::getTheInstance().handleSPlessBreakPoint( i_info ); + TRACFCOMP( g_trac_initsvc, + "Top level handle was NULL" ); + l_istepmodeflag = false; } else { - IStepDispatcher::getTheInstance().handleBreakPoint( i_info ); + l_istepmodeflag = l_pTopLevel->getAttr<ATTR_ISTEP_MODE> (); } -} - -void getIstepMsgQ ( msg_q_t & o_msgQ ) -{ - Singleton<IStepDispatcher>::instance().getIstepMsgQ( o_msgQ ); -} -void IStepDispatcher::getIstepMsgQ ( msg_q_t & o_msgQ ) -{ - o_msgQ = iv_msgQ; -} - -void getIstepMsg ( msg_t* & o_msg ) -{ - Singleton<IStepDispatcher>::instance().getIstepMsg( o_msg ); -} -void IStepDispatcher::getIstepMsg ( msg_t* & o_msg ) -{ - o_msg = iv_pMsg; + return l_istepmodeflag; } -IStepDispatcher::IStepDispatcher() -: iv_sts() +// ---------------------------------------------------------------------------- +// IStepDispatcher::spLess() +// ---------------------------------------------------------------------------- +bool IStepDispatcher::spLess ( void ) { - SPLESS::initIStepMode(); - mutex_init(&iv_poll_mutex); - - // init mailbox / message Q. - iv_msgQ = msg_q_create(); + bool spless = true; + TARGETING::Target * sys = NULL; + TARGETING::targetService().getTopLevelTarget( sys ); + TARGETING::SpFunctions spfuncs; + if( sys && + sys->tryGetAttr<TARGETING::ATTR_SP_FUNCTIONS>(spfuncs) && + spfuncs.mailboxEnabled ) + { + spless = false; + } + return spless; } -IStepDispatcher::~IStepDispatcher() -{ } - - } // namespace diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H index b887a8829..1025704a5 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.H +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H @@ -42,23 +42,16 @@ /******************************************************************************/ #include <stdint.h> #include <util/singleton.H> - #include <sys/msg.h> -#include <mbox/mboxif.H> // mailbox Q -#include <mbox/mbox_queues.H> // HB_ISTEP_MSGQ - +#include <sys/sync.h> #include <errl/errlentry.H> #include <initservice/taskargs.H> #include <initservice/initsvcreasoncodes.H> #include <initservice/initsvcstructs.H> - #include "../baseinitsvc/initservice.H" - #include "splesscommon.H" - #include "istep_mbox_msgs.H" - namespace INITSERVICE { @@ -78,9 +71,18 @@ namespace INITSERVICE * param[in,out] - pointer to any args * * @return nothing - * */ -void spTask( void *io_pArgs ); +void spTask ( void *io_pArgs ); + +/** + * @brief enums for whether the messages IStepdispatcher sends are synchronus + * or asynchronous. + */ +enum IStepSync_t +{ + ISTEP_SYNC, + ISTEP_ASYNC, +}; /******************************************************************************/ @@ -105,53 +107,71 @@ public: */ static IStepDispatcher& getTheInstance(); - /** - * @brief Provide an entry function into the class, called from _start() + * @brief This function is what is called to startup the main istep + * dispatcher thread. * - * @param[in] io_rtaskRetErrl - ref to errlHndl_t passed back to _start(). + * @param[in/out] io_rtaskRetErrl - Errorlog pointer to be returned for + * any errors that might have been encountered. * - * @return nothing + * @return NONE. */ - void init( errlHndl_t &io_rtaskRetErrl ); + void init ( errlHndl_t &io_rtaskRetErrl ); + /** + * @brief This function is used to send a sync point message from Hostboot + * to the Fsp. + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to the + * error log. + */ + errlHndl_t sendSyncPoint ( void ); /** - * @brief Handle an istep break point to FSP - * @param[in] i_info, @TODO - location/info + * @brief This function is used for calling code to be held off waiting + * for a syncpoint message from an external source. Anyone calling + * this will be blocked on this call until ANY sync point message is + * received. Once received, each caller in succession will be + * released. * - * @note blocks until an outside istep cmd to resume is received. + * @return NONE. */ - void handleBreakPoint( uint32_t info); + void waitForSyncPoint ( void ); /** - * @brief Handle an istep break point from SPless - * @param[in] i_info, @TODO - location/info - * @pre iv_sts contains current istep status + seqnum or - * 0 if not in step mode - * @note blocks until an outside istep cmd to resume is recieved. + * @brief This function when called will send a Istep complete mailbox + * message to the Fsp to indicate that the current Istep is complete. + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to the + * error log. */ - void handleSPlessBreakPoint( uint32_t info); + errlHndl_t sendIstepCompleteMsg ( void ); /** - * @brief This function returns the MBOX Message Queue used by the istep - * dispatcher. + * @brief This function will handle all breakpoint requests from the + * running istep code. The running istep code would be initiated via + * the istep dispatcher worker thread. Thus, holding off the worker + * thread. * - * @param[out] o_msgQ - The message queue. + * @param[in] i_info - TODO - this needs to be decided yet. But it seems + * at least preliminarily that this will contain a unique breakpoint + * numbering value. * * @return NONE. */ - void getIstepMsgQ ( msg_q_t & o_msgQ ); + void handleBreakpoint ( uint32_t i_info ); /** - * @brief This function returns the current MBOX Message used by the istep - * dispatcher. + * @brief This function will return the current istep and substep. + * + * @param[out] o_iStep - The current Istep value. * - * @param[out] o_msg - The message. + * @param[out] o_subStep - The current SubStep value. * * @return NONE. */ - void getIstepMsg ( msg_t* & o_msg ); + void getIstepInfo ( uint8_t & o_iStep, + uint8_t & o_subStep ); protected: @@ -182,104 +202,93 @@ private: * @retval false if IStep Mode is "OFF" * true if IStep Mode is "ON" */ - bool getIStepMode( ) const; + bool getIStepMode( ) const; + /** + * @brief This function will start at istep 0, substep 0, and cycle + * through all possible isteps, returning when complete, or an error + * is hit. + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to an + * error log. + */ + errlHndl_t executeAllISteps ( void ); /** - * @brief Find a TaskInfo struct in the global istep list(s), - * addressed by { IStep, SubStep } + * @brief This function is the main handler loop for the Istep Dispatcher. + * it receives all messages from outside sources and initiates the + * proper action and response (if required). * - * @param[in] i_IStep - IStepNumber - * @param[in] i_SubStep - SubStepNumber + * @return errlHndl_t - NULL if successful, otherwise a pointer to an + * error log. + */ + errlHndl_t msgHndlr ( void ); + + /** + * @brief This function is used to send mailbox messages to the Fsp. * - * @return pointer to a TaskInfo struct - * @retval pointer to a TaskInfo struct, or NULL + * @param[in] i_sendSync - The sync type of message to send. Whether + * synchronous or asynchronous. * + * @param[in] i_msg - The message to send to the Fsp. + * + * @return errlHndl_t - NULL if successful, otherwise a pointer to an + * error log. */ - const TaskInfo *findTaskInfo( - const uint32_t i_IStep, - const uint32_t i_SubStep ) const; - - /** - * @brief runAllISteps - * - * Run all available ISteps sequentially. - * If an IStep gets an error, report it and stop. - * Otherwise, return. - * - * @param[in,out] - ref to an errlHndl_t that can be passed back to - * ExtInitSvc . - * - * @return none - */ - void runAllISteps( errlHndl_t &io_rtaskRetErrl ) ; - - - /** - * @brief singleStepISteps - * - * Go into a polling loop, waiting for Istep commands from - * the FSP or SPTask. - * - * @param[in,out] - ref to an errlHndl_t that can be passed back to - * ExtInitSvc . - * @return none - */ - void singleStepISteps( errlHndl_t &io_rtaskRetErrl ) ; + errlHndl_t sendMboxMsg ( IStepSync_t i_sendSync, + msg_t * i_msg ); + /** + * @brief This function is used for all of the Syncpoint message handling. + * + * @return NONE. + */ + void handleSyncPointReachedMsg ( void ); /** - * @brief getCanContinueProcedure - * If an IStep fails, this routine will fetch the recovery procedure - * This is only used in "normal" mode, it will not be used when IStep Mode - * is ON (i.e. it will not be used when single-stepping). + * @brief This function is used to handle the message from the worker + * thread requesting more work. * - * @param[in] i_failingIStep - ref to IStepInfo struct for failing - * Istep - * @param[in] i_failingError - ref to errorlog for the failure - * @param[in,out] io_nextIStep - ref to TaskInfo struct for next - * IStep to run. struct will be filled - * out with info on the next IStep to - * run. + * @return NONE. + */ + void handleMoreWorkNeededMsg ( void ); + + /** + * @brief This function is used to handle the single Istep requests from + * outside sources. + * + * @return NONE. + */ + void handleIStepRequestMsg ( void ); + + /** + * @brief This function is used to set the current Istep and Substep + * values for what is currently running. * - * @return bool - * @retval false if there is no Can-Continue procedure, - * true otherwise + * @return NONE. + */ + void setIstepInfo ( uint16_t i_type ); + + /** + * @brief This function will return whether or not we are SPless * - * @todo 2011-08-22 currently the defs for this procedure are pretty - * vague - requirements for Can-Continue behaviour have not been - * defined yet. + * @return bool - whether we are SPLESS. */ - bool getCanContinueProcedure( - const TaskInfo &i_failingIStep, - errlHndl_t &i_failingError, - TaskInfo &io_nextIStep ) const; - - - /** - * @brief Command 0: Run the requested IStep/SubStep - * - * param[in] i_IStep - IStep number - * param[in] i_Substep - Substep number - * param[out] o_rSts - lookup status - returns Invalid if the - * IStep, Substep doesn't exist - * - * @post iv_sts set to current istep status - * - * @return errlHndl_t - */ - errlHndl_t processSingleIStepCmd( - const uint32_t i_IStep, - const uint32_t i_Substep, - uint32_t &o_rSts ); + bool spLess ( void ); // ----- internal vars ----------------------------- - mutex_t iv_poll_mutex; //!< protect who's polling istep cmds - SPLESS::SPLessSts iv_sts; //!< Current status of istep mode - msg_q_t iv_msgQ; //!< Message Q to FSP & SPTask. - msg_t *iv_pMsg; //!< ptr to msg from FSP or user console + mutex_t iv_bkPtMutex; + mutex_t iv_syncMutex; + mutex_t iv_stepMutex; + sync_cond_t iv_syncHit; + uint8_t iv_curIStep; + uint8_t iv_curSubStep; + bool iv_sync; + msg_q_t iv_msgQ; + msg_t* iv_workerMsg; // More work Needed Msg from Worker + msg_t* iv_Msg; // All other Msgs that need to be saved }; // class IStepDispatcher diff --git a/src/usr/initservice/istepdispatcher/makefile b/src/usr/initservice/istepdispatcher/makefile index eaae9b9ea..04a6da054 100644 --- a/src/usr/initservice/istepdispatcher/makefile +++ b/src/usr/initservice/istepdispatcher/makefile @@ -1,11 +1,11 @@ -# IBM_PROLOG_BEGIN_TAG +# IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # $Source: src/usr/initservice/istepdispatcher/makefile $ # # IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2011 - 2012 +# COPYRIGHT International Business Machines Corp. 2011-2012 # # p1 # @@ -24,7 +24,7 @@ ROOTPATH = ../../../.. MODULE = istepdisp OBJS = istepdispatcher.o initsvcudistep.o \ - sptask.o splesscommon.o + sptask.o splesscommon.o istepWorker.o ## SUBDIRS = test.d diff --git a/src/usr/initservice/istepdispatcher/splesscommon.C b/src/usr/initservice/istepdispatcher/splesscommon.C index fdba904de..809915014 100644 --- a/src/usr/initservice/istepdispatcher/splesscommon.C +++ b/src/usr/initservice/istepdispatcher/splesscommon.C @@ -119,6 +119,14 @@ void initIStepMode( ) // $$ save l_readData = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_CONFIG ); l_readData = g_SPLess_IStepMode_Reg; + // Get the Thread 5 scratch reg + uint64_t t5ScratchVal = mmio_scratch_read( MMIO_SCRATCH_ISTEP_MODE ); + TRACFCOMP( INITSERVICE::g_trac_initsvc, + INFO_MRK"Thread 5 scratch reg val: 0x%08x", + t5ScratchVal ); + // Only need 1 bit. + t5ScratchVal = t5ScratchVal & 0x1; + #ifdef SPLESS_DEBUG printk( "IStepMode Reg = 0x%p, 0x%lx\n", &g_SPLess_IStepMode_Reg, l_readData ); printk( "Status Reg = 0x%p\n", &g_SPLess_Status_Reg ); @@ -130,8 +138,8 @@ void initIStepMode( ) // check for IStep Mode signature(s) if ( ( l_readData == ISTEP_MODE_SPLESS_SIGNATURE ) - || ( l_readData == ISTEP_MODE_FSP_SIGNATURE ) - ) + || ( l_readData == ISTEP_MODE_FSP_SIGNATURE ) || + ( 0x1 == t5ScratchVal ) ) { l_pTopLevel->setAttr<ATTR_ISTEP_MODE> (true ); diff --git a/src/usr/initservice/istepdispatcher/splesscommon.H b/src/usr/initservice/istepdispatcher/splesscommon.H index 3dd0f9030..dc3fb30b0 100644 --- a/src/usr/initservice/istepdispatcher/splesscommon.H +++ b/src/usr/initservice/istepdispatcher/splesscommon.H @@ -5,7 +5,7 @@ * * IBM CONFIDENTIAL * - * COPYRIGHT International Business Machines Corp. 2011 - 2012 + * COPYRIGHT International Business Machines Corp. 2011-2012 * * p1 * @@ -100,11 +100,11 @@ enum { * @note SPLess commands, and masks for the status. * */ -const uint8_t SPLESS_SINGLE_ISTEP_CMD = 0x00; -const uint8_t SPLESS_RESUME_ISTEP_CMD = 0x01; -const uint8_t SPLESS_CLEAR_TRACE_CMD = 0x02; -const uint8_t SPLESS_SHUTDOWN_CMD = 0x03; -const uint64_t SPLESS_SINGLE_STEP_STS_MASK = 0x00000000ffffffff; +//const uint8_t SPLESS_SINGLE_ISTEP_CMD = 0x00; +//const uint8_t SPLESS_RESUME_ISTEP_CMD = 0x01; +//const uint8_t SPLESS_CLEAR_TRACE_CMD = 0x02; +//const uint8_t SPLESS_SHUTDOWN_CMD = 0x03; +//const uint64_t SPLESS_SINGLE_STEP_STS_MASK = 0x00000000ffffffff; /** * @brief init ISTEP_MODE attribute diff --git a/src/usr/initservice/istepdispatcher/sptask.C b/src/usr/initservice/istepdispatcher/sptask.C index 842a259be..417754412 100644 --- a/src/usr/initservice/istepdispatcher/sptask.C +++ b/src/usr/initservice/istepdispatcher/sptask.C @@ -79,46 +79,6 @@ const uint64_t SINGLESTEP_PAUSE_S = 0; const uint64_t SINGLESTEP_PAUSE_NS = 10000000; /** - * @brief Translate beween commands on SPless user console and FSP commands - * - * @param[in] - command from SPLess user console - * - * @return FSP command - * - */ -uint32_t SPLessToFSP( const uint8_t i_cmd ) -{ - uint32_t l_FSPCmd = 0; - - switch( i_cmd ) - { - - case SPLESS_SINGLE_ISTEP_CMD: - l_FSPCmd = SINGLE_STEP_TYPE; - break; - case SPLESS_RESUME_ISTEP_CMD: - l_FSPCmd = BREAKPOINT_TYPE; - break; - case SPLESS_CLEAR_TRACE_CMD: - l_FSPCmd = CLEAR_TRACE_TYPE; - break; - case SPLESS_SHUTDOWN_CMD: - l_FSPCmd = SHUTDOWN_TYPE; - break; - default: - TRACFCOMP( g_trac_initsvc, - "spTask ERROR: unknown cmd %d", - i_cmd ); - // should never happen... - assert( 0 ); - } - - return l_FSPCmd; -} - - - -/** * @brief userConsoleComm * * Communicate with User Console on VPO or Simics. @@ -198,10 +158,10 @@ void userConsoleComm( void * io_msgQ ) writeSts( l_sts ); // pass the command on to IstepDisp, block until reply - l_pCurrentMsg->type = SPLessToFSP( l_cmd.hdr.cmdnum ); - l_pCurrentMsg->data[0] = - ( static_cast<uint64_t>( l_cmd.istep ) << 32 ) | - static_cast<uint64_t>( l_cmd.substep ) ; + l_pCurrentMsg->type = 0x0; + l_pCurrentMsg->data[0] = + ( ( static_cast<uint64_t>(l_cmd.istep & 0xFF) << 32) | + ( static_cast<uint64_t>(l_cmd.substep & 0xFF ) ) ); l_pCurrentMsg->data[1] = 0; l_pCurrentMsg->extra_data = NULL; @@ -233,7 +193,7 @@ void userConsoleComm( void * io_msgQ ) static_cast<uint32_t>( l_pCurrentMsg->data[0] >> 32 ), static_cast<uint32_t>( l_pCurrentMsg->data[0] & 0x0ffffffff ) ); - if ( l_pCurrentMsg->type == BREAKPOINT_TYPE ) + if ( l_pCurrentMsg->type == BREAKPOINT ) { l_sts.hdr.status = SPLESS_AT_BREAK_POINT; } @@ -258,6 +218,9 @@ void userConsoleComm( void * io_msgQ ) // if shutdown issued, end this task if ( l_cmd.hdr.cmdnum == SPLESS_SHUTDOWN_CMD ) { + TRACFCOMP( g_trac_initsvc, + "sptask: shutdown received" ); + l_quitflag = true; } @@ -274,9 +237,11 @@ void userConsoleComm( void * io_msgQ ) writeCmd( l_cmd ); } // endif gobit - if ( l_quitflag == true ) { + TRACFCOMP( g_trac_initsvc, + "sptask: got quitflag" ); + // shutdown command issued, break out of loop break; } @@ -300,6 +265,9 @@ void userConsoleComm( void * io_msgQ ) } } // endwhile + TRACFCOMP( g_trac_initsvc, + "sptask: Uh-oh, we just exited... what went wrong?" ); + // @note // Fell out of loop, clear sts reg and turn off readybit // disable the ready bit so the user knows. |