diff options
Diffstat (limited to 'src/usr/targeting/attrsync.C')
-rw-r--r-- | src/usr/targeting/attrsync.C | 332 |
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 |