diff options
author | Mark Wenning <wenning@us.ibm.com> | 2011-06-06 14:07:51 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-06-21 17:54:41 -0500 |
commit | a2fbc8cb2e51821331f3ba8d920dddf8ab0fb96d (patch) | |
tree | a8f2b80dd70837255c2012f86917cb1f9e8c415a /src/usr | |
parent | a1450c913cb7864234ae1adea8aaffe561a627d6 (diff) | |
download | blackbird-hostboot-a2fbc8cb2e51821331f3ba8d920dddf8ab0fb96d.tar.gz blackbird-hostboot-a2fbc8cb2e51821331f3ba8d920dddf8ab0fb96d.zip |
Initialization Service (Flow Control)
- save off changes before switch branch
- rename to get rid of '_' in filenames.
- split into separate files
- adding errorlogs, saved off so CC guru could work
- fix problem in vfs_main where we would crash if there is no _start in launched task.
- refactor
- fix problems with coding guidelines
- add testcases for startTask and reportError
- add fixes from code review
Change-Id: I2ae34cb6097c466d4f6d0e41b4b32c2eba47e9df
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/145
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/example/example.C | 7 | ||||
-rw-r--r-- | src/usr/initservice/initservice.C | 418 | ||||
-rw-r--r-- | src/usr/initservice/initservice.H | 448 | ||||
-rw-r--r-- | src/usr/initservice/initservicetaskentry.C | 67 | ||||
-rw-r--r-- | src/usr/initservice/initservicevfs1.C | 69 | ||||
-rw-r--r-- | src/usr/initservice/initservicevfs2.C | 176 | ||||
-rw-r--r-- | src/usr/initservice/initsvctasks.H | 79 | ||||
-rw-r--r-- | src/usr/initservice/makefile | 11 | ||||
-rw-r--r-- | src/usr/initservice/test/initservicetest.H | 237 | ||||
-rw-r--r-- | src/usr/initservice/test/makefile | 6 | ||||
-rw-r--r-- | src/usr/makefile | 2 |
11 files changed, 1517 insertions, 3 deletions
diff --git a/src/usr/example/example.C b/src/usr/example/example.C index 632eb6882..290d8abc4 100644 --- a/src/usr/example/example.C +++ b/src/usr/example/example.C @@ -12,9 +12,12 @@ trace_desc_t *g_trac_test = NULL; TRAC_INIT(&g_trac_test, "EXAMPLE", 4096); extern "C" -void _start(void*) +void _start(void *ptr) { - printk("Executing example module.\n"); + /** + * @todo fix printk to accept (NULL) + */ + printk( "Executing Example module, arg=%s\n", ( (ptr==NULL) ? "(NULL)" : (char*)ptr ) ); task_end(); } diff --git a/src/usr/initservice/initservice.C b/src/usr/initservice/initservice.C new file mode 100644 index 000000000..6fe759ed0 --- /dev/null +++ b/src/usr/initservice/initservice.C @@ -0,0 +1,418 @@ +/** + * @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 "initservice.H" + + + +namespace INITSERVICE +{ + +// always set up a trace buffer +trace_desc_t *g_trac_errl = NULL; +TRAC_INIT(&g_trac_errl, "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 failure to start a task is considered FATAL, revisit later. + */ + +tid_t InitService::startTask( const TaskInfo &i_rtask, errlHndl_t &io_rerrl ) const +{ + tid_t tidrc = 0; + + + if ( i_rtask.taskflags.startflag ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "startflag is on, starting task...\n" ); + printk( "startflag is on, starting task %s\n", i_rtask.taskname ); + tidrc = task_exec( i_rtask.taskname, NULL ); + if ( (int16_t)tidrc < 0 ) + { + + io_rerrl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, + i_rtask.taskflags.module_id, + INITSERVICE::START_TASK_FAILED, + 0, + 0 + ); + TRACFCOMP(INITSERVICE::g_trac_errl, "ERROR %d starting task, errlog p = %p\n", + tidrc, io_rerrl ); + + } // endif tidrc + else + { + TRACFCOMP(INITSERVICE::g_trac_errl, "task number %d started. errlog p = %p\n", + tidrc, io_rerrl ); + } + } + + return tidrc; +} + +/** + * @todo commit the error log here, and then delete it + * @todo dump some or all of the error log so we know who died. + * + */ +void InitService::reportError(errlHndl_t &io_rerrl ) const +{ + + TRACFCOMP(INITSERVICE::g_trac_errl, "reportError!!!"); + + if ( io_rerrl == NULL ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "ERROR: reportError was passed a NULL errorlog handle.\n"); + } + else + { + + TRACFCOMP(INITSERVICE::g_trac_errl, + "TODO: commit the error log. delete errl and set to NULL for now.\n" + ); + /** + + * @todo cannot commit an error log until the errorlog service is started up. + * do some checking here + * @todo commit the error log here, note that the commit should delete the log and + * set the handle to NULL + */ + + delete( io_rerrl ); + io_rerrl = NULL; // $$TODO set errl back to NULL for now so all the tasks run + } + + return; +} + + +void InitService::start( void *i_ptr ) +{ + errlHndl_t errl = NULL; // steps will return an error handle if failure + + TRACFCOMP(INITSERVICE::g_trac_errl, "+++++ Initialization Service is starting." ); + + // ---------------------------------------------------------------- + // Start up any tasks necessary in the base modules... + // ---------------------------------------------------------------- + do { + + // startTrace + TRACFCOMP(INITSERVICE::g_trac_errl, "running startTrace..."); + startTrace( errl ); + if ( errl ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "startTrace failed"); + break; // break out and report error + } + + // startErrorLog + TRACFCOMP(INITSERVICE::g_trac_errl, "running startErrLog..."); + startErrLog( errl ); + if ( errl ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "startErrLog failed"); + break; // break out and report error + } + + // startXSCOM + TRACFCOMP(INITSERVICE::g_trac_errl, "running startXSCOM..."); + startXSCOMDD( errl ); + if ( errl ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "startSCOMDD failed"); + break; // break out and report error + } + + // startPNOR + TRACFCOMP( INITSERVICE::g_trac_errl, "running startPNORDD"); + startPNORDD( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startPNOR failed"); + break; // break out and report error + } + + // startVFS_2 + TRACFCOMP( INITSERVICE::g_trac_errl, "running startVFS_2"); + startVFS_2( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startVFS_2 failed"); + break; // break out and report error + } + + } while( false ); + + + /** + * @todo stop here now if someone posted an error log, revisit this + * when we know what to do. + */ + if ( errl ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "Errorlog posted, commit and die."); + reportError( errl ); + } + + assert( errl == NULL ); + + + // ---------------------------------------------------------------- + // start running the extended modules + // ---------------------------------------------------------------- + do { + // startTargetting + TRACFCOMP( INITSERVICE::g_trac_errl, "running startTargetting"); + startTargetting( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startTargetting failed"); + + break; // break out and report error + } + + // getMasterChipTarget + TRACFCOMP( INITSERVICE::g_trac_errl, "running getMasterChipTarget"); + getMasterChipTarget( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "getMasterChipTarget failed"); + + break; // break out and report error + } + + // startMailboxDD + TRACFCOMP( INITSERVICE::g_trac_errl, "running startMailboxDD"); + startMailboxDD( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startMailboxDD failed"); + + break; // break out and report error + } + + // startSPComm + TRACFCOMP( INITSERVICE::g_trac_errl, "running startSPComm"); + startSPComm( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startSPComm failed"); + + break; // break out and report error + } + + // enableStreamingTrace + TRACFCOMP( INITSERVICE::g_trac_errl, "running enableStreamingTrace"); + enableStreamingTrace( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "enableStreamingTrace failed"); + + break; // break out and report error + } + + // startProgressCodes + TRACFCOMP( INITSERVICE::g_trac_errl, "running startProgressCodes"); + startProgressCodes( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startProgressCodes failed"); + + break; // break out and report error + } + + // startFSIDD + TRACFCOMP( INITSERVICE::g_trac_errl, "running startFSIDD"); + startFSIDD( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startFSIDD failed"); + + break; // break out and report error + } + + // setupSlaveLinks + TRACFCOMP( INITSERVICE::g_trac_errl, "running setupSlaveLinks"); + setupSlaveLinks( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "setupSlaveLinks failed"); + + break; // break out and report error + } + + // startFSISCOM + TRACFCOMP( INITSERVICE::g_trac_errl, "running startFSISCOM"); + startFSISCOM( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startFSISCOM failed"); + + break; // break out and report error + } + + // startFSII2C + TRACFCOMP( INITSERVICE::g_trac_errl, "running startFSII2C"); + startFSII2C( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startFSII2C failed"); + + break; // break out and report error + } + + // startHWP + TRACFCOMP( INITSERVICE::g_trac_errl, "running startHWP"); + startHWPF( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "startHWP failed"); + + break; // break out and report error + } + + // readMaxConfigfromPNOR + TRACFCOMP( INITSERVICE::g_trac_errl, "running readMaxConfigfromPNOR"); + readMaxConfigfromPNOR( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "readMaxConfigfromPNOR failed"); + + break; // break out and report error + } + + // applyPresenceDetect + TRACFCOMP( INITSERVICE::g_trac_errl, "running applyPresenceDetect"); + applyPresenceDetect( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "applyPresenceDetect failed"); + + break; // break out and report error + } + + // applyPartialBad + TRACFCOMP( INITSERVICE::g_trac_errl, "running applyPartialBad"); + applyPartialBad( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "applyPartialBad failed"); + + break; // break out and report error + } + + // applyGard + TRACFCOMP( INITSERVICE::g_trac_errl, "running applyGard..."); + applyGard( errl ); + if ( errl ) + { + + TRACFCOMP( INITSERVICE::g_trac_errl, "applyGard failed"); + break; // break out and report error + } + + // collectHWIDEC + TRACFCOMP( INITSERVICE::g_trac_errl, "running collectHWIDEC..."); + collectHWIDEC( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "collectHWIDEC failed"); + + break; // break out and report error + } + + // verifyIDEC + TRACFCOMP( INITSERVICE::g_trac_errl, "running verifyIDEC"); + verifyIDEC( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "verifyIDEC failed"); + + break; // break out and report error + } + + // disableWatchDog + TRACFCOMP( INITSERVICE::g_trac_errl, "running disableWatchDog"); + disableWatchDog( errl ); + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "disableWatchDog failed"); + + break; // break out and report error + } + + + } while ( false ); + + + /** + * @todo stop here now if someone posted an error log, revisit this + * when we know what to do. + */ + if ( errl ) + { + TRACFCOMP(INITSERVICE::g_trac_errl, "Errorlog posted, commit and die."); + reportError( errl ); + } + + assert( errl == NULL ); + + + + // executeISteps + TRACFCOMP( INITSERVICE::g_trac_errl, "running executeISteps"); + executeISteps( errl ); + + if ( errl ) + { + TRACFCOMP( INITSERVICE::g_trac_errl, "executeISteps failed"); + reportError( errl ); + assert( errl == NULL ); + } + + + TRACFCOMP( INITSERVICE::g_trac_errl, "+++++ Initilization Service finished. IN THE REAL CODE WE WILL NEVER GET HERE"); + + // return to _start(), which may end the task or die. + return; +} + + +} // namespace INITSERVICE diff --git a/src/usr/initservice/initservice.H b/src/usr/initservice/initservice.H new file mode 100644 index 000000000..0e880de1a --- /dev/null +++ b/src/usr/initservice/initservice.H @@ -0,0 +1,448 @@ +/** + * @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: remove ADUDD, not used + * @todo SP3: add (NULL) detection to printk + * @todo SP3: reevaluate all trace calls - TRACF are field traces, - ERR_MRK etc macros + * @todo SP3: change InitService::start() to init(), document this as a standard. + * @todo SP3: initservice/makefile remove trailing tabs + * @todo SP3: Disable copy CTOR/assignment operator; this would have caught an illegal copy by assignment elsewhere + * @@todo Add more macros to trace, discuss with Andrew and Nick + * + * + */ + +#ifndef __INIT_SERVICE_H +#define __INIT_SERVICE_H + +/******************************************************************************/ +// Includes +/******************************************************************************/ +#include <stdint.h> +#include <util/singleton.H> +#include <sys/vfs.h> // VFS_MODULE_NAME_MAX + +#include <errl/errlentry.H> +#include <initservice/initsvcreasoncodes.H> + +namespace INITSERVICE +{ + +/******************************************************************************/ +// Globals/Constants +/******************************************************************************/ + +/******************************************************************************/ +// Typedef/Enumerations +/******************************************************************************/ +/** + * @enum ModuleType + * - BASE_MODULE == module in the base image + * - EXT_MODULE == module in the extended image + */ +enum ModuleType +{ + BASE_MODULE = 0, + EXT_MODULE, +}; + + +/** + * @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 +{ + bool startflag; // this is a task, run _start() function + ModuleType module_type; // BASE_MODULE_TYPE or EXT_MODULE_TYPE + 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]; + TaskFlags taskflags; + +} PACKED; + + +/******************************************************************************/ +// 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 . + * + * @todo Sprint 3: pass in ptr to errorlog struct? + * @todo document any changes for args + */ + void start( void *i_args); + + /** + * @brief Constructor for the InitService object. + */ + InitService(); + + /** + * @brief Destructor for the InitService object. + */ + ~InitService(); + + /** + * @brief start a task + * + * @param[in] i_rtask reference to a TaskInfo struct + * @param[inout] i_rerrl reference to an errorlog struct. + * struct will be filled out if error, + * otherwise untouched. + * + * @return child id if success, < 0 for failure + * + * @todo return errorlog handle in sprint3 + */ + tid_t startTask( const TaskInfo &i_rtask, errlHndl_t &i_rerrl ) const; + + /** + * @brief report Error to the system. + * + * @param[in] io_errl - 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; + + +private: + + + + /** + * @brief Initialize the Trace module + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startTrace( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the ErrorLog module + * + * * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startErrLog( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the XSCOM Device Driver module + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startXSCOMDD( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the PNOR Device Driver module + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startPNORDD( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the second stage of VFS module + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + + void startVFS_2( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the Targetting DD module + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startTargetting( errlHndl_t &i_rerrl ) const; + + /** + * @brief get the Master Chip Target + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void getMasterChipTarget( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the Mailbox Device Driver + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startMailboxDD( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize SP Communications + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startSPComm( errlHndl_t &i_rerrl ) const; + + /** + * @brief Turn on Streaming Trace, if the PNOR flag is set + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void enableStreamingTrace( errlHndl_t &i_rerrl ) const; + + /** + * @brief Start reporting progress codes. + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startProgressCodes( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize the FSI Device Driver module + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startFSIDD( errlHndl_t &i_rerrl ) const; + + /** + * @brief Set up links to the slaves + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void setupSlaveLinks( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize FSI SCOM + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startFSISCOM( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize FSI I2C + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startFSII2C( errlHndl_t &i_rerrl ) const; + + /** + * @brief Initialize HWP + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void startHWPF( errlHndl_t &i_rerrl ) const; + + /** + * @brief Read Configuration from PNOR + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void readMaxConfigfromPNOR( errlHndl_t &i_rerrl ) const; + + /** + * @brief apply Presence Detect + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void applyPresenceDetect( errlHndl_t &i_rerrl ) const; + + /** + * @brief apply Partial Bad + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void applyPartialBad( errlHndl_t &i_rerrl ) const; + /** + * @brief apply Gard + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void applyGard( errlHndl_t &i_rerrl ) const; + + /** + * @brief Collect HW IDEC info + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void collectHWIDEC( errlHndl_t &i_rerrl ) const; + + /** + * @brief verify the IDEC info + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void verifyIDEC( errlHndl_t &i_rerrl ) const; + + /** + * @brief Disable the HW watchdog + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void disableWatchDog( errlHndl_t &i_rerrl ) const; + + /** + * @brief Execute the IStep module to communicate with SP and run + * the isteps. + * + * @param[in,out] i_rerrl - errorlog handle. + * Success: handle is untouched + * Failure: will point to a filled-out errorlog + * + * @return none + */ + void executeISteps( errlHndl_t &i_rerrl ) const; + + +}; // class InitService + +} // namespace INITSERVICE + +#endif diff --git a/src/usr/initservice/initservicetaskentry.C b/src/usr/initservice/initservicetaskentry.C new file mode 100644 index 000000000..0fb84e00d --- /dev/null +++ b/src/usr/initservice/initservicetaskentry.C @@ -0,0 +1,67 @@ +/** + * @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 +{ + +/** + * @brief task entry routine, called by init_main.C + * + */ + +extern "C" +void _start(void *ptr) +{ + tid_t tidrc = 0; + + printk("===== Executing Initialization Service modules\n" ); + + + // create an instance of InitService + InitService::InitService& is = InitService::getTheInstance(); + + // initialize the base modules in Hostboot. + is.start( ptr ); + + + + // ----- run unit tests and example code, if present ---------------- + /** + * @todo remove this eventually, figure out where to run UnitTests. + */ + printk("===== Executing Unit Tests\n" ); + + // run unit tests if present (i.e. we are running hbicore_test.bin) + tidrc = task_exec("libcxxtest.so", NULL); + + /** + * @todo barrier here to wait for all the tests to finish... + */ + + printk( "===== Done, terminating Initialization service..."); + + /** + * @todo add assert(0) here??? + */ + + + task_end(); +} + +} // INITSERVICE diff --git a/src/usr/initservice/initservicevfs1.C b/src/usr/initservice/initservicevfs1.C new file mode 100644 index 000000000..691fef197 --- /dev/null +++ b/src/usr/initservice/initservicevfs1.C @@ -0,0 +1,69 @@ +/** + * @file initservicevfs1.C + * + * Private functions for VFS1 phase. + */ + +#include <kernel/console.H> +#include <sys/vfs.h> +#include <sys/task.h> +#include <trace/interface.H> + +#include "initservice.H" + +#include "initsvctasks.H" + + +namespace INITSERVICE +{ + +/******************************************************************************/ +// private functions for VFS 1 phase +/******************************************************************************/ + +void InitService::startTrace( errlHndl_t &io_rerrl ) const +{ + + // start up the task + startTask( TASK_TRACE, io_rerrl ); + + return; +} + + +void InitService::startErrLog( errlHndl_t &io_rerrl ) const +{ + + startTask( TASK_ERRORLOG, io_rerrl ); + + return; +} + + +void InitService::startXSCOMDD( errlHndl_t &io_rerrl ) const +{ + + startTask( TASK_XSCOMDD, io_rerrl ); + + return; +} + + +void InitService::startPNORDD( errlHndl_t &io_rerrl ) const +{ + + startTask( TASK_PNORDD, io_rerrl ); + + return; +} + + +void InitService::startVFS_2( errlHndl_t &io_rerrl ) const +{ + + startTask( TASK_VFS_2, io_rerrl ); + + return; +} + +} // namespace INITSERVICE diff --git a/src/usr/initservice/initservicevfs2.C b/src/usr/initservice/initservicevfs2.C new file mode 100644 index 000000000..46c49e988 --- /dev/null +++ b/src/usr/initservice/initservicevfs2.C @@ -0,0 +1,176 @@ +/** + * @file initservicevfs2.C + * + * Private functions for VFS2 phase. + */ + +#include <kernel/console.H> +#include <sys/vfs.h> +#include <sys/task.h> +#include <trace/interface.H> + +#include "initservice.H" + +#include "initsvctasks.H" + + +namespace INITSERVICE +{ + + +/******************************************************************************/ +// private functions for VFS 2 phase +/******************************************************************************/ + + +void InitService::startTargetting( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::getMasterChipTarget( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::startMailboxDD( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::startSPComm( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::enableStreamingTrace( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::startProgressCodes( errlHndl_t &io_rerrl ) const +{ + + return; + +} + + + void InitService::startFSIDD( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::setupSlaveLinks( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::startFSISCOM( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::startFSII2C( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::startHWPF( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::readMaxConfigfromPNOR( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + +void InitService::applyPresenceDetect( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::applyPartialBad( errlHndl_t &io_rerrl ) const +{ + + + return; +} + +void InitService::applyGard( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + +void InitService::collectHWIDEC( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::verifyIDEC( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::disableWatchDog( errlHndl_t &io_rerrl ) const +{ + + + return; +} + + + void InitService::executeISteps( errlHndl_t &io_rerrl ) const +{ + + + return; +} + +} // namespace INITSERVICE diff --git a/src/usr/initservice/initsvctasks.H b/src/usr/initservice/initsvctasks.H new file mode 100644 index 000000000..4f8c48656 --- /dev/null +++ b/src/usr/initservice/initsvctasks.H @@ -0,0 +1,79 @@ +/** + * @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 +{ + + +/** + * @brief Trace Task + */ +const TaskInfo TASK_TRACE = { + "libtrace.so" , // taskname + { false, // don't start + BASE_MODULE, // Base Module + START_TRACE_ID, // module id for errorlog + }, +}; + + +/** + * @brief Errorlog Task + */ +const TaskInfo TASK_ERRORLOG = { + "liberrl.so" , // taskname + { false, // don't start + BASE_MODULE, // Base Module + START_ERRL_ID, // module id for errorlog + + }, +}; + + +/** + * @brief XSCOM Task + */ +const TaskInfo TASK_XSCOMDD = { + "libscom.so" , // taskname + { false, // don't start + BASE_MODULE, // Base Module + START_XSCOMDD_ID, // module id for errorlog + }, +}; + + +/** + * @brief PNOR Driver Task + */ +const TaskInfo TASK_PNORDD = { + "libpnordd.so" , // taskname + { false, // don't start + BASE_MODULE, // Base Module + START_PNORDD_ID, // module id for errorlog + }, +}; + + +/** + * @brief VFS 2 task, initializes extended module area + */ +const TaskInfo TASK_VFS_2 = { + "vfs2.so" , // taskname + { false, // don't start + BASE_MODULE, // Base Module + START_VFS_2_ID // module id for errorlog + }, +}; + + +}; // namespace INITSERVICE +#endif // __INIT_SVC_TASKS_H diff --git a/src/usr/initservice/makefile b/src/usr/initservice/makefile new file mode 100644 index 000000000..085805786 --- /dev/null +++ b/src/usr/initservice/makefile @@ -0,0 +1,11 @@ +ROOTPATH = ../../.. +MODULE = initservice + +OBJS = initservice.o \ + initservicetaskentry.o \ + initservicevfs1.o \ + initservicevfs2.o + +SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/initservice/test/initservicetest.H b/src/usr/initservice/test/initservicetest.H new file mode 100644 index 000000000..3edfa2885 --- /dev/null +++ b/src/usr/initservice/test/initservicetest.H @@ -0,0 +1,237 @@ +/** + * @file initservicetest.H + * + * Private functions for VFS2 phase. + */ + +#ifndef __TEST_INIT_SERVICETEST_H +#define __TEST_INIT_SERVICETEST_H + +/** + * @file initservicetest.H + * + * @brief Unit tests for initservice module + */ + +#include <cxxtest/TestSuite.H> + +#include "../initservice.H" + +/** + * @brief set up a dummy TaskInfo struct for test 1. + * this taskname should not exist, so we are expecting an error log back. + * + */ +const INITSERVICE::TaskInfo TASK_TEST1 = { + "libtestinitsvc_noexist.so" , // taskname + { + true, // startflag=true, try to start + INITSERVICE::BASE_MODULE, // Base Module + INITSERVICE::INIT_SVC_TEST1_ID, // module id for errorlog + }, +}; + + +/** + * @brief set up a dummy TaskInfo struct for test 2. + * example.C does indeed have a _start() function so this should return OK. + * + * @todo this needs to be replaced with a test module + */ +const INITSERVICE::TaskInfo TASK_TEST2 = { + "libexample.so" , // taskname + { + true, // startflag=true, try to start + INITSERVICE::BASE_MODULE, // Base Module + INITSERVICE::INIT_SVC_TEST2_ID, // module id for errorlog + }, +}; + + +/** + * @brief set up a dummy TaskInfo struct. + * libtrace does NOT have a _start() function so this should return an errorlog. + * + * @todo this needs to be replaced with a test module + */ +const INITSERVICE::TaskInfo TASK_TEST3 = { + "libtrace.so" , // taskname + { + true, // startflag=true, try to start + INITSERVICE::BASE_MODULE, // Base Module + INITSERVICE::INIT_SVC_TEST3_ID, // module id for errorlog + }, +}; + +/** + * @class InitServiceTest + * + * runs unit testa against InitService class + * + */ +class InitServiceTest: public CxxTest::TestSuite +{ + +public: + /** + * @brief testInitServiceStartTask1 + * this should try to run a nonexistent task, return an + * errorlog, and not blow up + * + */ + void testInitServiceStartTask1(void) + { + errlHndl_t errl = NULL; + /** + * @todo use a separate instance here, not the singleton + */ + INITSERVICE::InitService &l_is = INITSERVICE::InitService::getTheInstance(); + tid_t tidrc = 0; + + + TS_TRACE( "=====>Attempt to run a nonexistent task.\n "); + tidrc = l_is.startTask( TASK_TEST1, errl ); + printk( "testInitServiceStartTask1: startTask returned %d: errl=%p\n", tidrc, errl ); + if ( (int16_t)tidrc < 0 ) + { + TS_TRACE( "SUCCESS: startTask returned an errorlog.\n"); + // @todo dump error log to trace? + } + else + { + TS_FAIL( "ERROR: no error log was returned.\n"); + } + + + return; + } + + /** + * @brief testInitServiceStartTask2 + * this should try to run a task that does have a _start() function. + * it should return OK. + */ + void testInitServiceStartTask2(void) + { + errlHndl_t errl = NULL; + /** + * @todo use a separate instance here, not the singleton + */ + INITSERVICE::InitService &l_is = INITSERVICE::InitService::getTheInstance(); + tid_t tidrc = 0; + + + TS_TRACE( "=====>Attempt to run a task with a _start() function.\n "); + tidrc = l_is.startTask( TASK_TEST2, errl ); + printk( "testInitServiceStartTask2: startTask returned %d: errl=%p\n", tidrc, errl ); + if ( (int16_t)tidrc >= 0 ) + { + TS_TRACE( "SUCCESS: startTask returned OK.\n"); + // @todo dump error log to trace? + } + else + { + TS_FAIL( "ERROR: StartTask returned an error log.\n"); + } + + + return; + } + + + /** + * @brief testInitServiceStartTask3 + * this should try to run a task that does NOT have a _start() function. + * it should fail + */ + void testInitServiceStartTask3(void) + { + errlHndl_t errl = NULL; + /** + * @todo use a separate instance here, not the singleton + */ + INITSERVICE::InitService &l_is = INITSERVICE::InitService::getTheInstance(); + tid_t tidrc = 0; + + + TS_TRACE( "====>Attempt to run a task with NO _start() function.\n "); + tidrc = l_is.startTask( TASK_TEST3, errl ); + printk( "testInitServiceStartTask3: startTask returned %d: errl=%p\n", tidrc, errl ); + if ( (int16_t)tidrc < 0 ) + { + TS_TRACE( "SUCCESS: startTask returned an error log.\n"); + // @todo dump error log to trace? + } + else + { + TS_FAIL( "ERROR: StartTask did not return an error log.\n"); + } + + return; + } + + /** + * @brief testInitServicereportError1 + * This will call reportError with a NULL errlHndl_t . It should handle it + * OK (reportError() will print an error message to trace) + */ + void testInitServicereportError1(void) + { + errlHndl_t errl = NULL; + /** + * @todo use a separate instance here, not the singleton + */ + INITSERVICE::InitService &l_is = INITSERVICE::InitService::getTheInstance(); + + TS_TRACE( "====> call reportError with NULL handle, should handle it OK\n "); + l_is.reportError( errl ); + + // reportError() might crash, if it returns, just make sure it didn't modify + // the input pointer + if ( errl != NULL) + { + TS_FAIL( "ERROR: expected the NULL errlHndl_t to stay NULL\n"); + } + + return; + } + + /** + * @brief testInitServicereportError1 + * This will call reportError with a good errorlog. + * on return, it should be NULLED out + * @todo can we check with the errorlogging facility to see if it got + * posted?? + */ + void testInitServicereportError2(void) + { + errlHndl_t errl = NULL; + /** + * @todo use a separate instance here, not the singleton + */ + INITSERVICE::InitService &l_is = INITSERVICE::InitService::getTheInstance(); + + errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + INITSERVICE::INIT_SVC_TEST5_ID, + INITSERVICE::START_TASK_FAILED, + 0, + 0 + ); + + TS_TRACE( "====> call reportError with good error handle, should commit and then delete\n "); + l_is.reportError( errl ); + if ( errl !=NULL ) + { + TS_FAIL( "ERROR: reportError did not delete the errlHndl_t handle!\n" ); + } + + + + return; + } +}; // class InitServiceTest + + +#endif // __TEST_INIT_SERVICETEST_H + diff --git a/src/usr/initservice/test/makefile b/src/usr/initservice/test/makefile new file mode 100644 index 000000000..350257803 --- /dev/null +++ b/src/usr/initservice/test/makefile @@ -0,0 +1,6 @@ +ROOTPATH = ../../../.. + +MODULE = testinitservice +TESTS = *.H + +include ${ROOTPATH}/config.mk diff --git a/src/usr/makefile b/src/usr/makefile index 0f0ec8e65..ec5d3d7e6 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -3,6 +3,6 @@ ROOTPATH = ../.. OBJS = module_init.o SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \ - scom.d xscom.d targeting.d + scom.d xscom.d targeting.d initservice.d include ${ROOTPATH}/config.mk |