summaryrefslogtreecommitdiffstats
path: root/src/usr/initservice/extinitsvc/extinitsvc.C
diff options
context:
space:
mode:
authorMark Wenning <wenning@us.ibm.com>2011-07-29 18:05:34 -0500
committerMark W. Wenning <wenning@us.ibm.com>2011-08-31 16:55:20 -0500
commitddc062ce177ca591958b0d6bdf4c1b616899a340 (patch)
tree961842e056dfecad329f472b98e521992c856f49 /src/usr/initservice/extinitsvc/extinitsvc.C
parent0ebac914541254c4b9ee2a271f26cd67fc2b94a0 (diff)
downloadtalos-hostboot-ddc062ce177ca591958b0d6bdf4c1b616899a340.tar.gz
talos-hostboot-ddc062ce177ca591958b0d6bdf4c1b616899a340.zip
RTC 3346: Allow SPless control of ISteps within Hostboot
- initial commit - add splesscommand and splessstatus objects - factoring - findTaskInfo, ExtTaskInfo structs - doxygen cleanup - unit tests - cleanup, final - review fixes - take out splesscommand and splessstatus classes - 2nd round of review changes Change-Id: I6dce18072b5464a4b8c34e5f4ff639e38afa53d0 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/245 Tested-by: Jenkins Server Reviewed-by: Mark W. Wenning <wenning@us.ibm.com>
Diffstat (limited to 'src/usr/initservice/extinitsvc/extinitsvc.C')
-rw-r--r--src/usr/initservice/extinitsvc/extinitsvc.C381
1 files changed, 198 insertions, 183 deletions
diff --git a/src/usr/initservice/extinitsvc/extinitsvc.C b/src/usr/initservice/extinitsvc/extinitsvc.C
index 886176375..b5ab6b64e 100644
--- a/src/usr/initservice/extinitsvc/extinitsvc.C
+++ b/src/usr/initservice/extinitsvc/extinitsvc.C
@@ -29,20 +29,20 @@
*
*/
-#include <kernel/console.H>
-#include <vfs/vfs.H>
-#include <sys/task.h>
-#include <sys/sync.h>
-#include <sys/misc.h>
-#include <sys/time.h>
-#include <usr/cxxtest/TestSuite.H>
+#include <kernel/console.H>
+#include <vfs/vfs.H>
+#include <sys/task.h>
+#include <sys/sync.h>
+#include <sys/misc.h>
+#include <sys/time.h>
+#include <usr/cxxtest/TestSuite.H>
-#include <trace/interface.H>
-#include <errl/errlentry.H>
-#include <initservice/taskargs.H> // task entry routine
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <initservice/taskargs.H> // task entry routine
-#include "extinitsvc.H"
-#include "extinitsvctasks.H"
+#include "extinitsvc.H"
+#include "extinitsvctasks.H"
namespace INITSERVICE
@@ -50,62 +50,21 @@ namespace INITSERVICE
extern trace_desc_t *g_trac_initsvc;
+
/**
- * @brief _start() - task entry point for this module
- *
- * @parms[in,out] - pointer to TaskArgs struct
- *
+ * @brief set up _start() task entry procedure using the macro in taskargs.H
*/
-extern "C"
-void _start( void *io_pArgs )
-{
- TaskArgs::TaskArgs *pTaskArgs =
- reinterpret_cast<TaskArgs::TaskArgs *>(io_pArgs);
-
- // initialize the extended modules in Hostboot.
- ExtInitSvc::getTheInstance().init( io_pArgs );
-
- if ( pTaskArgs )
- {
- pTaskArgs->waitChildSync();
- }
-
- task_end();
-}
-
-
-
-/******************************************************************************/
-// ExtInitSvc::getTheInstance return the only instance
-/******************************************************************************/
-ExtInitSvc& ExtInitSvc::getTheInstance()
-{
- return Singleton<ExtInitSvc>::instance();
-}
-
-/******************************************************************************/
-// ExtInitSvc::ExtInitSvc constructor
-/******************************************************************************/
-ExtInitSvc::ExtInitSvc()
-{
-
-}
-
-/******************************************************************************/
-// ExtInitSvc::~ExtInitSvc destructor
-/******************************************************************************/
-ExtInitSvc::~ExtInitSvc()
-{
-
-}
+TASK_ENTRY_MACRO( ExtInitSvc::getTheInstance().init );
void ExtInitSvc::init( void *i_ptr )
{
- errlHndl_t errl = NULL; // steps will return an error handle if failure
- uint64_t nextTask = 0;
- const TaskInfo *ptask = NULL;
- TaskArgs::TaskArgs args;
+ errlHndl_t l_errl = NULL;
+ uint64_t l_task = 0;
+ const TaskInfo *l_ptask = NULL;
+ TaskArgs::TaskArgs l_args;
+ uint64_t l_childrc = 0;
+
TRACFCOMP( g_trac_initsvc,
"Extended Initialization Service is starting." );
@@ -113,165 +72,207 @@ void ExtInitSvc::init( void *i_ptr )
// ----------------------------------------------------------------
// loop through the task list and start up any tasks necessary
// ----------------------------------------------------------------
- for ( nextTask=0;
- nextTask<MAX_EXT_TASKS;
- nextTask++ )
+ for ( l_task=0;
+ l_task<INITSERVICE::MAX_EXT_TASKS;
+ l_task++ )
{
// make a local copy of the extended image task
- ptask = &(g_exttaskinfolist[nextTask]);
- if ( ptask->taskflags.task_type == END_TASK_LIST )
+ l_ptask = &(g_exttaskinfolist[l_task]);
+ if ( l_ptask->taskflags.task_type == END_TASK_LIST )
{
TRACDCOMP( g_trac_initsvc,
"End of ExtInitSvc task list." );
break;
}
- args.clear(); // clear args for next task
-
- // dispatch tasks...
- switch ( ptask->taskflags.task_type)
- {
- case NONE:
- // task is a place holder, skip
- TRACDBIN( g_trac_initsvc,
- "task_type=NONE : ",
- ptask->taskname,
- strlen(ptask->taskname) );
- break;
- case INIT_TASK:
- TRACDBIN( g_trac_initsvc,
- "task_type==INIT_TASK : ",
- ptask->taskname,
- strlen(ptask->taskname) );
- errl = VFS::module_load( ptask->taskname );
- break;
-
- case START_TASK: // call _init(), _start(), stay resident
- TRACDBIN( g_trac_initsvc,
- "task_type=START_TASK : ",
- ptask->taskname,
- strlen(ptask->taskname) );
- errl = InitService::getTheInstance().startTask( ptask,
- &args );
- break;
-
- case START_FN:
- TRACDCOMP( g_trac_initsvc,
- "task_type==START_FN : %p",
- ptask->taskfn );
- errl = InitService::getTheInstance().executeFn( ptask,
- &args );
- // $$TODO
- break;
- case BARRIER:
- TRACDCOMP( g_trac_initsvc,
- "task_type==BARRIER" );
- // $$TODO
- break;
+ l_args.clear();
- case UNINIT_TASK:
- TRACDBIN( g_trac_initsvc,
- "task_type=UNINIT_TASK : ",
- ptask->taskname,
- strlen(ptask->taskname) );
- errl = VFS::module_unload( ptask->taskname );
- break;
+ // dispatch the task
+ l_errl = InitService::getTheInstance().dispatchTask( l_ptask,
+ &l_args );
- default:
- TRACDCOMP( g_trac_initsvc,
- "Invalid task_type: %d",
- ptask->taskflags.task_type );
- /*@ errorlog tag
- * @errortype ERRL_SEV_CRITICAL_SYS_TERM
- * @moduleid START_EXTINITSVC_ERRL_ID
- * @reasoncode INVALID_TASK_TYPE
- * @userdata1 task_type value
- * @userdata2 0
- *
- * @devdesc Extended Initialization Service found an invalid
- * Task Type in the task list.
- * The module id will identify the task.
- * task_type value will be the invalid type.
- */
- errl = new ERRORLOG::ErrlEntry(
- ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity
- START_EXTINITSVC_ERRL_ID, // moduleid
- INVALID_TASK_TYPE, // reason Code
- 0, // user1 = tidrc
- 0 );
+ // process errorlogs returned from the task that was launched
+ if ( l_errl )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "ERROR: dispatching task, errlog=0x%p",
+ l_errl );
+ // break out of loop with error.
break;
- } // endswitch
+ }
- // report an error
- InitService::getTheInstance().reportError( errl );
+ // 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 ( args.getReturnCode() != TASKARGS_UNDEFINED64 )
+ if ( l_errl )
{
TRACFCOMP( g_trac_initsvc,
- ERR_MRK "ExtInitSvc TaskArgs returned 0x%llx, errlog=%p",
- args.getReturnCode(),
- args.getErrorLog()
- );
+ " Child task returned 0x%llx, errlog=0x%p",
+ l_childrc,
+ l_errl );
+ // 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 != TASKARGS_UNDEFINED64 )
+ && ( l_childrc != 0 )
+ )
+ {
+ TRACFCOMP( g_trac_initsvc,
+ "Child task returned 0x%llx, no errlog",
+ l_childrc );
+
+ /*@ errorlog tag
+ * @errortype ERRL_SEV_CRITICAL_SYS_TERM
+ * @moduleid see task list
+ * @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,
+ l_ptask->taskflags.module_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.
+ TRACFCOMP( g_trac_initsvc,
+ "ERROR: extra errorlog found: %p",
+ l_errl );
+ errlCommit( l_errl );
+ assert( 0 );
+ }
TRACFCOMP( g_trac_initsvc,
EXIT_MRK "ExtInitSvc finished.");
+
+
// =====================================================================
// ----- Unit Tests -------------------------------------------------
// =====================================================================
/**
- * @note run all the unit tests after we finish the rest
- * there are 2 images generated in the build:
+ * @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 -1,
* no module present. This is OK.
*
+ * @todo can we call call module_load() to see if libcxxtest.so exists?
+ * ask Doug or Patrick
+ *
*/
- // Pass it a set of args so we can wait on the barrier
- // This is a bit wasteful since it is always allocated; we need a
- // system call to check if a module exists.
- TaskArgs::TaskArgs cxxtestargs; // create a new one for cxxtest
- cxxtestargs.clear(); // clear it
-
- TRACFCOMP( g_trac_initsvc,
- ENTER_MRK " "); // leave whitespace in trace
- TRACDBIN( g_trac_initsvc,
- ENTER_MRK "Run Unit Tests (if libcxxtests.so is present): ",
- CXXTEST_TASK.taskname,
- strlen(CXXTEST_TASK.taskname) );
-
- errl = InitService::getTheInstance().startTask( &CXXTEST_TASK,
- &cxxtestargs );
-
- // check the returncode and errorlog in the returned args
- if ( ( cxxtestargs.getReturnCode() != TASKARGS_UNDEFINED64 )
- || ( cxxtestargs.getErrorLog() != NULL )
- )
+ // add a do-while loop so there is only one return at the bottom....
+ do
{
- TRACFCOMP( g_trac_initsvc,
- ERR_MRK "CxxTests returned an error 0x%lx and an errorlog %p",
- cxxtestargs.getReturnCode(),
- cxxtestargs.getErrorLog()
- );
- // report an error
- errlHndl_t childerrl = cxxtestargs.getErrorLog();
- InitService::getTheInstance().reportError( childerrl );
- }
+ // 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;
+
+ l_cxxtestargs.clear();
+
+ TRACDCOMP( g_trac_initsvc,
+ ENTER_MRK "Run Unit Tests (if libcxxtests.so is present): %s",
+ l_pcxxtask->taskname );
+
+ 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 );
+ break; // ERROR, break out of do-while.
+ }
- TRACDCOMP( g_trac_initsvc,
- EXIT_MRK "Unit Tests finished.");
- TRACFCOMP( g_trac_initsvc,
- EXIT_MRK " "); // leave whitespace in trace
+ // 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 );
+ }
+ 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 != TASKARGS_UNDEFINED64 )
+ && ( 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 see task list
+ * @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,
+ l_pcxxtask->taskflags.module_id,
+ INITSERVICE::CXXTEST_FAILED_NO_ERRLOG,
+ l_cxxchildrc,
+ 0 );
+ errlCommit( l_cxxerrl );
+ } // end if
+ } // end else
+
+ } while(0); // end do-while
- // Shutdown all CPUs
+ // =====================================================================
+ // ----- Shutdown all CPUs -----------------------------------------
+ // =====================================================================
uint64_t l_shutdownStatus = SHUTDOWN_STATUS_GOOD;
if (CxxTest::g_FailedTests)
@@ -286,4 +287,18 @@ void ExtInitSvc::init( void *i_ptr )
}
+ExtInitSvc& ExtInitSvc::getTheInstance()
+{
+ return Singleton<ExtInitSvc>::instance();
+}
+
+
+ExtInitSvc::ExtInitSvc()
+{ }
+
+
+ExtInitSvc::~ExtInitSvc()
+{ }
+
+
} // namespace
OpenPOWER on IntegriCloud