/* IBM_PROLOG_BEGIN_TAG * This is an automatically generated prolog. * * $Source: src/usr/hwpf/hwp/start_payload/start_payload.C $ * * IBM CONFIDENTIAL * * COPYRIGHT International Business Machines Corp. 2012 * * p1 * * Object Code Only (OCO) source materials * Licensed Internal Code Source Materials * IBM HostBoot Licensed Internal Code * * The source code for this program is not published or other- * wise divested of its trade secrets, irrespective of what has * been deposited with the U.S. Copyright Office. * * Origin: 30 * * IBM_PROLOG_END_TAG */ /** * @file start_payload.C * * Support file for IStep: start_payload * Start Payload * * HWP_IGNORE_VERSION_CHECK * */ /******************************************************************************/ // Includes /******************************************************************************/ #include #include // printk status #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // targeting support #include // fapi support #include #include #include "start_payload.H" #include // Uncomment these files as they become available: // #include "host_start_payload/host_start_payload.H" namespace START_PAYLOAD { using namespace TARGETING; using namespace fapi; using namespace ISTEP; /** * @brief This function will call the Initservice interface to shutdown * Hostboot. This function will call shutdown, passing in system * attribute variables for the Payload base and Payload offset. * * @return errlHndl_t - NULL if succesful, otherwise a pointer to the error * log. */ errlHndl_t callShutdown ( void ); /** * @brief This function will check the Istep mode and send the appropriate * mailbox message to the Fsp to indicate what we're doing. * * @param[in] i_istepModeFlag - Whether or not Isteps is enabled. * * @param[in] i_spFuncs - The SpFuncs system attribute. * * @return errlHndl_t - NULL if successful, otherwise a pointer to the error * log. */ errlHndl_t notifyFsp ( bool i_istepModeFlag, TARGETING::SpFunctions i_spFuncs ); // // Wrapper function to call 21.1 : // host_start_payload // void* call_host_start_payload( void *io_pArgs ) { errlHndl_t l_errl = NULL; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_start_payload entry" ); do { // Need to wait here until Fsp tells us go INITSERVICE::waitForSyncPoint(); // Need to load up the runtime module if it isn't already loaded if ( !VFS::module_is_loaded( "libruntime.so" ) ) { l_errl = VFS::module_load( "libruntime.so" ); if ( l_errl ) { // load module returned with errl set TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "Could not load runtime module" ); // break out of do block break; } } // Host Start Payload procedure, per documentation from Patrick. // - Verify target image // - TODO - Done via call to Secure Boot ROM. // - Will be done in future sprints // - Update HDAT with updated SLW images // - TODO - Once we know where they go in the HDAT //@todo : Move this to new sub-step with RTC:49501 // Write the HostServices attributes into mainstore l_errl = RUNTIME::populate_attributes(); if( l_errl ) { break; } // - Run CXX testcases l_errl = INITSERVICE::executeUnitTests(); if( l_errl ) { break; } // - Call shutdown using payload base, and payload entry. // - base/entry will be from system attributes // - this will start the payload (Phyp) // NOTE: this call will not return if successful. l_errl = callShutdown(); if( l_errl ) { break; } } while( 0 ); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_start_payload exit" ); // end task, returning any errorlogs to IStepDisp return l_errl; } // // Call shutdown // errlHndl_t callShutdown ( void ) { errlHndl_t err = NULL; uint64_t payloadBase = 0x0; uint64_t payloadEntry = 0x0; bool istepModeFlag = false; uint64_t status = SHUTDOWN_STATUS_GOOD; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ENTER_MRK"callShutdown()" ); do { // Set scratch register to indicate Hostboot is [still] active. const char * hostboot_string = "hostboot"; mmio_scratch_write(MMIO_SCRATCH_HOSTBOOT_ACTIVE, *reinterpret_cast(hostboot_string)); // Get Target Service, and the system target. TargetService& tS = targetService(); TARGETING::Target* sys = NULL; (void) tS.getTopLevelTarget( sys ); if( NULL == sys ) { // Error getting system target to get payload related values. We // will create an error to be passed back. This will cause the // istep to fail. TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ERR_MRK"System Target was NULL!" ); /*@ * @errortype * @reasoncode ISTEP_TARGET_NULL * @severity ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM * @moduleid ISTEP_START_PAYLOAD_CALL_SHUTDOWN * @userdata1 * @userdata2 * @devdesc System target was NULL! */ err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM, ISTEP_START_PAYLOAD_CALL_SHUTDOWN, ISTEP_TARGET_NULL, 0x0, 0x0 ); break; } // Get Payload base/entry from attributes payloadBase = sys->getAttr(); payloadEntry = sys->getAttr(); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"Payload Base: 0x%08x, Entry: 0x%08x", payloadBase, payloadEntry ); payloadBase = (payloadBase * MEGABYTE); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK" base: 0x%08x", payloadBase ); // Get Istep Mode flag istepModeFlag = sys->getAttr(); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"Istep mode flag: %s", ((istepModeFlag) ? "Enabled" : "Disabled") ); // Get the Service Processor Functions TARGETING::SpFunctions spFuncs = sys->getAttr(); // Notify Fsp with appropriate mailbox message. err = notifyFsp( istepModeFlag, spFuncs ); if( err ) { break; } // do the shutdown. TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_start_payload finished, shutdown = 0x%x.", status ); INITSERVICE::doShutdown( status, payloadBase, payloadEntry ); // Hang out here until shutdown happens int status = 0x0; while( 1 ) { task_wait( &status, NULL ); } } while( 0 ); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, EXIT_MRK"callShutdown()" ); return err; } // // Notify the Fsp via Mailbox Message // errlHndl_t notifyFsp ( bool i_istepModeFlag, TARGETING::SpFunctions i_spFuncs ) { errlHndl_t err = NULL; TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, ENTER_MRK"notifyFsp()" ); do { if( i_istepModeFlag ) { // Istep Mode send istep complete TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"Isteps enabled, send istep complete msg" ); err = INITSERVICE::sendIstepCompleteMsg(); if( err ) { break; } } else { // Non-Istep mode send SYNC_POINT_REACHED TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"Isteps disabled, send SYNC_POINT_REACHED msg" ); err = INITSERVICE::sendSyncPoint(); if( err ) { break; } } } while( 0 ); TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, EXIT_MRK"notifyFsp()" ); return err; } }; // end namespace