From dd7a32e1a27ecac1c8decaa958cbca7ef139c6bc Mon Sep 17 00:00:00 2001 From: Mark Wenning Date: Tue, 20 Mar 2012 11:37:13 -0500 Subject: Refactor InitService Finish join() conversion, remove TaskArgs Cleanup Initservice Cleanup ExtInitService Cleanup IStepDisp Add SPLess Halt & Shutdown command. Implements code for Tasks 35508, 3855, 36929 and 38870 . RTC: 38196 Change-Id: I554655412b529ef6cd143fea361a39bd584d18b5 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/794 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III --- src/usr/initservice/baseinitsvc/initservice.C | 495 +++++++++++++++------ src/usr/initservice/baseinitsvc/initservice.H | 53 +-- .../initservice/baseinitsvc/initservicetaskentry.C | 67 --- src/usr/initservice/baseinitsvc/initsvctasks.H | 17 +- src/usr/initservice/baseinitsvc/makefile | 3 +- src/usr/initservice/extinitsvc/extinitsvc.C | 312 +++++-------- src/usr/initservice/extinitsvc/extinitsvc.H | 7 +- src/usr/initservice/extinitsvc/extinitsvctasks.H | 3 +- src/usr/initservice/initsvctasktest2/makefile | 28 -- src/usr/initservice/initsvctasktest2/tasktest2.C | 85 ---- src/usr/initservice/initsvctasktest2/tasktest2.H | 103 ----- src/usr/initservice/initsvctesttask/makefile | 28 ++ src/usr/initservice/initsvctesttask/tasktest2.C | 66 +++ src/usr/initservice/initsvctesttask/tasktest2.H | 101 +++++ src/usr/initservice/initsvcunittesttask2/makefile | 28 -- .../initservice/istepdispatcher/istepdispatcher.C | 351 ++++----------- .../initservice/istepdispatcher/istepdispatcher.H | 43 +- .../initservice/istepdispatcher/splesscommand.C | 113 ----- src/usr/initservice/istepdispatcher/splesscommon.H | 9 +- src/usr/initservice/istepdispatcher/splessstatus.C | 93 ---- src/usr/initservice/makefile | 6 +- src/usr/initservice/taskargs/makefile | 28 -- src/usr/initservice/taskargs/taskargs.C | 162 ------- src/usr/initservice/test/initservicetest.H | 6 +- 24 files changed, 809 insertions(+), 1398 deletions(-) delete mode 100644 src/usr/initservice/baseinitsvc/initservicetaskentry.C delete mode 100644 src/usr/initservice/initsvctasktest2/makefile delete mode 100644 src/usr/initservice/initsvctasktest2/tasktest2.C delete mode 100644 src/usr/initservice/initsvctasktest2/tasktest2.H create mode 100644 src/usr/initservice/initsvctesttask/makefile create mode 100644 src/usr/initservice/initsvctesttask/tasktest2.C create mode 100644 src/usr/initservice/initsvctesttask/tasktest2.H delete mode 100644 src/usr/initservice/initsvcunittesttask2/makefile delete mode 100644 src/usr/initservice/istepdispatcher/splesscommand.C delete mode 100644 src/usr/initservice/istepdispatcher/splessstatus.C delete mode 100644 src/usr/initservice/taskargs/makefile delete mode 100644 src/usr/initservice/taskargs/taskargs.C (limited to 'src/usr/initservice') diff --git a/src/usr/initservice/baseinitsvc/initservice.C b/src/usr/initservice/baseinitsvc/initservice.C index 532d899d6..2187b8cb0 100644 --- a/src/usr/initservice/baseinitsvc/initservice.C +++ b/src/usr/initservice/baseinitsvc/initservice.C @@ -45,6 +45,8 @@ #include +#include // TASK_ENTRY_MACRO + #include "initservice.H" #include "initsvctasks.H" @@ -52,131 +54,369 @@ // ----- namespace SPLESS ----------------------------------------------- namespace SPLESS { - // allocate space for SPLess Command regs + // allocate space for SPLess Command regs in the base image. uint64_t g_SPLess_Command_Reg = 0; uint64_t g_SPLess_Status_Reg = 0; uint64_t g_SPLess_IStepMode_Reg = 0x123456789abcdef0; -} // ----- end namespace SPLESS --------------------------------------- +} +// ----- end namespace SPLESS --------------------------------------- + namespace INITSERVICE { trace_desc_t *g_trac_initsvc = NULL; -TRAC_INIT(&g_trac_initsvc, "INITSVC", 4096 ); +TRAC_INIT(&g_trac_initsvc, "INITSVC", 2048 ); + +/** + * @brief start() task entry procedure + * This one is "special" since we do not return anything to the kernel/vfs + */ +extern "C" +void _start(void *ptr) +{ + TRACFCOMP( g_trac_initsvc, + "Executing Initialization Service module." ); + + // initialize the base modules in Hostboot. + InitService::getTheInstance().init( ptr ); + + TRACFCOMP( g_trac_initsvc, + "return from Initialization Service module." ); + + task_end(); +} + -errlHndl_t InitService::startTask( const TaskInfo *i_ptask, - TaskArgs::TaskArgs *io_pargs ) const +errlHndl_t InitService::checkNLoadModule( const TaskInfo *i_ptask ) const { - tid_t l_tidrc = 0; - errlHndl_t l_errl = NULL; + errlHndl_t l_errl = NULL; + const char *l_modulename = NULL; + + assert(i_ptask->taskflags.task_type == START_FN ); + + do { + + // i_ptask->taskflags.task_type == STARTFN + l_modulename = VFS::module_find_name( + reinterpret_cast(i_ptask->taskfn) ); + if ( l_modulename == NULL ) + { + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid BASE_INITSVC_MOD_ID + * @reasoncode INITSVC_LOAD_MODULE_FAILED + * @userdata1 0 + * @userdata2 0 + * + * @devdesc Initialization Service failed to load a + * module needed to load a function or task. + * UserDetails will contain the name of the + * function or task. + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + INITSERVICE::BASE_INITSVC_MOD_ID, + INITSERVICE::INITSVC_LOAD_MODULE_FAILED, + 0, + 0 ); + + // error, break out of do block + break; + } + + TRACDCOMP( g_trac_initsvc, + "checkNLoadModule: found %s in module %s", + i_ptask->taskname, + ((l_modulename!=NULL)?l_modulename:"NULL???") ); + + if ( !VFS::module_is_loaded( l_modulename ) + ) + { + TRACDCOMP( g_trac_initsvc, + "loading module %s", + l_modulename ); + l_errl = VFS::module_load( l_modulename ); + if ( l_errl ) + { + // load module returned with errl set + TRACFCOMP( g_trac_initsvc, + "module_load( %s ) returned with an error.", + l_modulename ); + + // break out of do block + break; + } + } + + } while( 0 ); // end do() block + + + return l_errl; +} + + +errlHndl_t InitService::startTask( + const TaskInfo *i_ptask, + void *io_pargs ) const +{ + tid_t l_tidlnchrc = 0; + tid_t l_tidretrc = 0; + errlHndl_t l_errl = NULL; + int l_childsts = 0; + void *l_childerrl = NULL; + assert( i_ptask != NULL ); - assert( i_ptask->taskflags.task_type == START_TASK ); + // assert( i_ptask->taskflags.task_type == START_TASK ); - // Base modules have already been loaded and initialized, - // extended modules have not. - if ( i_ptask->taskflags.module_type == EXT_IMAGE ) - { - // load module and call _init() - l_errl = VFS::module_load( i_ptask->taskname ); - } + do { + // Base modules have already been loaded and initialized, + // extended modules have not. + if ( i_ptask->taskflags.module_type == EXT_IMAGE ) + { + // load module if necessary + l_errl = VFS::module_load( i_ptask->taskname ); + } + if ( l_errl ) + { + TRACFCOMP(g_trac_initsvc, + "ERROR: failed to load module for task '%s'", + i_ptask->taskname); + + // drop out of do block with errl set + break; + } - if ( ! l_errl ) - { // launch a task and wait for it. - l_tidrc = task_exec( i_ptask->taskname, io_pargs ); + l_tidlnchrc = task_exec( i_ptask->taskname, io_pargs ); + TRACDCOMP( g_trac_initsvc, + "launch task %s returned %d", + i_ptask->taskname, + l_tidlnchrc ); // process the return - kernel returns a 16-bit signed # as a // threadid/error - if ( static_cast (l_tidrc) < 0 ) + if ( static_cast (l_tidlnchrc) < 0 ) { // task failed to launch, post an errorlog and dump some trace - TRACFCOMP(g_trac_initsvc, "ERROR: starting task '%s'", - i_ptask->taskname); + TRACFCOMP(g_trac_initsvc, + "ERROR 0x%x: starting task '%s'", + l_tidlnchrc, + i_ptask->taskname); /*@ errorlog tag * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid INITSVC_START_TASK_MOD_ID + * @moduleid BASE_INITSVC_MOD_ID * @reasoncode START_TASK_FAILED - * @userdata1 task return code + * @userdata1 0 + * @userdata2 task id or task return code * * @devdesc Initialization Service failed to start a task. * */ l_errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - INITSERVICE::INITSVC_START_TASK_MOD_ID, + INITSERVICE::BASE_INITSVC_MOD_ID, INITSERVICE::START_TASK_FAILED, - l_tidrc ); + 0, + l_tidlnchrc ); - // Add the task name as user detail data - ERRORLOG::ErrlUserDetailsString(i_ptask->taskname).addToLog(l_errl); - } // endif tidrc - else + // break out of do block + break; + } // endif tidlnchrc + + TRACDCOMP(g_trac_initsvc, + "Wait for tid %d '%s'", + l_tidlnchrc, + i_ptask->taskname); + + // wait here for the task to end. + // status of the task ( OK or Crashed ) is returned in l_childsts + // if the task returns an errorlog, it will be returned + // (via task_end2) in l_childerrl + l_tidretrc = task_wait_tid( + l_tidlnchrc, + &l_childsts, + &l_childerrl ); + if ( ( static_cast(l_tidretrc) < 0 ) + || ( l_childsts != TASK_STATUS_EXITED_CLEAN ) + ) { - // if InitService passed in a taskargs, wait for barrier. - if ( io_pargs ) - { - io_pargs->waitParentSync(); - } - } // endelse - } // endif ! l_errl + // the launched task failed or crashed, + // post an errorlog and dump some trace + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid BASE_INITSVC_MOD_ID + * @reasoncode WAIT_TASK_FAILED + * @userdata1 task id or task return code + * @userdata2 returned status from task + * + * @devdesc Initialization Service launched a task and + * the task returned an error. + * + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + INITSERVICE::BASE_INITSVC_MOD_ID, + INITSERVICE::WAIT_TASK_FAILED, + l_tidretrc, + l_childsts ); + + // break out of do block + break; + } // endif tidretrc + // check for returned errorlog + if ( l_childerrl != NULL ) + { + // cast to the correct type and return + l_errl = reinterpret_cast(l_childerrl); + + // break out of do block + break; + } + + } while(0); // end do block + + if ( l_errl ) + { + // Add the task name as user detail data to any errorlog + ERRORLOG::ErrlUserDetailsString(i_ptask->taskname).addToLog(l_errl); + } // return any errorlog to the caller return l_errl; -} +} // startTask() + -errlHndl_t InitService::executeFn( const TaskInfo *i_ptask, - TaskArgs *io_pargs ) const +errlHndl_t InitService::executeFn( + const TaskInfo *i_ptask, + void *io_pargs ) const { - tid_t l_tidrc = 0; - errlHndl_t l_errl = NULL; + tid_t l_tidlnchrc = 0; + tid_t l_tidretrc = 0; + errlHndl_t l_errl = NULL; + int l_childsts = 0; + void *l_childerrl = NULL; assert( i_ptask != NULL ); assert( i_ptask->taskfn != NULL ) ; - /** - * @todo: add Doug Gilbert's code here to look up the module based on - * the function pointer and then load the module. - * For now we just blindly load the module in istepdispatcher - */ - // valid function, launch it - l_tidrc = task_create( i_ptask->taskfn, io_pargs); - if (static_cast (l_tidrc) < 0) - { - TRACFCOMP(g_trac_initsvc, "ERROR: starting function in task'%s'", - i_ptask->taskname); - - /*@ errorlog tag - * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid INITSVC_START_FN_MOD_ID - * @reasoncode START_FN_FAILED - * @userdata1 task return code - * - * @devdesc Initialization Service attempted to start a - * function within a module but the function - * failed to launch - */ - l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - INITSERVICE::INITSVC_START_FN_MOD_ID, - INITSERVICE::START_FN_FAILED, - l_tidrc ); + do { - // Add the task name as user detail data - ERRORLOG::ErrlUserDetailsString(i_ptask->taskname).addToLog(l_errl); - } // endif tidrc - else - { - // task launched OK. - if ( io_pargs ) + // + l_errl = checkNLoadModule( i_ptask ); + if ( l_errl ) { - io_pargs->waitParentSync(); // sync up parent task + TRACFCOMP(g_trac_initsvc, + "ERROR: failed to load module for task '%s'", + i_ptask->taskname); + + // break out with errorlog set + break; } + + // valid function, launch it + l_tidlnchrc = task_create( i_ptask->taskfn, io_pargs); + if (static_cast (l_tidlnchrc) < 0) + { + TRACFCOMP(g_trac_initsvc, + "ERROR %d: starting function in task'%s'", + l_tidlnchrc, + i_ptask->taskname); + + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid BASE_INITSVC_MOD_ID + * @reasoncode START_FN_FAILED + * @userdata1 task return code + * @userdata2 0 + * + * @devdesc Initialization Service attempted to start a + * function within a module but the function + * failed to launch + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + INITSERVICE::BASE_INITSVC_MOD_ID, + INITSERVICE::START_FN_FAILED, + l_tidlnchrc, + 0 ); + + // break out with errorlog set + break; + } // endif tidlnchrc + + // wait here for the task to end. + // status of the task ( OK or Crashed ) is returned in l_childsts + // if the task returns an errorlog, it will be returned + // (via task_end2) in l_childerrl + l_tidretrc = task_wait_tid( + l_tidlnchrc, + &l_childsts, + &l_childerrl ); + if ( ( static_cast(l_tidretrc) < 0 ) + || ( l_childsts != TASK_STATUS_EXITED_CLEAN ) + ) + { + // the launched task failed or crashed + // post an errorlog and dump some trace + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid BASE_INITSVC_MOD_ID + * @reasoncode WAIT_TASK_FAILED + * @userdata1 task id or task return code + * @userdata2 returned status from task + * + * @devdesc Initialization Service launched a task and the task returned an error. + * + * + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + INITSERVICE::BASE_INITSVC_MOD_ID, + INITSERVICE::WAIT_TASK_FAILED, + l_tidretrc, + l_childsts ); + + TRACFCOMP(g_trac_initsvc, + "ERROR : task_wait_tid(0x%x). '%s', l_tidretrc=0x%x, l_childsts=0x%x", + l_tidlnchrc, + i_ptask->taskname, + l_tidretrc, + l_childsts ); + + // break out of do block + break; + } // endif tidretrc + + // check for returned errorlog + if ( l_childerrl != NULL ) + { + TRACFCOMP(g_trac_initsvc, + "ERROR : task_wait_tid(0x%x). '%s', l_childerrl=%p", + l_tidlnchrc, + i_ptask->taskname, + l_childerrl ); + + // cast to the correct type and return + l_errl = reinterpret_cast(l_childerrl); + + // break out of do block + break; + } + + } while( 0 ); // end do block + + if ( l_errl ) + { + // Add the task name as user detail data to any errorlog that was + // posted. + ERRORLOG::ErrlUserDetailsString(i_ptask->taskname).addToLog(l_errl); } return l_errl; @@ -195,7 +435,7 @@ void InitService::setProgressCode( uint64_t i_progresscode ) const errlHndl_t InitService::dispatchTask( const TaskInfo *i_ptask, - TaskArgs *io_pargs ) const + void *io_pargs ) const { errlHndl_t l_errl = NULL; @@ -255,20 +495,23 @@ errlHndl_t InitService::dispatchTask( const TaskInfo *i_ptask, void InitService::init( void *io_ptr ) { - errlHndl_t l_errl = NULL; - uint64_t l_task = 0; - const TaskInfo *l_ptask = NULL; - TaskArgs::TaskArgs l_args; - uint64_t l_childrc = 0; + errlHndl_t l_errl = NULL; + uint64_t l_task = 0; + const TaskInfo *l_ptask = NULL; + // init shutdown status to good. + uint64_t l_shutdownStatus = SHUTDOWN_STATUS_GOOD; + + // @todo detach from parent. + // $$ task_detach(); printk( "InitService entry.\n" ); TRACFCOMP( g_trac_initsvc, - ENTER_MRK "Initialization Service is starting %p.", io_ptr ); + "Initialization Service is starting, io_ptr=%p.", io_ptr ); // loop through the task list and start up any tasks necessary for ( l_task=0; - l_task < INITSERVICE::MAX_TASKS; + l_task < ( sizeof(g_taskinfolist)/sizeof(TaskInfo) ) ; l_task++ ) { // make a local copy of the base image task @@ -280,11 +523,9 @@ void InitService::init( void *io_ptr ) break; } - l_args.clear(); // clear args struct for next task - // dispatch the task and return good or errorlog - l_errl = dispatchTask( l_ptask, - &l_args ); + l_errl = dispatchTask( l_ptask , + NULL ); // process errorlogs returned from the task that was launched if ( l_errl ) @@ -296,77 +537,35 @@ void InitService::init( void *io_ptr ) break; } - - // make local copies of the values in TaskArgs that are returned from - // the child. - // this also clears the errorlog from the TaskArgs struct, so - // use it or lose it ( see taskargs.H for details ). - l_childrc = l_args.getReturnCode(); - l_errl = l_args.getErrorLog(); - - if ( l_errl ) - { - TRACFCOMP( g_trac_initsvc, - " ERROR: Child task returned 0x%llx, errlog=0x%p", - l_childrc, - l_errl ); - // drop out with the error - break; - } - else - { - // Check child results for a valid nonzero return code. - // If we have one, and no errorlog, then we create and - // post our own errorlog here. - if ( l_childrc != 0 ) - { - TRACFCOMP( g_trac_initsvc, - "ERROR: Child task '%s' returned 0x%llx, no errlog", - l_ptask->taskname, - l_childrc ); - - /*@ errorlog tag - * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid INITSVC_TASK_RETURNED_ERROR_ID - * @reasoncode INITSVC_FAILED_NO_ERRLOG - * @userdata1 returncode from task - * @userdata2 0 - * - * @devdesc The task returned with an error, - * but there was no errorlog returned. - * See userdata1 for the return code. - * - */ - l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - INITSVC_TASK_RETURNED_ERROR_ID, - INITSERVICE::INITSVC_FAILED_NO_ERRLOG, - l_childrc, - 0 ); - // drop out with the error - break; - } // end if - } // end else } // endfor // die if we drop out with an error if ( l_errl ) { + // commit the log first, then shutdown. - TRACFCOMP( g_trac_initsvc, "InitService: Committing errorlog." ); + TRACFCOMP( g_trac_initsvc, + "InitService: Committing errorlog %p", + l_errl ); errlCommit( l_errl, INITSVC_COMP_ID ); - //Tell initservice to perform shutdown sequence - doShutdown( SHUTDOWN_STATUS_INITSVC_FAILED ); - + // post bad shutdown status + l_shutdownStatus = SHUTDOWN_STATUS_INITSVC_FAILED; } + // ===================================================================== + // ----- Shutdown all CPUs ----------------------------------------- + // ===================================================================== + TRACFCOMP( g_trac_initsvc, - EXIT_MRK "Initilization Service finished."); + "InitService finished, shutdown = 0x%x.", + l_shutdownStatus ); - printk( "InitService exit.\n" ); + // Tell kernel to perform shutdown sequence + InitService::getTheInstance().doShutdown( l_shutdownStatus ); - // return to _start() + printk( "InitService exit.\n" ); + // return to _start() to exit the task. } @@ -426,7 +625,7 @@ void InitService::doShutdown(uint64_t i_status) /* * @errorlog tag * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid INITSVC_DO_SHUTDOWN_MOD_ID + * @moduleid BASE_INITSVC_MOD_ID * @reasoncode SHUTDOWN_FLUSH_FAILED * @userdata1 returncode from mm_remove_pages() * @userdata2 0 @@ -436,7 +635,7 @@ void InitService::doShutdown(uint64_t i_status) */ l_err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - INITSERVICE::INITSVC_DO_SHUTDOWN_MOD_ID, + INITSERVICE::BASE_INITSVC_MOD_ID, INITSERVICE::SHUTDOWN_FLUSH_FAILED,l_rc,0); //Commit and attempt flushing other registered blocks errlCommit( l_err, INITSVC_COMP_ID ); diff --git a/src/usr/initservice/baseinitsvc/initservice.H b/src/usr/initservice/baseinitsvc/initservice.H index 4d15ffeec..d80c5d2ef 100644 --- a/src/usr/initservice/baseinitsvc/initservice.H +++ b/src/usr/initservice/baseinitsvc/initservice.H @@ -42,9 +42,9 @@ #include // VFS_MODULE_NAME_MAX #include -#include +#include // errlHndl_t +#include // errlCommit() #include -#include #include #include @@ -108,47 +108,28 @@ public: * is the name of the compiled and linked targetting module. * The module is expected to have implemented a extern "C" * function called "void _start(void *args)" which is considered - * to be the "task entry point". When _start is called, its - * parameter will be set to point to a TaskArgs struct which - * can be used to pass information back and forth. See the - * comments in TaskArgs.H for more info. - * See initsvctasks.H and the unit tests for some examples of - * how this is used. - * + * to be the "task entry point". * * * @param[in] i_ptask pointer to a TaskInfo struct - * @param[in,out] io_pargs pointer to a TaskArgs struct, or NULL - * On input, TaskArgs struct will have - * command, returncode, and errlog fields - * cleared. task can fill in these values - * on return. + * @param[in,out] io_pargs pointer to any args. This is usually NULL. * * @return pointer to errorlog * @retval NULL if success, filled in errorlog handle for failure - * - * @note startTask() can also be used to launch an asynchronous task - * by calling it with i_pargs set to NULL. This will disable - * the barrier check. - * */ errlHndl_t startTask( const TaskInfo *i_ptask, - TaskArgs::TaskArgs *io_pargs ) const; + void *io_pargs ) const; /** * @brief Execute an function * * @param[in] i_ptask - pointer to an TaskInfo struct - * @param[in,out] i_pargs - pointer to a TaskArgs struct - * On input, TaskArgs struct will have - * command, returncode, and errlog fields - * cleared. Task can fill in these values - * on return. + * @param[in,out] i_pargs - pointer to any args. This is usually NULL. * * @return pointer to errorlog * @retval NULL if success, filled out errorlog if failure */ errlHndl_t executeFn( const TaskInfo *i_ptask, - TaskArgs *i_pargs ) const; + void *i_pargs ) const; /** @@ -172,14 +153,13 @@ public: * * @param[in] i_ptask - pointer to a TaskInfo struct, which should * contain all the info to run the task. - * @param[in,out] io_pargs - pointer to a TaskArgs struct. It is - * possible that this will not be used at all. + * @param[in,out] io_pargs - pointer to any args. This is usually NULL. * * @return pointer to errlog * @retval returns NULL, or a pointer to a filled out errorlog */ errlHndl_t dispatchTask( const TaskInfo *i_ptask, - TaskArgs *io_pargs ) const; + void *io_pargs ) const; /** * @brief Registry a block/range of vitual memory to be handled during a @@ -218,11 +198,24 @@ protected: private: /** - * @note Disable copy constructor and assignment operator + * Disable copy constructor and assignment operator */ InitService(const InitService& i_right); InitService& operator=(const InitService& i_right); + + /** + * Check and load module associated with this task or function + * if necessary. + * + * @param[in] i_ptask - pointer to a TaskInfo struct, which should + * contain all the info to run the task. + * @return pointer to errorlog + * @retval NULL if success, filled out errorlog if failure + */ + errlHndl_t checkNLoadModule( const TaskInfo *i_ptask ) const; + + /** * @struct regBlock_t * @brief Attributes stored for virtual memory ranges that must be handled diff --git a/src/usr/initservice/baseinitsvc/initservicetaskentry.C b/src/usr/initservice/baseinitsvc/initservicetaskentry.C deleted file mode 100644 index eec6eef96..000000000 --- a/src/usr/initservice/baseinitsvc/initservicetaskentry.C +++ /dev/null @@ -1,67 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/baseinitsvc/initservicetaskentry.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 -/** - * @file initservicetaskentry.C - * task entry point for Initialization Service. - * init_main.C will call this by executing - * task_exec( "libinitservice.so", NULL ); - * From there we can execute the classes that will run in the task. - * - * At the end, we must run task_end(). - */ -#include -#include -#include -#include -#include - -#include "initservice.H" - - - -namespace INITSERVICE -{ - -extern trace_desc_t *g_trac_initsvc; - -/** - * @brief task entry routine, called by init_main.C - * - */ - -extern "C" -void _start(void *ptr) -{ - TRACFCOMP( g_trac_initsvc, - ENTER_MRK "Executing Initialization Service module." ); - - // initialize the base modules in Hostboot. - InitService::getTheInstance().init( ptr ); - - TRACFCOMP( g_trac_initsvc, - EXIT_MRK "return from Initialization Service module." ); - - task_end(); -} - -} // namespace diff --git a/src/usr/initservice/baseinitsvc/initsvctasks.H b/src/usr/initservice/baseinitsvc/initsvctasks.H index 69b146c92..eed58f592 100644 --- a/src/usr/initservice/baseinitsvc/initsvctasks.H +++ b/src/usr/initservice/baseinitsvc/initsvctasks.H @@ -33,26 +33,13 @@ #include #include "initservice.H" + namespace INITSERVICE { -const uint64_t MAX_TASKS = 10; const TaskInfo g_taskinfolist[] = { - /** - * @brief Errorlog Task - */ - { - "liberrl.so" , // taskname - NULL, // no ptr to fn - { - NONE, // don't start - BASE_IMAGE, // Base Module - } - }, - - /** * @brief PNOR Driver Task */ @@ -86,7 +73,7 @@ const TaskInfo g_taskinfolist[] = { "libextinitsvc.so" , // taskname NULL, // no pointer to fn { - START_TASK, // call start() + START_TASK, EXT_IMAGE, // EXT_IMAGE } }, diff --git a/src/usr/initservice/baseinitsvc/makefile b/src/usr/initservice/baseinitsvc/makefile index 097dc3f98..0bbe15d22 100644 --- a/src/usr/initservice/baseinitsvc/makefile +++ b/src/usr/initservice/baseinitsvc/makefile @@ -23,7 +23,6 @@ ROOTPATH = ../../../.. MODULE = initservice -OBJS = initservice.o \ - initservicetaskentry.o +OBJS = initservice.o include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/extinitsvc/extinitsvc.C b/src/usr/initservice/extinitsvc/extinitsvc.C index 2db1c44b6..0c42e9678 100644 --- a/src/usr/initservice/extinitsvc/extinitsvc.C +++ b/src/usr/initservice/extinitsvc/extinitsvc.C @@ -40,7 +40,7 @@ #include #include -#include // task entry routine +#include // task entry macro #include "extinitsvc.H" #include "extinitsvctasks.H" @@ -51,36 +51,31 @@ namespace INITSERVICE extern trace_desc_t *g_trac_initsvc; - /** - * @brief set up _start() task entry procedure using the macro in taskargs.H + * _start() task entry procedure using the macro in taskargs.H */ TASK_ENTRY_MACRO( ExtInitSvc::getTheInstance().init ); -void ExtInitSvc::init( void *io_ptr ) +void ExtInitSvc::init( errlHndl_t &io_rtaskRetErrl ) { errlHndl_t l_errl = NULL; uint64_t l_task = 0; const TaskInfo *l_ptask = NULL; - TaskArgs::TaskArgs l_args; - uint64_t l_childrc = 0; - // set up pointer to our taskargs - INITSERVICE::TaskArgs *pTaskArgs = - static_cast( io_ptr ); printk( "ExtInitSvc entry.\n" ); - TRACFCOMP( g_trac_initsvc, - "Extended Initialization Service is starting %p.", io_ptr ); - + // @todo detach from initservice + // task_detach(); + TRACFCOMP( g_trac_initsvc, + "Extended Initialization Service is starting." ); // ---------------------------------------------------------------- // loop through the task list and start up any tasks necessary // ---------------------------------------------------------------- for ( l_task=0; - l_tasktaskname, - l_childrc, l_errl ); - // break out of loop with error + // break out of loop with error. break; } - else - { - // Check child results for a valid nonzero return code. - // If we have one, and no errorlog, then we create and - // post our own errorlog here. - if ( l_childrc != 0 ) - { - TRACFCOMP( g_trac_initsvc, - "EIS: Child task %s returned 0x%llx, no errlog", - l_ptask->taskname, - l_childrc ); - - /*@ errorlog tag - * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid EXTINITSVC_TASK_RETURNED_ERROR_ID - * @reasoncode EXTINITSVC_FAILED_NO_ERRLOG - * @userdata1 returncode from task - * @userdata2 0 - * - * @devdesc The task returned with an error, - * but there was no errorlog returned. - * - */ - l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - EXTINITSVC_TASK_RETURNED_ERROR_ID, - INITSERVICE::EXTINITSVC_FAILED_NO_ERRLOG, - l_childrc, - 0 ); - - // break out of loop with error - break; - } // end if - } // end else } // endfor // die if we drop out with an error if ( l_errl ) { - // dropped out of loop with error. - // Commit the log first, then stop right here. + +#if 0 + // @todo detach this task and just do task_end() + // Commit the errorlog here. TRACFCOMP( g_trac_initsvc, - "ExtInitSvc: Committing errorlog..." ); + "ExtInitSvc ERROR: Committing errorlog %p & shutdown", + l_errl ); errlCommit( l_errl, INITSVC_COMP_ID ); - // pass an error code to initsvc that we are shutting down. - pTaskArgs->postReturnCode( TASKARGS_SHUTDOWN_RC ); - //Tell initservice to perform shutdown sequence + // Tell the kernel to shut down. This will not actually + // happen until the last thread has ended. InitService::getTheInstance().doShutdown( SHUTDOWN_STATUS_EXTINITSVC_FAILED); + + // end the task. + end_task(); +#endif + + // end the task and pass the errorlog to initservice to be committed. + // initservice should do the shutdown. + TRACFCOMP( g_trac_initsvc, + "ExtInitSvc: ERROR: return to initsvc with errlog %p", + l_errl ); + + task_end2( l_errl ); } TRACFCOMP( g_trac_initsvc, - EXIT_MRK "ExtInitSvc finished."); + "ExtInitSvc finished OK."); + - // Test if the child posted an errorcode. If so, don't - // bother to run the unit tests. - if ( pTaskArgs->getReturnCode() == 0 ) + // ===================================================================== + // ----- Unit Tests ------------------------------------------------- + // ===================================================================== + /** + * @note run all of the unit tests after we finish the rest + * There are 2 images generated in the build: + * hbicore.bin (HostBoot shippable image) + * hbicore_test.bin (runs all unit tests) + * Only hbicore_test.bin has the libcxxtest.so module, so that's + * how we test whether to run this. + */ + + // If the test task does not exist then don't run it. + if ( VFS::module_exists( cxxTestTask.taskname ) ) { - // ===================================================================== - // ----- Unit Tests ------------------------------------------------- - // ===================================================================== - /** - * @note run all of the unit tests after we finish the rest - * There are 2 images generated in the build: - * hbicore.bin (HostBoot shippable image) - * hbicore_test.bin (runs all unit tests) - * Only hbicore_test.bin has the libcxxtest.so module, so when - * we execute startTask() below on hbicore.bin, it will return -ENOENT, - * no module present. This is OK. - * - * @todo can we call call module_load() to see if libcxxtest.so exists? - * ask Doug or Patrick - * - */ - - printk( "start CxxTest.\n" ); - - // add a do-while loop so there is only one return at the bottom.... - do + printk( "CxxTest entry.\n" ); + + // Pass it a set of args so we can wait on the barrier + errlHndl_t l_cxxerrl = NULL; + const TaskInfo *l_pcxxtask = &cxxTestTask; + + TRACDCOMP( g_trac_initsvc, + "Run CxxTest Unit Tests: %s", + l_pcxxtask->taskname ); + + l_cxxerrl = InitService::getTheInstance().startTask( l_pcxxtask, + NULL ); + // process any errorlogs from cxxtestexec (not sure there are any...) + if ( l_cxxerrl ) { - // Pass it a set of args so we can wait on the barrier - errlHndl_t l_cxxerrl = NULL; - TaskArgs::TaskArgs l_cxxtestargs; - const TaskInfo *l_pcxxtask = &CXXTEST_TASK; - uint64_t l_cxxchildrc = 0; - errlHndl_t l_cxxchilderrl = NULL; +#if 0 + // @todo detach this task and just do task_end() + // First commit the errorlog... + TRACFCOMP( g_trac_initsvc, + "Committing errorlog %p from cxxtask", + l_cxxerrl ); + errlCommit( l_cxxerrl, INITSVC_COMP_ID ); - l_cxxtestargs.clear(); + // Tell the kernel to shut down. This will not actually + // happen until the last thread has ended. + InitService::getTheInstance().doShutdown( SHUTDOWN_STATUS_UT_FAILED); - TRACDCOMP( g_trac_initsvc, - ENTER_MRK "Run Unit Tests (if libcxxtests.so is present): %s", - l_pcxxtask->taskname ); - - // If the test task does not exist then don't run it. - if(!VFS::module_exists(l_pcxxtask->taskname)) break; - - l_cxxerrl = InitService::getTheInstance().startTask( l_pcxxtask, - &l_cxxtestargs ); - - // process errorlogs returned from the task that was launched - // @TODO if we are running the non-test version of HostBoot, this - // will always post an extra errorlog. We need a way to know - // if we are running the _test version or not. - if ( l_cxxerrl ) - { - TRACFCOMP( g_trac_initsvc, - "Committing error from cxxtask launch" ); - errlCommit( l_cxxerrl, INITSVC_COMP_ID ); - break; // ERROR, break out of do-while. - } - - // make local copies of the values in TaskArgs that are returned from - // the child. - // this also clears the errorlog from the TaskArgs struct, so - // use it or lose it ( see taskargs.H for details ). - l_cxxchildrc = l_cxxtestargs.getReturnCode(); - l_cxxchilderrl = l_cxxtestargs.getErrorLog(); - - if ( l_cxxchilderrl ) - { - TRACFCOMP( g_trac_initsvc, - " Child task returned 0x%llx, errlog=0x%p", - l_cxxchildrc, - l_cxxchilderrl ); - errlCommit( l_cxxchilderrl, INITSVC_COMP_ID ); - } - else - { - // Check child results for a valid nonzero return code. - // If we have one, and no errorlog, then we create and - // post our own errorlog here. - if ( l_cxxchildrc != 0 ) - { - TRACFCOMP( g_trac_initsvc, - "Child task returned 0x%llx, no errlog", - l_cxxchildrc ); - - /*@ errorlog tag - * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid CXXTEST_TASK_RETURNED_ERROR_ID - * @reasoncode CXXTEST_FAILED_NO_ERRLOG - * @userdata1 returncode from istep - * @userdata2 0 - * - * @devdesc The unit test dispatcher returned with an - * error, but there was no errorlog returned. - */ - l_cxxerrl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - CXXTEST_TASK_RETURNED_ERROR_ID, - INITSERVICE::CXXTEST_FAILED_NO_ERRLOG, - l_cxxchildrc, - 0 ); - errlCommit( l_cxxerrl, INITSVC_COMP_ID ); - - } // end if - } // end else - - } while(0); // end do-while - - printk( "finish CxxTest.\n" ); + // end the task. + end_task(); +#endif - } + // end the task and pass the errorlog to initservice to be committed. + // initservice should do the shutdown. + TRACFCOMP( g_trac_initsvc, + "CxxTest: ERROR: return to initsvc with errlog %p", + l_cxxerrl ); + task_end2( l_cxxerrl ); + } // endif l_cxxerrl - // ===================================================================== - // ----- Shutdown all CPUs ----------------------------------------- - // ===================================================================== - TRACFCOMP( g_trac_initsvc, - EXIT_MRK "CxxTests finished."); + // make up and post an errorlog if any tests failed. + if ( CxxTest::g_FailedTests ) + { + // some unit tests failed, post an errorlog + /*@ errorlog tag + * @errortype ERRL_SEV_CRITICAL_SYS_TERM + * @moduleid CXXTEST_MOD_ID + * @reasoncode CXXTEST_FAILED_TEST + * @userdata1 number of failed tests + * @userdata2 0 + * + * @devdesc One or more CxxTest Unit Tests failed. + * + */ + l_cxxerrl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + INITSERVICE::CXXTEST_MOD_ID, + INITSERVICE::CXXTEST_FAILED_TEST, + CxxTest::g_FailedTests, + 0 ); + TRACFCOMP( g_trac_initsvc, + "CxxTest ERROR: %d failed tests, build errlog %p.", + CxxTest::g_FailedTests, + l_cxxerrl ); - uint64_t l_shutdownStatus = SHUTDOWN_STATUS_GOOD; + // end the task and pass the errorlog to initservice to be committed. + // initservice should do the shutdown. + TRACFCOMP( g_trac_initsvc, "CxxTest: return to initsvc with errlog" ); - if (CxxTest::g_FailedTests) - { - l_shutdownStatus = SHUTDOWN_STATUS_UT_FAILED; - } + task_end2( l_cxxerrl ); + } // endif g_FailedTest - //Tell initservice to perform shutdown sequence - InitService::getTheInstance().doShutdown(l_shutdownStatus); + printk( "CxxTest exit.\n" ); - printk( "ExtInitSvc exit.\n" ); + } // endif cxxtest module exists. + // finish things up, return to initservice with goodness. + TRACFCOMP( g_trac_initsvc, + "ExtInitSvc finished OK, return to initsvc with NULL."); + + printk( "ExtInitSvc exit.\n" ); - // return to _start() + task_end2( NULL ); } diff --git a/src/usr/initservice/extinitsvc/extinitsvc.H b/src/usr/initservice/extinitsvc/extinitsvc.H index eb56dd98c..7c6acec1b 100644 --- a/src/usr/initservice/extinitsvc/extinitsvc.H +++ b/src/usr/initservice/extinitsvc/extinitsvc.H @@ -82,14 +82,13 @@ public: */ static ExtInitSvc& getTheInstance(); + /** * @brief Provide an entry function into the class, called from _start() * - * @param[in] i_args pointer to any arguments passed in from - * _start() and by extension the kernel, - * currently this is NULL . + * @param[in] io_rtaskRetErrl ref to an errlHndl_t passed back to _start() */ - void init( void *i_args); + void init( errlHndl_t &io_rtaskRetErrl ); protected: diff --git a/src/usr/initservice/extinitsvc/extinitsvctasks.H b/src/usr/initservice/extinitsvc/extinitsvctasks.H index e02954319..7d40421e4 100644 --- a/src/usr/initservice/extinitsvc/extinitsvctasks.H +++ b/src/usr/initservice/extinitsvc/extinitsvctasks.H @@ -36,7 +36,6 @@ namespace INITSERVICE { -const uint64_t MAX_EXT_TASKS = 25; const TaskInfo g_exttaskinfolist[] = { @@ -284,7 +283,7 @@ const TaskInfo g_exttaskinfolist[] = { // ------------------------------------------------------------------------- // ----- UNIT TESTS ------------------------------------------------- // ------------------------------------------------------------------------- -const TaskInfo CXXTEST_TASK = { +const TaskInfo cxxTestTask = { "libcxxtest.so" , // taskname NULL, // no pointer to fn { diff --git a/src/usr/initservice/initsvctasktest2/makefile b/src/usr/initservice/initsvctasktest2/makefile deleted file mode 100644 index 40d0d6c38..000000000 --- a/src/usr/initservice/initsvctasktest2/makefile +++ /dev/null @@ -1,28 +0,0 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/usr/initservice/initsvctasktest2/makefile $ -# -# IBM CONFIDENTIAL -# -# COPYRIGHT International Business Machines Corp. 2011 -# -# 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 -ROOTPATH = ../../../.. -MODULE = initsvctasktest2 - -OBJS = tasktest2.o - -include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/initsvctasktest2/tasktest2.C b/src/usr/initservice/initsvctasktest2/tasktest2.C deleted file mode 100644 index fdf830518..000000000 --- a/src/usr/initservice/initsvctasktest2/tasktest2.C +++ /dev/null @@ -1,85 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/initsvcunittesttask2/tasktest2.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 - -/** - * @file tasktest2.H - * - */ - -/******************************************************************************/ -// Includes -/******************************************************************************/ -#include -#include -#include -#include - -#include "tasktest2.H" - -namespace INITSERVICE -{ - - -/******************************************************************************/ -// Globals/Constants -/******************************************************************************/ - -/******************************************************************************/ -// InitService::getTheInstance return the only instance -/******************************************************************************/ -InitSvcTaskTest2& InitSvcTaskTest2::getTheInstance() -{ - return Singleton::instance(); -} - - -/** - * @brief _start() - task entry point for this module - * - */ -extern "C" -void _start( void *io_pArgs ) -{ - TaskArgs::TaskArgs *pTaskArgs = (TaskArgs::TaskArgs *)io_pArgs; - - // create an instance of InitService - InitSvcTaskTest2::InitSvcTaskTest2& tt = InitSvcTaskTest2::getTheInstance(); - - // initialize the base modules in Hostboot. - tt.init( io_pArgs ); - - if ( pTaskArgs ) - { - pTaskArgs->waitChildSync(); - } - - task_end(); -} - -void InitSvcTaskTest2::init( void *i_args ) -{ - - return; -}; - -} // namespace diff --git a/src/usr/initservice/initsvctasktest2/tasktest2.H b/src/usr/initservice/initsvctasktest2/tasktest2.H deleted file mode 100644 index 227013990..000000000 --- a/src/usr/initservice/initsvctasktest2/tasktest2.H +++ /dev/null @@ -1,103 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/initsvcunittesttask2/tasktest2.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 - -#ifndef __INITSVC_TASK_TEST_2_H -#define __INITSVC_TASK_TEST_2_H - -/** - * @file tasktest2.H - * - * dummy file for use in initservice unit tests - * - */ - -/******************************************************************************/ -// Includes -/******************************************************************************/ -#include -#include - -namespace INITSERVICE -{ - -/******************************************************************************/ -// Globals/Constants -/******************************************************************************/ - -/******************************************************************************/ -// Typedef/Enumerations -/******************************************************************************/ - -/******************************************************************************/ -// InitService Class -/******************************************************************************/ - -/** - * @class InitSvcTestTask2 - * - * test module launched - */ -class InitSvcTaskTest2 -{ - -public: - - /** - * @brief Constructor for the InitService object. - */ - InitSvcTaskTest2() - { } - - /** - * @brief Destructor for the InitService object. - */ - ~InitSvcTaskTest2() - { } - - /** - * @brief Get singleton instance of this class. - * - * @return the (one and only) instance of InitService - */ - static InitSvcTaskTest2& getTheInstance(); - - /** - * @brief Provide an entry function into the class, called from _start() - * - * @param[in] i_args pointer to any arguments passed in from - * _start() and by extension the kernel, - * currently this is NULL . - * - * @todo document any changes for args - */ - void init( void *i_args); - - -private: - - -}; // class InitSvcTaskTest2 - -} // namespace INITSVCTASKTEST2 - -#endif diff --git a/src/usr/initservice/initsvctesttask/makefile b/src/usr/initservice/initsvctesttask/makefile new file mode 100644 index 000000000..8bdd7cf28 --- /dev/null +++ b/src/usr/initservice/initsvctesttask/makefile @@ -0,0 +1,28 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/initservice/initsvctasktest2/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2011 +# +# 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 +ROOTPATH = ../../../.. +MODULE = initsvctesttask + +OBJS = tasktest2.o + +include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/initsvctesttask/tasktest2.C b/src/usr/initservice/initsvctesttask/tasktest2.C new file mode 100644 index 000000000..c8c52a386 --- /dev/null +++ b/src/usr/initservice/initsvctesttask/tasktest2.C @@ -0,0 +1,66 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/initservice/initsvcunittesttask2/tasktest2.C $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// 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 + +/** + * @file tasktest2.H + * + */ + +/******************************************************************************/ +// Includes +/******************************************************************************/ +#include +#include +#include +#include +#include + +#include "tasktest2.H" + +namespace INITSERVICE +{ + +TASK_ENTRY_MACRO( InitSvcTaskTest2::getTheInstance().init ); + +/******************************************************************************/ +// Globals/Constants +/******************************************************************************/ + +/******************************************************************************/ +// InitService::getTheInstance return the only instance +/******************************************************************************/ +InitSvcTaskTest2& InitSvcTaskTest2::getTheInstance() +{ + return Singleton::instance(); +} + + +void InitSvcTaskTest2::init( errlHndl_t &io_taskRetErrl ) +{ + errlHndl_t l_errl = NULL; + + + task_end2( l_errl ); +}; + +} // namespace diff --git a/src/usr/initservice/initsvctesttask/tasktest2.H b/src/usr/initservice/initsvctesttask/tasktest2.H new file mode 100644 index 000000000..ec2b20db5 --- /dev/null +++ b/src/usr/initservice/initsvctesttask/tasktest2.H @@ -0,0 +1,101 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/initservice/initsvcunittesttask2/tasktest2.H $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// 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 + +#ifndef __INITSVC_TASK_TEST_2_H +#define __INITSVC_TASK_TEST_2_H + +/** + * @file tasktest2.H + * + * dummy file for use in initservice unit tests + * + */ + +/******************************************************************************/ +// Includes +/******************************************************************************/ +#include +#include + + +namespace INITSERVICE +{ + +/******************************************************************************/ +// Globals/Constants +/******************************************************************************/ + +/******************************************************************************/ +// Typedef/Enumerations +/******************************************************************************/ + +/******************************************************************************/ +// InitService Class +/******************************************************************************/ + +/** + * @class InitSvcTestTask2 + * + * test module launched + */ +class InitSvcTaskTest2 +{ + +public: + + /** + * @brief Constructor + */ + InitSvcTaskTest2() + { } + + /** + * @brief Destructor + */ + ~InitSvcTaskTest2() + { } + + /** + * @brief Get singleton instance of this class. + * + * @return the (one and only) instance + */ + static InitSvcTaskTest2& getTheInstance(); + + /** + * @brief Provide an entry function into the class, called from _start() + * + * @param[in,out] - reference to an errlHndl_t + * + */ + void init( errlHndl_t &io_taskRetErrl ); + + +private: + + +}; // class InitSvcTaskTest2 + +} // namespace INITSVCTASKTEST2 + +#endif diff --git a/src/usr/initservice/initsvcunittesttask2/makefile b/src/usr/initservice/initsvcunittesttask2/makefile deleted file mode 100644 index dfb0339ee..000000000 --- a/src/usr/initservice/initsvcunittesttask2/makefile +++ /dev/null @@ -1,28 +0,0 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/usr/initservice/initsvcunittesttask2/makefile $ -# -# IBM CONFIDENTIAL -# -# COPYRIGHT International Business Machines Corp. 2011 -# -# 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 -ROOTPATH = ../../../.. -MODULE = tasktest2 - -OBJS = tasktest2.o - -include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.C b/src/usr/initservice/istepdispatcher/istepdispatcher.C index 6c36fa1ec..519369f64 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.C +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.C @@ -55,7 +55,7 @@ #include // ISTEPS_TRACE buffer #include // InitSvcUserDetailsIstep -#include // TaskArgs structs +#include // TASK_ENTRY_MACRO #include // ISTEP_MODE attribute @@ -93,39 +93,37 @@ using namespace SPLESS; // SingleStepMode extern trace_desc_t *g_trac_initsvc; /** - * @note SPLess PAUSE - These two constants are used in a nanosleep() call * below to sleep between polls of the StatusReg. Typically this will * be about 10 ms - the actual value will be determined empirically. - * */ const uint64_t SINGLESTEP_PAUSE_S = 0; const uint64_t SINGLESTEP_PAUSE_NS = 10000000; /** - * @brief set up _start() task entry procedure using the macro in taskargs.H + * _start() task entry procedure using the macro in taskargs.H */ TASK_ENTRY_MACRO( IStepDispatcher::getTheInstance().init ); const TaskInfo *IStepDispatcher::findTaskInfo( const uint16_t i_IStep, - const uint16_t i_SubStep, - const char *&io_rmodulename ) const + const uint16_t i_SubStep ) const { + // 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 will translate to index into + * numbers ( starting at 1 ) - this routine should translate to index into * the isteplists ( starting at 0 ) * + * int16_t l_istepIndex = i_IStep-1; + * int16_t l_substepIndex = i_SubStep-1; + * + * assert( l_istepIndex >= 0 ); + * assert( l_substepIndex >= 0 ); */ - //int16_t l_istepIndex = i_IStep-1; - //int16_t l_substepIndex = i_SubStep-1; - - //assert( l_istepIndex >= 0 ); - //assert( l_substepIndex >= 0 ); // apply filters do @@ -134,7 +132,7 @@ const TaskInfo *IStepDispatcher::findTaskInfo( if ( g_isteps[i_IStep].pti == NULL) { TRACDCOMP( g_trac_initsvc, - "g_isteps[0x%x].pti == NULL (substep=0x%x)", + "g_isteps[%d].pti == NULL (substep=%d)", i_IStep, i_SubStep ); break; @@ -144,7 +142,7 @@ const TaskInfo *IStepDispatcher::findTaskInfo( if ( i_IStep >= MAX_ISTEPS ) { TRACDCOMP( g_trac_initsvc, - "IStep 0x%x out of range. (substep=0x%x) ", + "IStep %d out of range. (substep=%d) ", i_IStep, i_SubStep ); break; // break out with l_pistep set to NULL @@ -154,7 +152,7 @@ const TaskInfo *IStepDispatcher::findTaskInfo( if ( i_SubStep >= g_isteps[i_IStep].numitems ) { TRACDCOMP( g_trac_initsvc, - "IStep 0x%x Substep 0x%x out of range.", + "IStep %d Substep %d out of range.", i_IStep, i_SubStep ); break; // break out with l_pistep set to NULL @@ -165,7 +163,7 @@ const TaskInfo *IStepDispatcher::findTaskInfo( == END_TASK_LIST ) { TRACDCOMP( g_trac_initsvc, - "IStep 0x%x SubSStep 0x%x task_type==END_TASK_LIST.", + "IStep %d SubStep %d task_type==END_TASK_LIST.", i_IStep, i_SubStep ); break; @@ -177,25 +175,15 @@ const TaskInfo *IStepDispatcher::findTaskInfo( if ( g_isteps[i_IStep].pti[i_SubStep].taskfn == NULL ) { TRACDCOMP( g_trac_initsvc, - "IStep 0x%x SubSStep 0x%x fn ptr is NULL.", + "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] ); - // find the name of the module that contains this function, - io_rmodulename = VFS::module_find_name( - reinterpret_cast(l_pistep->taskfn) ); - // looks good, send it back to the caller - TRACDCOMP( g_trac_initsvc, - "Found TaskInfo 0x%p %d.%d in module %s", - l_pistep, - i_IStep, - i_SubStep, - ((io_rmodulename!=NULL)?io_rmodulename:"NULL???") ); - } while ( 0 ); @@ -203,9 +191,8 @@ const TaskInfo *IStepDispatcher::findTaskInfo( } -void IStepDispatcher::init( void * io_ptr ) +void IStepDispatcher::init( errlHndl_t &io_rtaskRetErrl ) { - // note, io_ptr will pass the TaskArgs struct through to runAllSteps, etc. // initialize (and declare) ISTEPS_TRACE here, the rest of the isteps will use it. ISTEPS_TRACE::g_trac_isteps_trace = NULL; @@ -215,8 +202,7 @@ void IStepDispatcher::init( void * io_ptr ) TRAC_INIT(&ISTEPS_TRACE::g_trac_isteps_trace, "ISTEPS_TRACE", 2048 ); TRACFCOMP( g_trac_initsvc, - "IStep Dispatcher is starting %p.", io_ptr ); - + "IStep Dispatcher is starting." ); if ( getIStepMode() ) { @@ -226,7 +212,7 @@ void IStepDispatcher::init( void * io_ptr ) "IStep single-step enable" ); // IStep single-step - singleStepISteps( io_ptr ); + singleStepISteps( io_rtaskRetErrl ); } else { @@ -236,7 +222,7 @@ void IStepDispatcher::init( void * io_ptr ) "IStep run all" ); // Run all the ISteps sequentially - runAllISteps( io_ptr ); + runAllISteps( io_rtaskRetErrl ); } // endelse @@ -245,7 +231,8 @@ void IStepDispatcher::init( void * io_ptr ) printk( "IStepDispatcher exit.\n" ); - // return to _start() + + task_end2( io_rtaskRetErrl ); } @@ -273,35 +260,20 @@ bool IStepDispatcher::getIStepMode( ) const } -/** - * @brief Command 0: Run the requested IStep/SubStep - * - * param[in] i_rcmd - ref to a filled in SPLessCmd struct - * @post iv_sts set to current istep status - * - * @return none - */ void IStepDispatcher::processSingleIStepCmd( SPLessCmd &i_rrawcmd ) { errlHndl_t l_errl = NULL; - uint64_t l_isteprc = NULL; - TaskArgs::TaskArgs l_taskargs; const TaskInfo *l_pistep = NULL; // init the command 0x00 struct to the incoming command reg values SPLessSingleIStepCmd l_cmd( i_rrawcmd ); // create a cleared status 0x00 reg SPLessSingleIStepSts l_sts; - const char *l_modulename = NULL; - - // look up istep+substep l_pistep = IStepDispatcher::getTheInstance().findTaskInfo( l_cmd.istep, - l_cmd.substep, - l_modulename); - + l_cmd.substep ); do { if ( l_pistep == NULL ) @@ -349,46 +321,6 @@ void IStepDispatcher::processSingleIStepCmd( // handleBreakPoint will need sequence number iv_sts.hdr.seqnum = l_cmd.hdr.seqnum; - - /** - * @todo temporary - executeFn will eventually figure out and - * load the correct module - */ - if ( ( l_modulename != NULL ) - && ( !VFS::module_is_loaded( l_modulename ) ) - ) - { - TRACDCOMP( g_trac_initsvc, - "loading module %s", - l_modulename ); - l_errl = VFS::module_load( l_modulename ); - if ( l_errl ) - { - // can't load module for istep, break out of inner loop - // with errl set - TRACFCOMP( g_trac_initsvc, - "Could not load module %s", - l_modulename ); - - l_sts.hdr.status = SPLESS_TASKRC_RETURNED_ERRLOG; - // go ahead and commit the errorlog - errlCommit( l_errl, INITSVC_COMP_ID ); - - // failed to load module, return error - l_sts.hdr.runningbit = false; - l_sts.hdr.readybit = true; - l_sts.hdr.status = SPLESS_TASKRC_FAIL_LOADMODULE; - l_sts.istep = l_cmd.istep; - l_sts.substep = l_cmd.substep; - l_sts.istepStatus = 0; - - // return to caller to write back to user console - iv_sts = l_sts; - - break; - } - } - /** * @todo placeholder - set progress code before starting * This will not be finalized until the progress code driver @@ -403,56 +335,28 @@ void IStepDispatcher::processSingleIStepCmd( l_cmd.substep, l_pistep->taskname ); - // clear the TaskArgs struct - l_taskargs.clear(); - // clear the status struct for the next step l_sts.val64 = 0; // launch the istep l_errl = InitService::getTheInstance().executeFn( l_pistep, - &l_taskargs ); - // filter errors returning from executeFn + NULL ); + // check for child errorlog if ( l_errl ) { - // handle an errorlog from the parent. This means the - // launch failed, set the task Status to Bad. - // no need to process child info, thus the else. - // set the taskStatus to LAUNCH_FAIL; this will fall - // out the bottom and be written to SPLESS Status - l_sts.hdr.status = SPLESS_TASKRC_LAUNCH_FAIL; + // tell the user that the IStep returned an errorlog + l_sts.hdr.status = SPLESS_TASKRC_RETURNED_ERRLOG; + l_sts.istepStatus = SPLESS_TASKRC_RETURNED_ERRLOG; + // go ahead and commit the child errorlog errlCommit( l_errl, INITSVC_COMP_ID ); } - else - { - // process information returned from the IStep. - // make local copies of the info; this has a secondary - // effect of clearing the errorlog pointer inside - // the TaskArgs struct. - l_isteprc = l_taskargs.getReturnCode(); // local copy - l_errl = l_taskargs.getErrorLog(); // local copy - - // check for child errorlog - if ( l_errl ) - { - // tell the user that the IStep returned an errorlog - l_sts.hdr.status = SPLESS_TASKRC_RETURNED_ERRLOG; - // go ahead and commit the child errorlog - errlCommit( l_errl, INITSVC_COMP_ID ); - } - - // truncate IStep return status to 32 bits. - l_isteprc &= SPLESS_SINGLE_STEP_STS_MASK; - l_sts.istepStatus = static_cast(l_isteprc); - } // end else parent errlog - // task status and istepStatus should be set correctly now, - // send it to the user console. + // send status to the user console. // clear runningbit, report status // set running bit, fill in istep and substep l_sts.hdr.runningbit = false; l_sts.hdr.readybit = true; - // l_sts.hdr.seqnum = i_seqnum; + // l_sts.hdr.seqnum set by caller // task status set above l_sts.istep = l_cmd.istep; l_sts.substep = l_cmd.substep; @@ -473,25 +377,15 @@ void IStepDispatcher::processSingleIStepCmd( } -/** - * @brief singleStepISteps - * - * Stop and wait for SP to send the next IStep to run. Run that, then - * wait for the next one. - * This is not expected to return - errors etc are sent to the user to - * handle. - * - * @param[in,out] io_ptr - pointer to any args passed in from - * ExtInitSvc. This may be a pointer to an - * TaskArgs struct (or something else) which - * can be filled out on return - * - * @return none - */ -void IStepDispatcher::singleStepISteps( void * io_ptr ) +void IStepDispatcher::singleStepISteps( errlHndl_t &io_rtaskRetErrl ) { SPLessCmd l_cmd; uint8_t l_seqnum = 0; + bool quitflag = false; + errlHndl_t l_errl = NULL; + + // init to no errorlog + io_rtaskRetErrl = NULL; mutex_lock(&iv_poll_mutex); // make sure this is only poller @@ -524,11 +418,7 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) { switch( l_cmd.hdr.cmdnum ) { - case SPLESS_CLEAR_TRACE_CMD: - TRAC_CLEAR_BUFFERS(); - TRACFCOMP( g_trac_initsvc, - "Cleared all trace buffers." ); - break; + case SPLESS_SINGLE_ISTEP_CMD: mutex_unlock(&iv_poll_mutex); // command 0: run istep/substep @@ -540,6 +430,17 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) iv_sts.hdr.status = SPLESS_NOT_AT_BREAK_POINT; break; + case SPLESS_CLEAR_TRACE_CMD: + TRAC_CLEAR_BUFFERS(); + TRACFCOMP( g_trac_initsvc, + "Cleared all trace buffers." ); + break; + + case SPLESS_SHUTDOWN_CMD: + iv_sts.hdr.status = SPLESS_SHUTTING_DOWN; + quitflag = true; + break; + default: iv_sts.hdr.status = SPLESS_INVALID_COMMAND; } // endif switch @@ -554,6 +455,30 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) } // endif gobit + if ( quitflag == true ) + { + // shutdown command issued, break out of loop + + /*@ errorlog tag + * @errortype ERRL_SEV_INFORMATIONAL + * @moduleid BASE_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::BASE_INITSVC_MOD_ID, + INITSERVICE::ISTEP_SINGLESTEP_SHUTDOWN, + 0, + 0 ); + + break; + } + // sleep, and wait for user to give us something else to do. /** * @todo Need a common method of doing delays in HostBoot @@ -575,8 +500,6 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) // @note // Fell out of loop, clear sts reg and turn off readybit - // Currently this will never be reached. Later there may be - // a reason to break out of the loop, if this happens we want to // disable the ready bit so the user knows. iv_sts.val64 = 0; iv_sts.hdr.status = SPLESS_TASKRC_TERMINATED; @@ -584,25 +507,21 @@ void IStepDispatcher::singleStepISteps( void * io_ptr ) writeSts( iv_sts ); mutex_unlock(&iv_poll_mutex); + // return with io_rtaskRetErrl set + io_rtaskRetErrl = l_errl; } -void IStepDispatcher::runAllISteps( void * io_ptr ) const +void IStepDispatcher::runAllISteps( errlHndl_t &io_rtaskRetErrl ) const { errlHndl_t l_errl = NULL; uint16_t l_IStep = 0; uint16_t l_SubStep = 0; const TaskInfo *l_pistep = NULL; uint64_t l_progresscode = 0; - uint64_t l_isteprc = 0; - const char *l_modulename = NULL; - - // taskargs struct for children - TaskArgs::TaskArgs l_args; - // set up pointer to our taskargs, passed in from caller - INITSERVICE::TaskArgs *pTaskArgs = - static_cast( io_ptr ); + // init, just to be sure. + io_rtaskRetErrl = NULL; for ( l_IStep=0; l_ISteptaskname ); - - l_args.clear(); l_errl = InitService::getTheInstance().executeFn( l_pistep, - &l_args ); - if ( l_errl ) - { - // Handle an errorlog from the parent, if it exists - // an error here is probably fatal, it means we can't - // launch the task or it doesn't exist. In either - // case we should exit the loop. - // Can't commit the errorlog here because we are using it - // as a flag to exit the loop. - break; - } - - // make local copies of the status returned from the istep. - // note that this also removes the errorlog from the TaskArgs - // struct - it is read-once. See taskargs.H for details - l_isteprc = l_args.getReturnCode(); - l_errl = l_args.getErrorLog(); - - + NULL ); if ( l_errl ) { TRACFCOMP( g_trac_initsvc, - "ISD: istep %s returned 0x%llx, errlog=%p", + "IStepDisp: istep %s returned errlog=%p", l_pistep->taskname, - l_isteprc, l_errl ); // if we have an errorlog, break out of the inner loop // and handle it. break; } - else - { - // Check child results for a valid nonzero return code. - // If we have one, and no errorlog, then we create an - // errorlog here. - if ( l_isteprc != 0 ) - { - TRACFCOMP( g_trac_initsvc, - "ISD: istep %s returned 0x%llx, no errlog", - l_pistep->taskname, - l_isteprc ); - - /*@ errorlog tag - * @errortype ERRL_SEV_CRITICAL_SYS_TERM - * @moduleid ISTEP_RETURNED_ERROR_ID - * @reasoncode ISTEP_FAILED_NO_ERRLOG - * @userdata1 istep / substep - * @userdata2 returncode from istep - * - * @devdesc The Istep returned with an error, - * but there was no errorlog posted - * from the IStep. Look at user1 data - * for the istep / substep, and - * user2 data for the returned errorcode. - */ - l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, - ISTEP_RETURNED_ERROR_ID, - INITSERVICE::ISTEP_FAILED_NO_ERRLOG, - ( l_IStep << 8 | l_SubStep ), - l_isteprc ); - - // Add IStep user detail data to the error log - InitSvcUserDetailsIstep(l_pistep->taskname, l_IStep, - l_SubStep).addToLog( l_errl ); - - // drop out of inner loop with errlog set. - break; - } // end if ( ) - } + } // endfor l_SubStep if ( l_errl ) @@ -746,22 +580,14 @@ void IStepDispatcher::runAllISteps( void * io_ptr ) const */ - // Post any errorlogs. If one exists, stop here. Otherwise, return - // to caller. if ( l_errl ) { TRACFCOMP( g_trac_initsvc, - "ERROR: istep=0x%x, substep=0x%x, isteprc=0x%x, committing errorlog and shutting down.", - l_IStep, - l_SubStep, - l_isteprc ); - errlCommit( l_errl, INITSVC_COMP_ID ); - - // pass an error code on to extinitsvc that we are shutting down. - pTaskArgs->postReturnCode( TASKARGS_SHUTDOWN_RC ); - //Tell initservice to perform shutdown sequence - InitService::getTheInstance().doShutdown( SHUTDOWN_STATUS_ISTEP_FAILED ); + "IStepDisp ERROR: errorlog %p", + l_errl ); + // return to _start() with the errorlog set, parent should do shutdown + io_rtaskRetErrl = l_errl; } } @@ -797,6 +623,7 @@ IStepDispatcher::IStepDispatcher() IStepDispatcher::~IStepDispatcher() { } + void IStepDispatcher::handleBreakPoint( uint32_t i_info ) { SPLessCmd l_cmd; diff --git a/src/usr/initservice/istepdispatcher/istepdispatcher.H b/src/usr/initservice/istepdispatcher/istepdispatcher.H index 6679f30d5..b4842f5e9 100644 --- a/src/usr/initservice/istepdispatcher/istepdispatcher.H +++ b/src/usr/initservice/istepdispatcher/istepdispatcher.H @@ -92,19 +92,19 @@ public: /** * @brief Provide an entry function into the class, called from _start() * - * @param[in] i_pargs pointer to any arguments passed in from - * _start(). + * @param[in] io_rtaskRetErrl - ref to errlHndl_t passed back to _start(). * * @return nothing */ - void init( void *i_pargs); + void init( errlHndl_t &io_rtaskRetErrl ); + /** * @brief Handle an istep break point * @param[in] i_info, @TODO - location/info - * @pre iv_sts contains current istep status + seqnum or + * @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. + * @note blocks until an outside istep cmd to resume is recieved. */ void handleBreakPoint( uint32_t info); @@ -146,7 +146,6 @@ private: * * @param[in] i_IStep - IStepNumber * @param[in] i_SubStep - SubStepNumber - * @param[in,out] io_rmodulename - return name of module to load * * @return pointer to a TaskInfo struct * @retval pointer to a TaskInfo struct, or NULL @@ -154,8 +153,7 @@ private: */ const TaskInfo *findTaskInfo( const uint16_t i_IStep, - const uint16_t i_SubStep, - const char *&io_rmodulename ) const; + const uint16_t i_SubStep ) const; /** * @brief Command 0: Run the requested IStep/SubStep @@ -165,8 +163,7 @@ private: * * @return none */ - void processSingleIStepCmd( - SPLESS::SPLessCmd &i_rcmd); + void processSingleIStepCmd( SPLESS::SPLessCmd &i_rcmd); /** @@ -174,17 +171,12 @@ private: * * Stop and wait for SP to send the next IStep to run. Run that, then * wait for the next one. - * This is not expected to return - errors etc are sent to the user to - * handle. - * - * @param[in,out] io_ptr - pointer to any args passed in from - * ExtInitSvc. This may be a pointer to an - * TaskArgs struct (or something else) which - * can be filled out on return + * @param[in,out] - ref to an errlHndl_t that can be passed back to + * ExtInitSvc . * * @return none */ - void singleStepISteps( void * io_ptr ); + void singleStepISteps( errlHndl_t &io_rtaskRetErrl ) ; /** @@ -194,14 +186,12 @@ private: * If an IStep gets an error, report it and stop. * Otherwise, return. * - * @param[in,out] io_ptr - pointer to a TaskArgs struct on input - * command, returncode and errorlog will be - * clear on input - * one or more may be filled in on return + * @param[in,out] - ref to an errlHndl_t that can be passed back to + * ExtInitSvc . * * @return none */ - void runAllISteps( void * io_ptr ) const; + void runAllISteps( errlHndl_t &io_rtaskRetErrl ) const; /** @@ -226,9 +216,10 @@ private: * vague - requirements for Can-Continue behaviour have not been * defined yet. */ - bool getCanContinueProcedure( const TaskInfo &i_failingIStep, - errlHndl_t &i_failingError, - TaskInfo &io_nextIStep ) const; + bool getCanContinueProcedure( + const TaskInfo &i_failingIStep, + errlHndl_t &i_failingError, + TaskInfo &io_nextIStep ) const; // ----- internal vars ----------------------------- diff --git a/src/usr/initservice/istepdispatcher/splesscommand.C b/src/usr/initservice/istepdispatcher/splesscommand.C deleted file mode 100644 index 563a4be3a..000000000 --- a/src/usr/initservice/istepdispatcher/splesscommand.C +++ /dev/null @@ -1,113 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/istepdispatcher/splesscommand.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 - -/** - * @file splesscommand.C - * - * Collection of routines to read/write the spless command reg - * - */ - - -/******************************************************************************/ -// Includes -/******************************************************************************/ -#include -#include -#include - -#include // errlHndl_t -#include // mmio_scratch_read/write - -#include "splesscommon.H" - - -/******************************************************************************/ -// Globals/Constants -/******************************************************************************/ - -/******************************************************************************/ -// Typedef/Enumerations -/******************************************************************************/ - -namespace SPLESSCMD -{ - - -void read( bool &io_rgobit, - uint16_t &io_ristep, - uint16_t &io_rsubstep ) -{ - InternalCommand l_cmd; - - l_cmd.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_COMMAND); - - io_rgobit = l_cmd.f.gobit; - io_ristep = l_cmd.f.istep; - io_rsubstep = l_cmd.f.substep; - -} - - -void write( const bool i_gobit, - const uint16_t i_istep, - const uint16_t i_substep ) -{ - InternalCommand l_cmd; - - // copy into union - l_cmd.f.gobit = i_gobit; - l_cmd.f.istep = i_istep; - l_cmd.f.substep = i_substep; - - mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_COMMAND, l_cmd.val64 ); - -} - - -void getgobit( bool &o_rgobit ) -{ - uint16_t l_istep = 0; - uint16_t l_substep = 0; - - // re-use above call... - read( o_rgobit, - l_istep, - l_substep ); - -} - - -void setgobit( const bool i_gobit ) -{ - InternalCommand l_cmd; - - l_cmd.val64 = mmio_scratch_read( MMIO_SCRATCH_IPLSTEP_COMMAND); - - l_cmd.f.gobit = i_gobit; - - mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_COMMAND, l_cmd.val64 ); - -} - -} // namespace diff --git a/src/usr/initservice/istepdispatcher/splesscommon.H b/src/usr/initservice/istepdispatcher/splesscommon.H index 2cb273f0e..e912b7a85 100644 --- a/src/usr/initservice/istepdispatcher/splesscommon.H +++ b/src/usr/initservice/istepdispatcher/splesscommon.H @@ -95,9 +95,10 @@ enum { SPLESS_TASKRC_TERMINATED = -6, // terminated the polling loop SPLESS_TASKRC_FAIL_LOADMODULE = -7, // failed to load module - SPLESS_INVALID_COMMAND = 10, // invalid command from user console - SPLESS_AT_BREAK_POINT = 11, // at breakpoint - SPLESS_NOT_AT_BREAK_POINT = 12, // resume command w/o breakpoint + SPLESS_INVALID_COMMAND = 10, // invalid command from user console + SPLESS_AT_BREAK_POINT = 11, // at breakpoint + SPLESS_NOT_AT_BREAK_POINT = 12, // resume command w/o breakpoint + SPLESS_SHUTTING_DOWN = 13, // shutdown command issued }; /** @@ -139,6 +140,8 @@ extern uint64_t g_SPLess_IStepMode_Reg; 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; /** diff --git a/src/usr/initservice/istepdispatcher/splessstatus.C b/src/usr/initservice/istepdispatcher/splessstatus.C deleted file mode 100644 index 30818778c..000000000 --- a/src/usr/initservice/istepdispatcher/splessstatus.C +++ /dev/null @@ -1,93 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/istepdispatcher/splessstatus.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 -/** - * @file splessstatus.C - * - * Routines to read and write spless status reg - * - */ - -/******************************************************************************/ -// Includes -/******************************************************************************/ -#include -#include -#include - -#include // errlHndl_t -#include // mmio_scratch_read/write - -#include "splesscommon.H" - -/******************************************************************************/ -// Globals/Constants -/******************************************************************************/ - -/******************************************************************************/ -// Typedef/Enumerations -/******************************************************************************/ - - -void SPLESSSTS::read( bool &io_rrunningbit, - bool &io_rreadybit, - uint16_t &io_ristep, - uint16_t &io_rsubstep, - uint16_t &io_rtaskStatus, - uint16_t &io_ristepStatus ) -{ - InternalStatus l_sts; - - l_sts.val64 = mmio_scratch_read(MMIO_SCRATCH_IPLSTEP_STATUS); - - // read was good - io_rrunningbit = l_sts.f.runningbit; - io_rreadybit = l_sts.f.readybit; - io_ristep = l_sts.f.istep; - io_rsubstep = l_sts.f.substep; - io_rtaskStatus = l_sts.f.taskStatus; - io_ristepStatus = l_sts.f.istepStatus; - -} - - -void SPLESSSTS::write( const bool i_runningbit, - const bool i_readybit, - const uint16_t i_istep, - const uint16_t i_substep, - const uint16_t i_taskStatus, - const uint16_t i_istepStatus ) -{ - InternalStatus l_sts; - - // copy in all the values - l_sts.f.runningbit = i_runningbit; - l_sts.f.readybit = i_readybit; - l_sts.f.istep = i_istep; - l_sts.f.substep = i_substep; - l_sts.f.taskStatus = i_taskStatus; - l_sts.f.istepStatus = i_istepStatus; - - mmio_scratch_write( MMIO_SCRATCH_IPLSTEP_STATUS, l_sts.val64 ); - -} - diff --git a/src/usr/initservice/makefile b/src/usr/initservice/makefile index 5bdac5fde..c87b7187a 100644 --- a/src/usr/initservice/makefile +++ b/src/usr/initservice/makefile @@ -26,9 +26,9 @@ ROOTPATH = ../../.. # OBJS = -# NOTE: initsvctasktest2 is a dummy module that is executed by +# NOTE: initsvctest is a dummy module that is executed by # unit test 2 in the test directory. Please do not rename. -SUBDIRS = baseinitsvc.d extinitsvc.d taskargs.d istepdispatcher.d \ - test.d initsvctasktest2.d build.d +SUBDIRS = baseinitsvc.d extinitsvc.d istepdispatcher.d \ + test.d initsvctesttask.d build.d include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/taskargs/makefile b/src/usr/initservice/taskargs/makefile deleted file mode 100644 index 7d3c28fd8..000000000 --- a/src/usr/initservice/taskargs/makefile +++ /dev/null @@ -1,28 +0,0 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. -# -# $Source: src/usr/initservice/taskargs/makefile $ -# -# IBM CONFIDENTIAL -# -# COPYRIGHT International Business Machines Corp. 2011 -# -# 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 -ROOTPATH = ../../../.. -MODULE = taskargs - -OBJS = taskargs.o - -include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/taskargs/taskargs.C b/src/usr/initservice/taskargs/taskargs.C deleted file mode 100644 index 75cd7f828..000000000 --- a/src/usr/initservice/taskargs/taskargs.C +++ /dev/null @@ -1,162 +0,0 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/taskargs/taskargs.C $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// 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 - -/** - * @file taskargs.C - * - * common file to hold arguments passed onto tasks. - * will also hold macros, etc to manage arguments - * - * @note Notes on barrier: - * barrier_init() will initialize the barrier to the number of threads to - * wait on. - * "barrier_wait() function shall synchronize participating threads at - * the barrier referenced by barrier. - * The calling thread shall block until the required number of threads - * have called pthread_barrier_wait specifying the barrier." - * - * So in this case, the barrier is initialized to 2 (through barrier_init() - * in the constructor). - * When InitSvc launches the child, it calls barrier wait() (through - * waitChildSync() ) which adds 1 task to the "waitlist", blocks, and - * returns to InitSvc. InitSvc then calls waitParentSync() which adds - * its' task to the "waitlist". When the second task is added, both task - * are unblocked. - * - * The barrier is destroyed when TaskArgs goes out of scope by calling - * barrier_destroy() in the destructor. - * - */ - -#include - - -namespace INITSERVICE -{ - -extern trace_desc_t *g_trac_initsvc; - - -void TaskArgs::waitParentSync( ) -{ - - barrier_wait( &iv_sync_barrier); - -} - - -void TaskArgs::waitChildSync( ) -{ - - barrier_wait( &iv_sync_barrier); - -} - - -void TaskArgs::postReturnCode( const uint64_t i_returncode ) -{ - iv_taskreturncode = i_returncode; - - return; -} - - -uint64_t TaskArgs::getReturnCode( ) const -{ - - return iv_taskreturncode; -} - - -void TaskArgs::setCommand( const uint64_t i_command ) -{ - - iv_taskcommand = i_command; - - return; -} - - -uint64_t TaskArgs::getCommand( ) const -{ - - return iv_taskcommand; -} - - -void TaskArgs::postErrorLog( errlHndl_t i_errl ) -{ - - iv_errl = i_errl; -} - - -errlHndl_t TaskArgs::getErrorLog( ) -{ - errlHndl_t l_errl = iv_errl; - - // null out iv_errl after returning it to someone. - iv_errl = NULL; - - return l_errl; -} - - -void TaskArgs::clear() -{ - iv_taskreturncode = 0; // init iv_returncode - iv_taskcommand = 0; // init iv_command - - // this should not happen, should have been handled by the caller(s) - // commit the errorlog here just to get rid of it - if ( iv_errl ) - { - TRACFCOMP( g_trac_initsvc, - ERR_MRK "ERROR: errorlog %p was left in TaskArgs", - iv_errl ); - - errlCommit(iv_errl,INITSVC_COMP_ID); - } - -} - - -TaskArgs::TaskArgs() -: iv_errl( NULL ), // init errorlog handle to NULL - iv_taskreturncode(0), // init iv_returncode to undefined - iv_taskcommand(0) // init iv_command to undefined -{ - // set barrier to wait for 2 tasks before releasing, - // see notes above. - barrier_init( &iv_sync_barrier, 2 ); -} - - -TaskArgs::~TaskArgs() -{ - clear(); - barrier_destroy( &iv_sync_barrier ); - // add an assert here to check if there is still an errorlog pending? -} - -}; // namespace diff --git a/src/usr/initservice/test/initservicetest.H b/src/usr/initservice/test/initservicetest.H index d912a6e88..5cbd77111 100644 --- a/src/usr/initservice/test/initservicetest.H +++ b/src/usr/initservice/test/initservicetest.H @@ -32,6 +32,8 @@ #define __TEST_INIT_SERVICETEST_H +#include // errlHndl_t +#include // errlCommit() #include @@ -58,7 +60,7 @@ const INITSERVICE::TaskInfo TASK_TEST1 = { * */ const INITSERVICE::TaskInfo TASK_TEST2 = { - "libinitsvctasktest2.so" , // taskname + "libinitsvctesttask.so" , // taskname NULL, // ptr to fn { INITSERVICE::START_TASK, // startflag=true, try to start @@ -110,7 +112,7 @@ public: TS_TRACE( "=====>Run a nonexistent task, expect an ERROR."); l_errl = l_is.startTask( &TASK_TEST1, - NULL ); + NULL ); if ( l_errl ) { TS_TRACE( "SUCCESS: startTask returned an errorlog.\n"); -- cgit v1.2.1