summaryrefslogtreecommitdiffstats
path: root/src/usr/targeting/attrsync.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/targeting/attrsync.C')
-rw-r--r--src/usr/targeting/attrsync.C332
1 files changed, 325 insertions, 7 deletions
diff --git a/src/usr/targeting/attrsync.C b/src/usr/targeting/attrsync.C
index 4dd43cc55..ca70f8658 100644
--- a/src/usr/targeting/attrsync.C
+++ b/src/usr/targeting/attrsync.C
@@ -54,6 +54,27 @@ namespace TARGETING
TRACDCOMP(g_trac_targeting, "total pages %d", iv_total_pages );
}
+ ATTR_SYNC_RC AttributeSync::updateSectionData() const
+ {
+ TARG_INF( ENTER_MRK "AttributeSync::updateSectionData - "
+ "section type %u total pages %d",
+ iv_section_to_sync, iv_total_pages );
+
+ ATTR_SYNC_RC l_rc = ATTR_SYNC_SUCCESS;
+
+ // call the targeting function here to get context.
+ TargetService& l_targetService = targetService();
+
+ // write the section data info into the iv_pages structure
+ if ( false == l_targetService.writeSectionData( iv_pages ) )
+ {
+ l_rc = ATTR_SYNC_FAILURE;
+ }
+
+ TARG_INF( EXIT_MRK "AttributeSync::updateSectionData");
+ return l_rc;
+ }
+
errlHndl_t AttributeSync::syncSectionToFsp(
TARGETING::SECTION_TYPE i_section_to_sync )
{
@@ -73,7 +94,7 @@ namespace TARGETING
{
msg = msg_allocate();
- msg->type = ATTR_SYNC_SECTION;
+ msg->type = ATTR_SYNC_SECTION_TO_FSP;
msg->data[0] = 0;
@@ -108,7 +129,6 @@ namespace TARGETING
}
- // if there was no error and there was data to send
if(( l_errl == NULL ) && ( iv_total_pages != 0 ))
{
// tell fsp to commit the last section of data we sent
@@ -127,6 +147,186 @@ namespace TARGETING
}
+ errlHndl_t AttributeSync::syncSectionFromFsp(
+ TARGETING::SECTION_TYPE i_section_to_sync,
+ msg_q_t i_pMsgQ )
+ {
+ TARG_INF( ENTER_MRK "AttributeSync::syncSectionFromFsp" );
+
+ errlHndl_t l_errl = NULL;
+ bool l_sync_complete = false;
+ ATTR_SYNC_RC l_rc = ATTR_SYNC_FAILURE;
+ TARGETING::sectionRefData l_page;
+
+ iv_section_to_sync = i_section_to_sync;
+ memset( &l_page, 0, sizeof(TARGETING::sectionRefData) );
+
+ do{
+
+ // send a request to FSP to sync to Hostboot
+ l_errl = sendSyncToHBRequestMessage();
+ if (l_errl)
+ {
+ break;
+ }
+
+ do{
+
+ // wait for FSP to send the section's attribute data
+ TARG_DBG( "Wait for message from FSP");
+ msg_t * l_pMsg = msg_wait(i_pMsgQ);
+
+ // process message just received
+ if ( ATTR_SYNC_SECTION_TO_HB == l_pMsg->type )
+ {
+ TARG_DBG( "HB Attribute Sync Section message type received "
+ "from the FSP");
+
+ // get the section id
+ l_page.sectionId = ATTR_SYNC_GET_SECTION_ID(l_pMsg->data[0]);
+
+ // get the page number
+ l_page.pageNumber = ATTR_SYNC_GET_PAGE_NUMBER(l_pMsg->data[0]);
+
+ // save a pointer to the page
+ l_page.dataPtr =
+ reinterpret_cast<uint8_t *> (l_pMsg->extra_data);
+
+ // Validate the data received. Ignore page if
+ // section id or page size is incorrect or if
+ // there are no page received since we cannot send
+ // an error back to the FSP at this point. We will
+ // check later whether the correct number of valid
+ // pages for the section was received when FSP send
+ // us the sync complete message.
+
+ // if no page received
+ if ( NULL == l_page.dataPtr)
+ {
+ TARG_ERR("WARNING: "
+ "no attribute page received from FSP");
+ }
+ // if it's not the requested section
+ else if ( iv_section_to_sync != l_page.sectionId )
+ {
+ TARG_ERR("WARNING: "
+ "section type received from FSP = %u, expecting %u",
+ l_page.sectionId, iv_section_to_sync);
+
+ //Free the memory
+ free(l_pMsg->extra_data);
+ l_pMsg->extra_data = NULL;
+ }
+ // page size should always be 4K
+ else if ( PAGESIZE != l_pMsg->data[1] )
+ {
+ TARG_ERR("WARNING: "
+ "page size received from FSP = %u, expecting 4K",
+ l_pMsg->data[1]);
+
+ free(l_pMsg->extra_data);
+ l_pMsg->extra_data = NULL;
+ }
+ else
+ {
+ iv_pages.push_back(l_page);
+ }
+ }
+ else if ( ATTR_SYNC_COMPLETE_TO_HB == l_pMsg->type )
+ {
+ TARG_DBG( "HB Attribute Sync Complete message type "
+ "received from the FSP");
+
+ l_sync_complete = true;
+
+ iv_total_pages = ATTR_SYNC_GET_PAGE_COUNT( l_pMsg->data[0] );
+
+ // check that the total # of valid pages received is correct
+ if ( iv_pages.size() == iv_total_pages )
+ {
+ // write the section to the Attribute virtual address
+ // space
+ l_rc = updateSectionData();
+
+ if (l_rc)
+ {
+ TARG_ERR(
+ "HB failed in writing the attribute section" );
+ }
+ }
+ else
+ {
+ TARG_ERR( "total # of valid pages received = %u, "
+ "expecting %u", iv_pages.size(), iv_total_pages);
+
+ l_rc = ATTR_SYNC_FAILURE;
+ }
+
+ if (l_rc)
+ {
+ /*@
+ * @errortype
+ * @moduleid TARG_MOD_ATTR_SYNC
+ * @reasoncode TARG_RC_ATTR_SYNC_TO_HB_FAIL
+ * @userdata1 return code
+ * @userdata2 section to sync
+ * @devdesc The Attribute synchronization from FSP
+ * failed.
+ */
+ l_errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TARG_MOD_ATTR_SYNC,
+ TARG_RC_ATTR_SYNC_TO_HB_FAIL,
+ l_rc,
+ iv_section_to_sync);
+ }
+
+ // send a msg back to FSP indicating success/failure
+ l_pMsg->data[0] = 0;
+ ATTR_SYNC_ADD_RC( l_rc, l_pMsg->data[0] );
+ int l_respond_rc = msg_respond(i_pMsgQ, l_pMsg);
+ if (l_respond_rc)
+ {
+ // Just output a trace here since FSP should
+ // handle error case where it doesn't receive
+ // a response from HB.
+ TARG_ERR( "WARNING: Bad rc from msg_respond: %d",
+ l_respond_rc);
+ msg_free( l_pMsg );
+ l_pMsg = NULL;
+ }
+ }
+ else
+ {
+ TARG_ERR( "WARNING: Invalid message type [0x%x] received "
+ "from the FSP, ignoring...", l_pMsg->type);
+ }
+
+ // Free memory allocated for message
+ if ( msg_is_async(l_pMsg) )
+ {
+ msg_free( l_pMsg );
+ l_pMsg = NULL;
+ }
+
+ }while (false == l_sync_complete);
+
+ // free memory
+ if ( iv_pages.size() )
+ {
+ for ( size_t i = 0; i < iv_pages.size(); i++ )
+ {
+ free( iv_pages[i].dataPtr );
+ }
+
+ iv_pages.clear();
+ }
+
+ }while (0);
+
+ TARG_INF( EXIT_MRK "AttributeSync::syncSectionFromFsp" );
+ return l_errl;
+ }
+
// send the sync complete message
errlHndl_t AttributeSync::sendSyncCompleteMessage( )
{
@@ -136,10 +336,10 @@ namespace TARGETING
msg_t * msg = msg_allocate();
- // initilaize msg buffer
+ // initialize msg buffer
memset( msg, 0, sizeof(msg_t) );
- msg->type = ATTR_SYNC_COMPLETE;
+ msg->type = ATTR_SYNC_COMPLETE_TO_FSP;
ATTR_SYNC_ADD_PAGE_COUNT( iv_total_pages, msg->data[0] );
@@ -157,7 +357,7 @@ namespace TARGETING
/*@
* @errortype
* @moduleid TARG_MOD_ATTR_SYNC
- * @reasoncode TARG_RC_ATTR_SYNC_FAIL
+ * @reasoncode TARG_RC_ATTR_SYNC_TO_FSP_FAIL
* @userdata1 return code from FSP attribute sync
* @userdata2 section ID of for section being sync'd
*
@@ -167,7 +367,7 @@ namespace TARGETING
*/
l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
TARG_MOD_ATTR_SYNC,
- TARG_RC_ATTR_SYNC_FAIL,
+ TARG_RC_ATTR_SYNC_TO_FSP_FAIL,
return_code,
(uint64_t)iv_section_to_sync);
}
@@ -179,6 +379,66 @@ namespace TARGETING
return l_err;
}
+ // send a request to FSP to sync to Hostboot
+ errlHndl_t AttributeSync::sendSyncToHBRequestMessage()
+ {
+ TARG_INF( ENTER_MRK "AttributeSync::sendSyncToHBRequestMessage" );
+
+ errlHndl_t l_err = NULL;
+
+ // allocate message buffer
+ // buffer will be initialized to zero by msg_allocate()
+ msg_t * l_pMsg = msg_allocate();
+
+ l_pMsg->type = ATTR_SYNC_REQUEST_TO_HB;
+
+ ATTR_SYNC_ADD_SECTION_ID( iv_section_to_sync, l_pMsg->data[0] );
+
+ l_err = sendMboxMessage( SYNCHRONOUS, l_pMsg );
+
+ if( l_err == NULL )
+ {
+ // see if there was an error on the other end
+ ATTR_SYNC_RC return_code = ATTR_SYNC_GET_RC( l_pMsg->data[0] );
+
+ if ( return_code )
+ {
+ TARG_ERR(
+ "rc 0x%x received from FSP for Sync to HB request",
+ return_code );
+
+ /*@
+ * @errortype
+ * @moduleid TARG_MOD_ATTR_SYNC
+ * @reasoncode TARG_RC_ATTR_SYNC_REQUEST_TO_HB_FAIL
+ * @userdata1 return code from FSP
+ * @userdata2 section to sync
+ * @devdesc The Attribute synchronization code on the
+ * FSP side was unable to fulfill the sync to
+ * HB request.
+ */
+ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE,
+ TARG_MOD_ATTR_SYNC,
+ TARG_RC_ATTR_SYNC_REQUEST_TO_HB_FAIL,
+ return_code,
+ iv_section_to_sync);
+ }
+ }
+ else
+ {
+ TARG_ERR(
+ "Failed to send request to FSP to sync section type %u "
+ "to Hostboot.", iv_section_to_sync );
+ }
+
+ // for a syncronous message we need to free the message
+ msg_free( l_pMsg );
+ l_pMsg = NULL;
+
+ TARG_INF( EXIT_MRK "AttributeSync::sendSyncToHBRequestMessage" );
+ return l_err;
+ }
+
errlHndl_t AttributeSync::sendMboxMessage( MBOX_MSG_TYPE type,
msg_t * i_msg )
{
@@ -254,7 +514,7 @@ namespace TARGETING
if( l_errl )
{
TRACFCOMP(g_trac_targeting,
- "Error returned when syncing section type %d",
+ "Error returned when syncing section type %d to FSP",
section_type[i]);
break;
}
@@ -265,6 +525,64 @@ namespace TARGETING
return l_errl;
}
+ errlHndl_t syncAllAttributesFromFsp()
+ {
+ TARG_INF( ENTER_MRK "syncAllAttributesFromFsp" );
+
+ errlHndl_t l_errl = NULL;
+
+ do{
+ // if the mailbox is not enabled then skip attribute sync
+ if( !(MBOX::mailbox_enabled()) )
+ {
+ TARG_INF( "Mailbox is not enabled, skipping attribute sync" );
+ break;
+ }
+
+ // create Hostboot message queue
+ msg_q_t l_pHbMsgQ = msg_q_create();
+
+ // register Hostboot message queue with mailbox to receive messages
+ l_errl = MBOX::msgq_register(MBOX::HB_ATTR_SYNC_MSGQ, l_pHbMsgQ);
+ if (l_errl)
+ {
+ TARG_ERR( "Error registering the Hostboot message queue with "
+ "mailbox service." );
+ break;
+ }
+
+ // these are the sections we want to sync
+ SECTION_TYPE section_type[] ={SECTION_TYPE_PNOR_RW,
+ SECTION_TYPE_HEAP_PNOR_INIT,
+ SECTION_TYPE_HEAP_ZERO_INIT};
+
+ size_t section_count = sizeof(section_type)/sizeof(section_type[0]);
+
+ TARG_DBG( "section count = %d", section_count );
+
+ // pull all attributes from FSP
+ AttributeSync l_Sync;
+
+ for(uint8_t i = 0; i < section_count; i++)
+ {
+ TARG_INF( "syncing section type = %d", section_type[i] );
+ l_errl = l_Sync.syncSectionFromFsp( section_type[i], l_pHbMsgQ );
+
+ if (l_errl)
+ {
+ break;
+ }
+ }
+
+ // unregister the Hosboot message queue from the mailbox service.
+ MBOX::msgq_unregister(MBOX::HB_ATTR_SYNC_MSGQ);
+
+ } while (0);
+
+ TARG_INF( EXIT_MRK "syncAllAttributesFromFsp" );
+ return l_errl;
+ }
+
}; // end namespace
OpenPOWER on IntegriCloud