summaryrefslogtreecommitdiffstats
path: root/src/usr/initservice/baseinitsvc
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/initservice/baseinitsvc')
-rw-r--r--src/usr/initservice/baseinitsvc/initservice.C233
-rw-r--r--src/usr/initservice/baseinitsvc/initservice.H220
-rw-r--r--src/usr/initservice/baseinitsvc/initservicetaskentry.C49
-rw-r--r--src/usr/initservice/baseinitsvc/initsvctasks.H85
-rw-r--r--src/usr/initservice/baseinitsvc/makefile7
5 files changed, 594 insertions, 0 deletions
diff --git a/src/usr/initservice/baseinitsvc/initservice.C b/src/usr/initservice/baseinitsvc/initservice.C
new file mode 100644
index 000000000..0c3617023
--- /dev/null
+++ b/src/usr/initservice/baseinitsvc/initservice.C
@@ -0,0 +1,233 @@
+/**
+ * @file initservice.C
+ *
+ * Implements Initialization Service for Host boot.
+ * See initservice.H for details
+ *
+ */
+
+#include <kernel/console.H>
+#include <sys/vfs.h>
+#include <sys/task.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <sys/sync.h>
+
+
+#include "initservice.H"
+#include "initsvctasks.H"
+
+
+
+namespace INITSERVICE
+{
+
+trace_desc_t *g_trac_initsvc = NULL;
+TRAC_INIT(&g_trac_initsvc, "INITSERVICE", 4096);
+
+
+/******************************************************************************/
+// InitService::getTheInstance return the only instance
+/******************************************************************************/
+InitService& InitService::getTheInstance()
+{
+ return Singleton<InitService>::instance();
+}
+
+/******************************************************************************/
+// InitService::Initservice constructor
+/******************************************************************************/
+InitService::InitService()
+{
+
+}
+
+/******************************************************************************/
+// InitService::~InitService destructor
+/******************************************************************************/
+InitService::~InitService()
+{
+
+}
+
+/**
+ * @todo mechanism to set taskcommand in TaskArgs struct
+ * @todo check taskreturncode inside of TaskArgs
+ * @todo test errorlog inside of Taskargs
+ */
+errlHndl_t InitService::startTask( const TaskInfo *i_ptask,
+ TaskArgs::TaskArgs *io_pargs,
+ errlHndl_t &io_rerrl ) const
+{
+ tid_t tidrc = 0;
+
+ assert(i_ptask->taskflags.task_type == START_TASK);
+
+ tidrc = task_exec( i_ptask->taskname, io_pargs ); // launch the child
+
+ if ( io_pargs )
+ {
+ io_pargs->waitParentSync(); // sync up childtask
+ }
+
+ if ( static_cast<int16_t>(tidrc) < 0 )
+ {
+ io_rerrl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity
+ i_ptask->taskflags.module_id, // moduleid
+ INITSERVICE::START_TASK_FAILED, // reason Code
+ tidrc, // user1 = tidrc
+ 0
+ );
+ TRACDBIN( g_trac_initsvc,
+ "ERROR starting task:",
+ i_ptask->taskname,
+ strlen(i_ptask->taskname) );
+ TRACDCOMP( g_trac_initsvc,
+ "tidrc=%d, errlog p = %p" ,
+ (int16_t)tidrc, io_rerrl );
+
+ } // endif tidrc
+ else
+ {
+ TRACDBIN( g_trac_initsvc,
+ "Task finished OK :",
+ i_ptask->taskname,
+ strlen(i_ptask->taskname) );
+ TRACDCOMP( g_trac_initsvc,
+ "task number %d, errlog p = %p",
+ tidrc, io_rerrl );
+ }
+
+ return io_rerrl;
+}
+
+
+void InitService::reportError(errlHndl_t &io_rerrl ) const
+{
+
+ if ( io_rerrl == NULL )
+ {
+ // this is OK, do nothing
+ }
+ else
+ {
+
+ TRACDCOMP( g_trac_initsvc,
+ "Committing the error log %p.",
+ io_rerrl
+ );
+
+ errlCommit( io_rerrl );
+
+ }
+
+ return;
+}
+
+
+/**
+ * @todo this will make a system call to post the error code.
+ */
+void InitService::setProgressCode( uint64_t &i_progresscode ) const
+{
+
+ // do nothing for now
+}
+
+
+/**
+ * @note For task_type = NONE case, I'm assuming that trace will not crash
+ * if we have a NULL taskname string, printing it is useful for debug.
+ */
+void InitService::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;
+
+ TRACFCOMP( g_trac_initsvc,
+ ENTER_MRK "Initialization Service is starting." );
+
+ // ----------------------------------------------------------------
+ // loop through the task list and start up any tasks necessary
+ // ----------------------------------------------------------------
+
+ for ( nextTask=0;
+ nextTask<INITSERVICE::MAX_TASKS;
+ nextTask++ )
+ {
+ // make a local copy of the base image task
+ ptask = &(iv_taskinfolist[nextTask]);
+ if ( ptask->taskflags.task_type == END_TASK_LIST )
+ {
+ TRACDCOMP( g_trac_initsvc,
+ "End of Initialization Service task list.\n" );
+ break;
+ }
+
+ // 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 START_TASK:
+ TRACDBIN( g_trac_initsvc,
+ "task_type==START_TASK",
+ ptask->taskname,
+ strlen( ptask->taskname) );
+ errl = startTask( ptask, // task struct
+ &args, // args
+ errl ); // errlog
+ break;
+ case START_FN:
+ TRACDCOMP( g_trac_initsvc,
+ "task_type==START_FN : %p",
+ ptask->taskfn );
+ // $$TODO
+ break;
+ case BARRIER:
+ TRACDCOMP( g_trac_initsvc,
+ "task_type==BARRIER" );
+ // $$TODO
+ break;
+
+ default:
+ TRACDCOMP( g_trac_initsvc,
+ "Invalid task_type %d: ",
+ ptask->taskflags.task_type );
+ errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, // severity
+ BASE_INITSVC_ERRL_ID, // moduleid
+ INVALID_TASK_TYPE, // reason Code
+ 0, // user1 = tidrc
+ 0 );
+ break;
+
+ } // endswitch
+
+ // report an error
+ reportError( errl );
+
+ } // endfor
+
+ // die if we drop out with an error
+ assert( errl == NULL);
+
+
+ TRACFCOMP( g_trac_initsvc,
+ EXIT_MRK "Initilization Service finished.");
+
+ // return to _start(), which may end the task or die.
+ return;
+}
+
+
+} // namespace INITSERVICE
diff --git a/src/usr/initservice/baseinitsvc/initservice.H b/src/usr/initservice/baseinitsvc/initservice.H
new file mode 100644
index 000000000..dd0a7df32
--- /dev/null
+++ b/src/usr/initservice/baseinitsvc/initservice.H
@@ -0,0 +1,220 @@
+#ifndef __BASEINITSVC_INITSERVICE_H
+#define __BASEINITSVC_INITSERVICE_H
+/**
+ * @file initservice.H
+ *
+ * - Manage high-level host boot IPL flow
+ * - Perform can-continue processing
+ * - Perform automatic and manual Istep execution
+ * - Handle flow errors as appropriate.
+ *
+ */
+
+/**
+ * High-level todo list
+ *
+ * @todo SP3: move startTask() and reportError() to private
+ * @todo SP3: add (NULL) detection to printk
+ * @@todo Add more macros to trace, discuss with Andrew and Nick
+ */
+
+/******************************************************************************/
+// Includes
+/******************************************************************************/
+#include <stdint.h>
+#include <util/singleton.H>
+#include <sys/vfs.h> // VFS_MODULE_NAME_MAX
+
+#include <trace/interface.H>
+#include <initservice/taskargs.H>
+#include <errl/errlentry.H>
+#include <initservice/initsvcreasoncodes.H>
+
+
+namespace INITSERVICE
+{
+
+/******************************************************************************/
+// Globals/Constants
+/******************************************************************************/
+
+
+/******************************************************************************/
+// Typedef/Enumerations
+/******************************************************************************/
+
+/**
+ * @enum TaskType
+ * - NONE == placeholder, no task
+ * - START_TASK == task with _start() function entry point
+ * - START_FN == task with function pointer entry point
+ * - BARRIER == set barrier for next N tasks.
+ * - STOP_TASK == Execute the destructor on the task in extended image.
+ * ( not implemented yet)
+ * - END_TASK_LIST == last entry in the task list.
+ */
+enum TaskType
+{
+ UNDEFINED_TT = 0,
+ NONE,
+ START_TASK,
+ START_FN,
+ BARRIER,
+ STOP_TASK,
+ END_TASK_LIST,
+};
+/**
+ * @enum ModuleType
+ * - BASE_IMAGE == module in the base image
+ * - EXT_IMAGE == module in the extended image
+ */
+enum ModuleType
+{
+ UNDEFINED_MT = 0,
+ BASE_IMAGE,
+ EXT_IMAGE,
+};
+
+
+/**
+ * @struct TaskFlags
+ *
+ * - run _start() function on start
+ * - module type, BASE_MODULE or EXT_MODULE
+ * - module_id for errorlog if task fails
+ *
+ * @todo revisit these flags in sprint3
+ */
+struct TaskFlags
+{
+ TaskType task_type; // this is a task, run _start() function
+ ModuleType module_type; // BASE_IMAGE or EXT_IMAGE
+ InitServiceModuleID module_id; // module id for errorlog
+};
+
+/**
+ * @struct _TaskInfo
+ *
+ * Holds information on each task in the system.
+ * - taskname
+ * - execution flags, see TaskFlags above
+ *
+ */
+struct TaskInfo
+{
+ const char taskname[VFS_MODULE_NAME_MAX];
+ void (*taskfn)(void *ptr);
+ const TaskFlags taskflags;
+
+};
+
+
+/******************************************************************************/
+// InitService Class
+/******************************************************************************/
+
+// Singleton definition
+class InitService;
+typedef Singleton<InitService> theInitService;
+
+/**
+ * @class InitService Singleton Class
+ *
+ * This class is launched by _start() (see initservicetaskentry.C),
+ * which is launched by the kernel (init_main.C).
+ *
+ * Once started, it handles the rest of HostBoot Initialization.
+ *
+ * @returns none
+ */
+class InitService
+{
+
+public:
+
+ friend class InitServiceTest;
+
+ /**
+ * @brief Get singleton instance of this class.
+ *
+ * @return the (one and only) instance of InitService
+ */
+ static InitService& 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 .
+ */
+ void init( void *i_args);
+
+ /**
+ * @todo InitServiceTest should be able to find protected functions.
+ */
+ // $$protected:
+
+ /**
+ * @brief start a task
+ *
+ * @param[in] i_ptask pointer to a TaskInfo struct
+ * @param[in] io_pargs pointer to a TaskArgs struct, or NULL
+ * @param[inout] io_rerrl reference to an errorlog handle.
+ * errorlog will be filled out if error,
+ * otherwise untouched.
+ *
+ * @return NULL if success, errorlog handle for failure
+ *
+ */
+ errlHndl_t startTask( const TaskInfo *i_ptask,
+ TaskArgs::TaskArgs *i_pargs,
+ errlHndl_t &io_rerrl ) const;
+
+
+ /**
+ * @brief report Error to the system.
+ *
+ * @param[in] io_rerrl - errlHndl_t pointer to a filled-out error entry
+ * errorlog will be committed, errorlog
+ * will be deleted, and pointer will be
+ * set to NULL on exit
+ *
+ * @return nothing
+ */
+ void reportError( errlHndl_t &io_rerrl) const;
+
+
+ /**
+ * @brief set progress code for task.
+ *
+ * @param[in] i_progresscode - 64-bit progress code.
+ *
+ * @return nothing
+ *
+ */
+ void setProgressCode( uint64_t &i_progresscode ) const;
+
+
+
+protected:
+
+ /**
+ * @brief Constructor for the InitService object.
+ */
+ InitService();
+
+ /**
+ * @brief Destructor for the InitService object.
+ */
+ ~InitService();
+
+
+private:
+
+
+}; // class InitService
+
+} // namespace INITSERVICE
+
+#endif
diff --git a/src/usr/initservice/baseinitsvc/initservicetaskentry.C b/src/usr/initservice/baseinitsvc/initservicetaskentry.C
new file mode 100644
index 000000000..62d531c07
--- /dev/null
+++ b/src/usr/initservice/baseinitsvc/initservicetaskentry.C
@@ -0,0 +1,49 @@
+/**
+ * @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 <kernel/console.H>
+#include <sys/vfs.h>
+#include <sys/task.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+
+#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." );
+
+
+ // create an instance of InitService
+ //InitService::InitService& is = InitService::getTheInstance();
+
+ // initialize the base modules in Hostboot.
+ InitService::getTheInstance().init( ptr );
+
+ TRACFCOMP( g_trac_initsvc,
+ EXIT_MRK "return from Initialization Service module." );
+
+ task_end();
+}
+
+} // INITSERVICE
diff --git a/src/usr/initservice/baseinitsvc/initsvctasks.H b/src/usr/initservice/baseinitsvc/initsvctasks.H
new file mode 100644
index 000000000..ae3362d31
--- /dev/null
+++ b/src/usr/initservice/baseinitsvc/initsvctasks.H
@@ -0,0 +1,85 @@
+/**
+ * @file initsvctasks.H
+ *
+ * TaskInfo structs for each task that will run.
+ */
+
+#ifndef __INIT_SVC_TASKS_H
+#define __INIT_SVC_TASKS_H
+
+#include <initservice/initsvcreasoncodes.H>
+#include "initservice.H"
+
+namespace INITSERVICE
+{
+
+const uint64_t MAX_TASKS = 10;
+
+const TaskInfo iv_taskinfolist[] = {
+
+ /**
+ * @brief Errorlog Task
+ */
+ {
+ "liberrl.so" , // taskname
+ NULL, // no ptr to fn
+ {
+ NONE, // don't start
+ BASE_IMAGE, // Base Module
+ START_ERRL_ERRL_ID, // module id for errorlog
+
+ }
+ },
+
+
+ /**
+ * @brief PNOR Driver Task
+ */
+ {
+ "libpnordd.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ NONE, // don't start
+ BASE_IMAGE, // Base Module
+ START_PNORDD_ERRL_ID, // module id for errorlog
+ }
+ },
+
+ // ----- Extended Image -----------------------------------------------------
+
+ /**
+ * @brief extinitsvc, initializes extended module area
+ */
+ {
+ "libextinitsvc.so" , // taskname
+ NULL, // no pointer to fn
+ {
+ START_TASK, // don't start
+ EXT_IMAGE, // Ext Module
+ START_EXTINITSVC_ERRL_ID, // module id for errorlog
+ }
+ },
+
+
+ // ---------------------------------------------------------------
+ // ----- END OF LIST!!! ---------------------------------------
+ // ---------------------------------------------------------------
+
+ /**
+ * @brief last task in the list
+ */
+ {
+ "end" , // dummy string
+ NULL, // pointer to fn
+ {
+ END_TASK_LIST, // end of list
+ UNDEFINED_MT, // dummy module type
+ UNDEFINED_MODULE_ERRL_ID, // dummy errorlog
+ }
+ },
+
+};
+
+
+}; // namespace INITSERVICE
+#endif // __INIT_SVC_TASKS_H
diff --git a/src/usr/initservice/baseinitsvc/makefile b/src/usr/initservice/baseinitsvc/makefile
new file mode 100644
index 000000000..45b83ef7d
--- /dev/null
+++ b/src/usr/initservice/baseinitsvc/makefile
@@ -0,0 +1,7 @@
+ROOTPATH = ../../../..
+MODULE = initservice
+
+OBJS = initservice.o \
+ initservicetaskentry.o
+
+include ${ROOTPATH}/config.mk
OpenPOWER on IntegriCloud