diff options
author | ayma <ayma@us.ibm.com> | 2012-12-13 16:29:39 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-12-18 15:46:41 -0600 |
commit | 7f36ca65b3ce2c358fcfff0ab4d30204fa9e89cc (patch) | |
tree | 4e3ddccf3fc4518ab25e4184093f7e97783478fa /src/usr | |
parent | 3147572991fa9eff4be6095b08b0299421e596b5 (diff) | |
download | talos-hostboot-7f36ca65b3ce2c358fcfff0ab4d30204fa9e89cc.tar.gz talos-hostboot-7f36ca65b3ce2c358fcfff0ab4d30204fa9e89cc.zip |
Changes to add support for dynamic VIDs on HB.
Changes to put code into HB to do the istep 13.1
and 13.5 which is disable_vddr and enable_vddr respectively
This is in conjunction with story 37517 on the hwsv side
RTC: 34041
Change-Id: Id09a78e581d2a778d781e2683cc7ec26c8d45153
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2687
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/hwpf/hwp/dram_training/dram_training.C | 188 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dram_training/hbVddrMsg.C | 425 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dram_training/hbVddrMsg.H | 250 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/dram_training/makefile | 3 | ||||
-rw-r--r-- | src/usr/hwpf/hwp/mc_config/mc_config.C | 121 | ||||
-rwxr-xr-x | src/usr/targeting/xmltohb/genHwsvMrwXml.pl | 27 |
6 files changed, 862 insertions, 152 deletions
diff --git a/src/usr/hwpf/hwp/dram_training/dram_training.C b/src/usr/hwpf/hwp/dram_training/dram_training.C index 2da2c66f1..b41092174 100644 --- a/src/usr/hwpf/hwp/dram_training/dram_training.C +++ b/src/usr/hwpf/hwp/dram_training/dram_training.C @@ -58,6 +58,9 @@ #include <fapi.H> #include <fapiPlatHwpInvoker.H> +//hb vddr support +#include <hbVddrMsg.H> + // Run on all Centaurs/MBAs, but needs to keep this one handy in case we // want to limit them in VPO const uint8_t UNLIMITED_RUN = 0xFF; @@ -102,54 +105,61 @@ void* call_host_disable_vddr( void *io_pArgs ) TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_disable_vddr entry" ); -#if 0 - // @@@@@ CUSTOM BLOCK: @@@@@ - // figure out what targets we need - // customize any other inputs - // set up loops to go through all targets (if parallel, spin off a task) - - // print call to hwp and dump physical path of the target(s) - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "===== host_disable_vddr HWP(? ? ? )", - ? - ? - ? ); - // dump physical path to targets - EntityPath l_path; - l_path = l_@targetN_target->getAttr<ATTR_PHYS_PATH>(); - l_path.dump(); - TRACFCOMP( g_trac_mc_init, "===== " ); - - // cast OUR type of target to a FAPI type of target. - const fapi::Target l_fapi_@targetN_target( - TARGET_TYPE_MEMBUF_CHIP, - reinterpret_cast<void *> - (const_cast<TARGETING::Target*>(l_@targetN_target)) ); - - // call the HWP with each fapi::Target - l_fapirc = host_disable_vddr( ? , ?, ? ); - - // process return code. - if ( l_fapirc== fapi::FAPI_RC_SUCCESS ) + if( MBOX::mailbox_enabled() ) { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : host_disable_vddr HWP(? ? ? )" ); + IStepError l_StepError; + + HBVddrMsg l_hbVddr; + + l_err = l_hbVddr.sendMsg(HBVddrMsg::HB_VDDR_DISABLE); + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: call_host_disable_vddr to sendMsg returns error", + l_err->reasonCode()); + /*@ + * @errortype + * @reasoncode ISTEP_DRAM_TRAINING_FAILED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid ISTEP_VDDR_DISABLE + * @userdata1 bytes 0-1: plid identifying first error + * bytes 2-3: reason code of first error + * @userdata2 bytes 0-1: total number of elogs included + * bytes 2-3: N/A + * @devdesc call to mss_scominit has failed + * see error log in the user details section for + * additional details. + */ + l_StepError.addErrorDetails(ISTEP_DRAM_TRAINING_FAILED, + ISTEP_VDDR_DISABLE, + l_err ); + + errlCommit( l_err, HWPF_COMP_ID ); + + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "SUCCESS : host_disable_vddr()" ); + } + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_disable_vddr" + "when a fsp present exit" ); + + return l_StepError.getErrorHandle(); } else { - /** - * @todo fapi error - just print out for now... - */ - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR 0x%.8X: host_disable_vddr HWP(? ? ?) ", - static_cast<uint32_t>(l_fapirc) ); + //no mailbox running so this is a fsp less system. Right now the istep + //only works when a FSP is present. May add code in the future for + //Stradale which is a FSP-less system + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"call_host_disable_vddr" + "no-op because fsp-less"); + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_disable_vddr " + "for an fsp less system exit" ); + + return l_err; } - // @@@@@ END CUSTOM BLOCK: @@@@@ -#endif - - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_disable_vddr exit" ); - return l_err; } // @@ -355,58 +365,64 @@ void* call_mem_startclocks( void *io_pArgs ) // void* call_host_enable_vddr( void *io_pArgs ) { - errlHndl_t l_err = NULL; - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_enable_vddr entry" ); -#if 0 - // @@@@@ CUSTOM BLOCK: @@@@@ - // figure out what targets we need - // customize any other inputs - // set up loops to go through all targets (if parallel, spin off a task) - - // print call to hwp and dump physical path of the target(s) - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "===== host_enable_vddr HWP(? ? ? )", - ? - ? - ? ); - // dump physical path to targets - EntityPath l_path; - l_path = l_@targetN_target->getAttr<ATTR_PHYS_PATH>(); - l_path.dump(); - TRACFCOMP( g_trac_mc_init, "===== " ); - - // cast OUR type of target to a FAPI type of target. - const fapi::Target l_fapi_@targetN_target( - TARGET_TYPE_MEMBUF_CHIP, - reinterpret_cast<void *> - (const_cast<TARGETING::Target*>(l_@targetN_target)) ); - - // call the HWP with each fapi::Target - l_fapirc = host_enable_vddr( ? , ?, ? ); - - // process return code. - if ( l_fapirc== fapi::FAPI_RC_SUCCESS ) + errlHndl_t l_err = NULL; + + if( MBOX::mailbox_enabled() ) { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : host_enable_vddr HWP(? ? ? )" ); + IStepError l_StepError; + + HBVddrMsg l_hbVddr; + + l_err = l_hbVddr.sendMsg(HBVddrMsg::HB_VDDR_ENABLE); + if (l_err) + { + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: call_host_enable_vddr to sendMsg returns error", + l_err->reasonCode()); + /*@ + * @errortype + * @reasoncode ISTEP_DRAM_TRAINING_FAILED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid ISTEP_VDDR_ENABLE + * @userdata1 bytes 0-1: plid identifying first error + * bytes 2-3: reason code of first error + * @userdata2 bytes 0-1: total number of elogs included + * bytes 2-3: N/A + * @devdesc call to mss_scominit has failed + * see error log in the user details section for + * additional details. + */ + l_StepError.addErrorDetails(ISTEP_DRAM_TRAINING_FAILED, + ISTEP_VDDR_ENABLE, + l_err ); + + errlCommit( l_err, HWPF_COMP_ID ); + + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "SUCCESS : host_enable_vddr()" ); + } + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_enable_vddr exit" ); + + return l_StepError.getErrorHandle(); } else { - /** - * @todo fapi error - just print out for now... - */ - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR 0x%.8X: host_enable_vddr HWP(? ? ?) ", - static_cast<uint32_t>(l_fapirc) ); - } - // @@@@@ END CUSTOM BLOCK: @@@@@ -#endif + //no mailbox running so this is a fsp less system. Right now the istep + //only works when a FSP is present. May add code in the future for + //Stradale which is a FSP-less system + TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"call_host_enable_vddr" + "no-op because fsp-less"); + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_enable_vddr " + "for an fsp less system exit" ); - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_host_enable_vddr exit" ); + return l_err; - return l_err; + } } diff --git a/src/usr/hwpf/hwp/dram_training/hbVddrMsg.C b/src/usr/hwpf/hwp/dram_training/hbVddrMsg.C new file mode 100644 index 000000000..f48e6626e --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/hbVddrMsg.C @@ -0,0 +1,425 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/hbVddrMsg.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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#include <sys/task.h> +#include <stdlib.h> +#include <string.h> +#include <sys/msg.h> +#include <sys/mm.h> +#include <errl/errlentry.H> +#include <errl/errlmanager.H> +#include <trace/interface.H> +#include <trace/trace.H> +#include <mbox/mbox_queues.H> +#include <mbox/mboxif.H> + +#include <hbVddrMsg.H> +#include <initservice/initserviceif.H> +#include <pnor/pnorif.H> +#include <fapi.H> + + +using namespace ERRORLOG; + +using namespace TARGETING; + +// Trace definition +trace_desc_t* g_trac_volt = NULL; +TRAC_INIT(&g_trac_volt, "HB_VDDR", 1024); + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::HBVddrMsg() +/////////////////////////////////////////////////////////////////////////////// +HBVddrMsg::HBVddrMsg() +{ + TRACDCOMP( g_trac_volt, ENTER_MRK "HBVddrMsg::HBVddrMsg()" ); + TRACDCOMP( g_trac_volt, EXIT_MRK "HBVddrMsg::HBVddrMsg()" ); + +}; + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::~HBVddrMsg() +/////////////////////////////////////////////////////////////////////////////// +HBVddrMsg::~HBVddrMsg() +{ + TRACDCOMP( g_trac_volt, ENTER_MRK "HBVddrMsg::~HBVddrMsg()" ); + TRACDCOMP( g_trac_volt, EXIT_MRK "HBVddrMsg::~HBVddrMsg()" ); +}; + + +/////////////////////////////////////////////////////////////////////////////// +// compareVids +/////////////////////////////////////////////////////////////////////////////// +bool compareVids( HBVddrMsg::hwsvPowrVmemRequest_t i_req1, + HBVddrMsg::hwsvPowrVmemRequest_t i_req2) +{ + return( static_cast<uint16_t>(i_req1.VmemId) < + static_cast<uint16_t>(i_req2.VmemId)); +} + +/////////////////////////////////////////////////////////////////////////////// +// areVidEqual +/////////////////////////////////////////////////////////////////////////////// +bool areVidsEqual(HBVddrMsg::hwsvPowrVmemRequest_t i_req1, + HBVddrMsg::hwsvPowrVmemRequest_t i_req2) +{ + return( static_cast<uint16_t>(i_req1.VmemId) == + static_cast<uint16_t>(i_req2.VmemId)); +} + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::createVddrData +/////////////////////////////////////////////////////////////////////////////// +void HBVddrMsg::createVddrData( + RequestContainer& io_request) const +{ + TRACFCOMP( g_trac_volt, ENTER_MRK "HBVddrMsg::createVddrData" ); + + //go through all the centaurs and gather the Voltage IDs and voltages + io_request.clear(); + + do{ + + TARGETING::TargetHandleList l_membufTargetList; + getAllChips(l_membufTargetList, TYPE_MEMBUF); + + TARGETING::Target* l_Target =NULL; + + hwsvPowrVmemRequest_t l_entry; + + for ( size_t i = 0; i < l_membufTargetList.size(); i++ ) + { + l_Target=l_membufTargetList[i]; + + TARGETING::ATTR_VMEM_ID_type l_VmemId= + l_Target->getAttr<TARGETING::ATTR_VMEM_ID>(); + TARGETING::ATTR_MSS_VOLT_type l_voltage = + l_Target->getAttr<TARGETING::ATTR_MSS_VOLT>(); + + l_entry.VmemId = l_VmemId; + l_entry.Voltage = static_cast<uint32_t>(l_voltage); + + io_request.push_back(l_entry); + } + + if (l_membufTargetList.size() >1) + { + //take out the duplicates Voltage IDs in io_request by first sorting and + //then removing the duplicates + + std::sort(io_request.begin(), io_request.end(), compareVids); + + std::vector<hwsvPowrVmemRequest_t>::iterator it; + it=std::unique(io_request.begin(), io_request.end(), areVidsEqual); + io_request.erase(it,io_request.end()); + } + + }while(0); + + TRACFCOMP( g_trac_volt, EXIT_MRK "HBVddrMsg::createVddrData" ); + return; +} + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::sendMsg +/////////////////////////////////////////////////////////////////////////////// +errlHndl_t HBVddrMsg::sendMsg(uint32_t i_msgType) const +{ + errlHndl_t l_err = NULL; + + TRACFCOMP(g_trac_volt, ENTER_MRK "hbVddrMsg::sendMsg msg_type =0x%08X",i_msgType); + + do{ + + RequestContainer l_request; + + if ( (i_msgType == HB_VDDR_ENABLE) || (i_msgType == HB_VDDR_DISABLE) ) + { + createVddrData(l_request); + } + else + { + TRACFCOMP(g_trac_volt, ERR_MRK "hbVddrMsg::send msg with non-" + "valid msg type%08X",i_msgType); + //generate errorLog; + /*@ + * @errortype + * @moduleid VDDR_SEND_MSG + * @reasoncode INCORRECT_MSG_TYPE + * @userdata1 i_msgType + * @userdata2 0 + * + * @devdesc HB got an incorrect type message. HB did not + * provide the correct message type in the istep. + * Userdata1 shows the message type passed in + */ + createErrLog(l_err,VDDR_SEND_MSG,INCORRECT_MSG_TYPE,i_msgType); + break; + } + + + + + size_t l_dataCount = l_request.size(); + uint32_t l_msgSize = l_dataCount*sizeof(hwsvPowrVmemRequest_t); + + + //create the hb send msg. the memory should be taken care of by mbox + msg_t* l_msg =NULL; + l_msg = msg_allocate(); + + l_msg->type = i_msgType; + + + l_msg->data[0]=0; + l_msg->data[1] =l_msgSize; + + TRACFCOMP(g_trac_volt, INFO_MRK "hbVddrMsg::l_dataCount=%d,l_msgSize=%d",l_dataCount,l_msgSize); + void* l_data=NULL; + l_data = malloc(l_msgSize); + + hwsvPowrVmemRequest_t* l_ptr = reinterpret_cast<hwsvPowrVmemRequest_t*>(l_data); + + for (size_t j =0; j<l_dataCount; j++) + { + l_ptr->VmemId=l_request.at(j).VmemId; + l_ptr->Voltage=l_request.at(j).Voltage; + + TRACFCOMP(g_trac_volt, ENTER_MRK "hbVddrMsg::sendMsg " + "l_ptr->VmemId=0x%04X,l_ptr->Voltage=%d, j=%d", + l_ptr->VmemId, l_ptr->Voltage,j); + + l_ptr++; + } + + l_msg->extra_data = l_data; + + TRACFBIN(g_trac_volt, "l_data", l_data, l_msgSize); + l_err = MBOX::sendrecv( MBOX::FSP_VDDR_MSGQ, l_msg ); + if (l_err) + { + TRACFCOMP(g_trac_volt, ERR_MRK "Failed sending VDDR message to FSP"); + + if (l_msg->extra_data!=NULL) + { + free(l_msg->extra_data); + } + if (l_msg) + { + msg_free(l_msg); + } + } + else + { + l_err=processMsg(l_msg); + } + + + }while(0); + + TRACFCOMP(g_trac_volt, EXIT_MRK "hbEnableVddr::sendMsg"); + return l_err; +} + + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::processVDDRmsg +/////////////////////////////////////////////////////////////////////////////// +errlHndl_t HBVddrMsg::processVDDRmsg(msg_t* i_recvMsg) const +{ + TRACFCOMP(g_trac_volt, ENTER_MRK "HBVddrMsg::processVDDRmsg"); + errlHndl_t l_errLog = NULL; + //check to see if an error occurred from the powr Enable/Disable functions + //and is inside the message + + uint32_t l_msgSize = i_recvMsg->data[1]; + uint16_t l_elementCount = l_msgSize/sizeof(hwsvPowrVmemReply_t); + const uint8_t* l_extraData = NULL; + l_extraData=static_cast<uint8_t*>(i_recvMsg->extra_data); + + do{ + if (l_extraData==NULL) + { + //an error occred in obtaining the extra data from the response msg + TRACFCOMP( g_trac_volt, ERR_MRK "HBVddrMsg::processVDDRmsg: l_extraData = NULL"); + //create an errorlog + /*@ + * @errortype + * @moduleid VDDR_PROC_VDDR_MSG + * @reasoncode VDDR_EMPTY_MSG + * @userdata1 0 + * @userdata2 0 + * + * @devdesc The hwsv returned a message where the extra data + * was null. This should not happen so need to + * tell HostBoot to stop the ipl + */ + createErrLog(l_errLog,VDDR_PROC_VDDR_MSG,VDDR_EMPTY_MSG); + break; + } + TARGETING::ATTR_VMEM_ID_type l_VmemId =0x0; + uint32_t l_errPlid =0x0; + + TRACFCOMP( g_trac_volt, INFO_MRK "HBVddrMsg::processVDDRmsg: " + "l_elementCount=%d, l_msgSize =%d", + l_elementCount, l_msgSize); + const hwsvPowrVmemReply_t* l_ptr= + reinterpret_cast<const hwsvPowrVmemReply_t*>(l_extraData); + + for (size_t i=0; i<l_elementCount; i++) + { + l_VmemId = l_ptr->VmemId; + l_errPlid = l_ptr->plid; + + TRACFCOMP( g_trac_volt, INFO_MRK "HBVddrMsg::processVDDRmsg: " + "l_VmemId=0x%08X, l_errPlid=0x%08X", l_VmemId,l_errPlid); + if (l_errPlid ==0x0) + { + TRACFCOMP( g_trac_volt, INFO_MRK "HBVddrMsg::processVDDRmsg: no plid " + "error found for l_VmemId=0x%08X", l_VmemId); + } + else + { + //error occured so break out of the loop and indicate an error was present + TRACFCOMP( g_trac_volt, ERR_MRK "HBVddrMsg::processVDDRmsg: error occured " + "on the powr function called in hwsv"); + //create an errorlog + /*@ + * @errortype + * @moduleid VDDR_PROC_VDDR_MSG + * @reasoncode VDDR_POWR_ERR + * @userdata1 l_errPlid + * @userdata2 0 + * + * @devdesc The hwsv returned a message where there was an error + * when the powr function was called. userdata1 contains + * the errorlog plid from hwsv generated by the powr function + */ + createErrLog(l_errLog,VDDR_PROC_VDDR_MSG,VDDR_POWR_ERR,l_errPlid); + l_errLog->plid(l_errPlid); + break; + } + + l_ptr++; + } + }while(0); + TRACFCOMP(g_trac_volt, EXIT_MRK "HBVddrMsg::processVDDRmsg"); + return l_errLog; +} + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::processMsg +/////////////////////////////////////////////////////////////////////////////// +errlHndl_t HBVddrMsg::processMsg(msg_t* i_Msg) const +{ + TRACFCOMP(g_trac_volt, ENTER_MRK "HBVddrMsg::processMsg"); + errlHndl_t l_errLog = NULL; + + do + { + //check to see if the data[0] =0 or contains a value. A value of 0 means its a + //response to a request and a value not equal to zero means that its an error coming back + + uint16_t l_value1=i_Msg->data[0]; + if (l_value1 ==0) + { + //process a response to a request + + uint32_t l_msgType =i_Msg->type; + TRACFCOMP( g_trac_volt, INFO_MRK "HBVddrMsg::processMsg l_msgType=x%08X",l_msgType ); + if ( (l_msgType == HB_VDDR_ENABLE) || (l_msgType == HB_VDDR_DISABLE) ) + { + //process a VDDR message + l_errLog=processVDDRmsg(i_Msg); + if (l_errLog) + { + break; + } + + } + else + { + TRACFCOMP( g_trac_volt, ERR_MRK "HBVddrMsg::processMsg recv'd a non valid type"); + //generate errorLog; + /*@ + * @errortype + * @moduleid VDDR_PROC_MSG + * @reasoncode INCORRECT_MSG_TYPE + * @userdata1 0 + * @userdata2 0 + * + * @devdesc HB got an incorrect type message. HWSV did not populate + * the message correctly or mbox corrupted the message + */ + createErrLog(l_errLog,VDDR_PROC_MSG,INCORRECT_MSG_TYPE); + } + } + else + { + //an error occurred so should stop the IPL + TRACFCOMP( g_trac_volt, ERR_MRK "HBVddrMsg::RecvMsgHndlr recv'd an error message" ); + //generate an errorlog + /*@ + * @errortype + * @moduleid VDDR_PROC_MSG + * @reasoncode VDDR_ERROR_MSG + * @userdata1 error PLID from hwsv + * @userdata2 0 + * + * @devdesc The hwsv found an error while processing the + * message so it sent an error message back to + * indicate to HostBoot to stop the IPL. + * Userdata1 will have the error PLID from hwsv's + * errorlog + */ + + createErrLog(l_errLog,VDDR_PROC_MSG,VDDR_ERROR_MSG,i_Msg->data[1]); + l_errLog->plid(i_Msg->data[1]); + } + + }while(0); + + TRACFCOMP(g_trac_volt, EXIT_MRK "HBVddrMsg::processMsg"); + return l_errLog; +} + +/////////////////////////////////////////////////////////////////////////////// +// HBVddrMsg::createErrLog +/////////////////////////////////////////////////////////////////////////////// +void HBVddrMsg::createErrLog(errlHndl_t& io_err, + VddrModuleId i_mod, + VddrReasonCode i_rc, + uint32_t i_userData1) const +{ + if (io_err == NULL) + { + io_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + i_mod, + i_rc, + i_userData1, + 0); + + } + return; +} + + diff --git a/src/usr/hwpf/hwp/dram_training/hbVddrMsg.H b/src/usr/hwpf/hwp/dram_training/hbVddrMsg.H new file mode 100644 index 000000000..0d04babe5 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/hbVddrMsg.H @@ -0,0 +1,250 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/hbVddrMsg.H $ */ +/* */ +/* 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 otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __HB_VDDR_MSG_H +#define __HB_VDDR_MSG_H + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <sys/task.h> +#include <stdlib.h> +#include <string.h> +#include <sys/mm.h> +#include <sys/msg.h> +#include <sys/sync.h> +#include <stdint.h> + +#include <util/singleton.H> +#include <errl/errlentry.H> +#include <kernel/timemgr.H> +#include <hbotcompid.H> +#include <hwas/common/hwasCallout.H> +#include <mbox/mbox_queues.H> +#include <mbox/mboxif.H> +#include <targeting/common/targetservice.H> +#include <targeting/common/utilFilter.H> + + +/*****************************************************************************/ +// Forward class declarations +/*****************************************************************************/ +class HBVddrMsg; + +/** + * @brief HBVddrMsg + * This class provides interfaces to send and process messages to and from + * hwsv with respect to powr. It also indicates when to stop the IPL via + * errorlogs + */ +class HBVddrMsg +{ + +public: + /** + * @struct hwsvPowrVmemRequest_t + * + * @brief structure to contain the Vmem Voltage rail ID and + * its corresponding voltage + * + */ + struct hwsvPowrVmemRequest_t + { + TARGETING::ATTR_VMEM_ID_type VmemId; + TARGETING::ATTR_MSS_VOLT_type Voltage; + + hwsvPowrVmemRequest_t() + { + VmemId=0x0; + Voltage=0; + } + }__attribute__ ((packed)); + + /** + * @struct hwsvPowrVmemReply_t + * + * @brief structure to contain the Vmem Voltage rail ID and + * its corresponding errorlog plid from the powr function + * call + * + */ + struct hwsvPowrVmemReply_t + { + TARGETING::ATTR_VMEM_ID_type VmemId; + uint32_t plid; + + hwsvPowrVmemReply_t() + { + VmemId=0x0; + plid=0x0; + } + }__attribute__ ((packed)); + + /** + * @enum VDDR_MSG_TYPE + * + * @brief Message enum to determine how the msg should be processed + * + */ + enum VDDR_MSG_TYPE + { + HB_VDDR_ENABLE = 0x40000041, + HB_VDDR_DISABLE = 0x40000042, + }; + + /** + * @enum VddrModuleId + * + * @brief Module ID enums for error handling + * + */ + enum VddrModuleId + { + VDDR_PROC_MSG = 0x01, + VDDR_PROC_VDDR_MSG = 0x02, + VDDR_SEND_MSG = 0x03, + }; + + /** + * @enum VddrReasonCode + * + * @brief Reason code enums for error handling + * + */ + enum VddrReasonCode + { + VDDR_EMPTY_MSG = 0x01, + VDDR_ERROR_MSG = 0x02, + VDDR_POWR_ERR = 0x03, + INCORRECT_MSG_TYPE = 0x04, + }; + + /** + * @brief typedefs for containers for structures + */ + typedef std::vector<hwsvPowrVmemReply_t> ResponseContainer; + typedef std::vector<hwsvPowrVmemRequest_t> RequestContainer; + + /** + * @brief Default constructor + */ + HBVddrMsg(); + + /** + * @brief Destructor + * + * Releases all resources owned by the handle. + * + * @return None + * + */ + ~HBVddrMsg(); + + + /** + * @brief Uses the internal mailbox to send a message to the FSP + * + * + * @par Detailed Description: + * This funciton will create the request message by + * going through the attributes and correlating the + * VID and Voltage into the final message for all the + * VIDs in the system + * + * @param[in/out] io_request + * Contains the voltage and VID pairs to be passed + * to hwsvd on the FSP. + * + * @return None + */ + void createVddrData(RequestContainer& io_request)const; + + /** + * @brief Uses the internal mailbox to send a message to the FSP + * + * + * @par Detailed Description: + * This function will call into mailbox FSP code using the + * FSP_VDDR_MSGQ as the message queue.. + * + * @param[in] i_msgType + * HBVddrMsg::VDDR_MSG_TYPE passed in to define the + * message policy. + * + * @return errlHndl_t + * return errl == NULL -> success + * return errl != NULL -> failure + */ + errlHndl_t sendMsg(uint32_t i_msgType) const; + + +protected: + + + /** + * @brief function to process a generic message recieved from the FSP + * + * @param[in] i_recvMsg The message from the message queue. + * It contains the response data from the FSP + * + * @return errlHndl_t + * return errl == NULL -> success + * return errl != NULL -> failure + */ + errlHndl_t processMsg(msg_t* i_recvMsg) const; + + /** + * @brief function to process a power Vmem message recieved from the FSP + * + * @param[in] i_recvMsg The message from the message queue. + * It contains the response data from the FSP + * + * @param[out] i_passed indicates if powr function succeeded or failed on the + * FSP. + * + * @return errlHndl_t + * return errl == NULL -> success + * return errl != NULL -> failure + */ + errlHndl_t processVDDRmsg(msg_t* i_recvMsg)const; + + /** + * @brief function to create error logs for errors that occured in FSP side + * + * @param[in/out] io_err. Error log to generate indicating that an error has + * has occured on HB or in the powr messages. This error + * should stop the IPL from processing further. + * + * @param[in] i_mod. The module where the error occured + * + * @param[in] i_rc. The return code for the error that occured + * + * @return None + */ + void createErrLog(errlHndl_t& io_err,VddrModuleId i_mod,VddrReasonCode i_rc, + uint32_t i_userData1=0x0) const; + +}; + + +#endif diff --git a/src/usr/hwpf/hwp/dram_training/makefile b/src/usr/hwpf/hwp/dram_training/makefile index b5712de65..4c0ab9d0e 100644 --- a/src/usr/hwpf/hwp/dram_training/makefile +++ b/src/usr/hwpf/hwp/dram_training/makefile @@ -66,7 +66,8 @@ OBJS = dram_training.o \ mss_access_delay_reg.o \ mss_generic_shmoo.o \ mss_mcbist.o \ - mss_mcbist_common.o + mss_mcbist_common.o\ + hbVddrMsg.o ## NOTE: add a new directory onto the vpaths when you add a new HWP ##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/??? diff --git a/src/usr/hwpf/hwp/mc_config/mc_config.C b/src/usr/hwpf/hwp/mc_config/mc_config.C index 4cef54b1d..c5968cda3 100644 --- a/src/usr/hwpf/hwp/mc_config/mc_config.C +++ b/src/usr/hwpf/hwp/mc_config/mc_config.C @@ -111,69 +111,98 @@ void* call_mss_volt( void *io_pArgs ) TARGETING::TargetHandleList l_membufTargetList; getAllChips(l_membufTargetList, TYPE_MEMBUF); - // declare a vector of fapi targets to pass to mss_volt - std::vector<fapi::Target> l_membufFapiTargets; + //get a list of unique VmemIds + std::vector<TARGETING::ATTR_VMEM_ID_type> l_VmemList; - // fill in the vector - for ( size_t i = 0; i < l_membufTargetList.size(); i++ ) + for (size_t i = 0; i < l_membufTargetList.size(); i++ ) { - // make a local copy of the target for ease of use - const TARGETING::Target* l_membuf_target = l_membufTargetList[i]; + TARGETING::ATTR_VMEM_ID_type l_VmemID = + l_membufTargetList[i]->getAttr<ATTR_VMEM_ID>(); + l_VmemList.push_back(l_VmemID); + } - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "===== add to fapi::Target vector..." ); - EntityPath l_path; - l_path = l_membuf_target->getAttr<ATTR_PHYS_PATH>(); - l_path.dump(); + std::sort(l_VmemList.begin(), l_VmemList.end()); - fapi::Target l_membuf_fapi_target( - TARGET_TYPE_MEMBUF_CHIP, - reinterpret_cast<void *> - (const_cast<TARGETING::Target*>(l_membuf_target)) ); + std::vector<TARGETING::ATTR_VMEM_ID_type>::iterator objItr; + objItr=std::unique(l_VmemList.begin(), l_VmemList.end()); + l_VmemList.erase(objItr,l_VmemList.end()); - l_membufFapiTargets.push_back( l_membuf_fapi_target ); - } // endfor + //for each unique VmemId filter it out of the list of membuf targets + //to create a subsetlist of membufs with just that vmemid + for(size_t i = 0; i < l_VmemList.size(); i++) + { + // declare a vector of fapi targets to pass to mss_volt + std::vector<fapi::Target> l_membufFapiTargets; - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "===== mss_volt HWP( vector )" ); - // call the HWP with a vector of targets - FAPI_INVOKE_HWP(l_err, mss_volt, l_membufFapiTargets); + for (size_t j = 0; j < l_membufTargetList.size(); j++) + { + if (l_membufTargetList[j]->getAttr<ATTR_VMEM_ID>()==l_VmemList[i]) + { + // make a local copy of the target for ease of use + const TARGETING::Target* l_membuf_target = + l_membufTargetList[j]; + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "===== add to fapi::Target vector vmem_id=0x%08X...", + l_membuf_target->getAttr<ATTR_VMEM_ID>()); + + EntityPath l_path; + l_path = l_membuf_target->getAttr<ATTR_PHYS_PATH>(); + l_path.dump(); + + fapi::Target l_membuf_fapi_target( + TARGET_TYPE_MEMBUF_CHIP, + reinterpret_cast<void *> + (const_cast<TARGETING::Target*>(l_membuf_target)) ); - // process return code. - if ( l_err ) - { + l_membufFapiTargets.push_back( l_membuf_fapi_target ); + + } + + } + + //now have the a list of fapi membufs with just the one VmemId + //call the HWP on the list of fapi targets TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "ERROR 0x%.8X: mss_volt HWP( ) ", l_err->reasonCode()); + "===== mss_volt HWP( vector )" ); + FAPI_INVOKE_HWP(l_err, mss_volt, l_membufFapiTargets); + + // process return code. + if ( l_err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "ERROR 0x%.8X: mss_volt HWP( ) ", l_err->reasonCode()); - /*@ - * @errortype - * @reasoncode ISTEP_MC_CONFIG_FAILED - * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE - * @moduleid ISTEP_MSS_VOLT - * @userdata1 bytes 0-1: plid identifying first error - * bytes 2-3: reason code of first error - * @userdata2 bytes 0-1: total number of elogs included - * bytes 2-3: N/A - * @devdesc call to mss_volt has failed - * - */ - l_StepError.addErrorDetails(ISTEP_MC_CONFIG_FAILED, + /*@ + * @errortype + * @reasoncode ISTEP_MC_CONFIG_FAILED + * @severity ERRORLOG::ERRL_SEV_UNRECOVERABLE + * @moduleid ISTEP_MSS_VOLT + * @userdata1 bytes 0-1: plid identifying first error + * bytes 2-3: reason code of first error + * @userdata2 bytes 0-1: total number of elogs included + * bytes 2-3: N/A + * @devdesc call to mss_volt has failed + * + */ + l_StepError.addErrorDetails(ISTEP_MC_CONFIG_FAILED, ISTEP_MSS_VOLT, l_err ); - errlCommit( l_err, HWPF_COMP_ID ); + errlCommit( l_err, HWPF_COMP_ID ); + break; - } - else - { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "SUCCESS : mss_volt HWP( )" ); - } + } + else + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "SUCCESS : mss_volt HWP( )" ); + } - TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_volt exit" ); + } // endfor + TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_volt exit" ); return l_StepError.getErrorHandle(); } diff --git a/src/usr/targeting/xmltohb/genHwsvMrwXml.pl b/src/usr/targeting/xmltohb/genHwsvMrwXml.pl index f5a2c3683..2cce8e78b 100755 --- a/src/usr/targeting/xmltohb/genHwsvMrwXml.pl +++ b/src/usr/targeting/xmltohb/genHwsvMrwXml.pl @@ -177,9 +177,9 @@ my $vmemCentaur = XMLin("$mrwdir/${sysname}-cent-vrds.xml"); # Capture all pnor attributes into the @unsortedPnorTargets array use constant VMEM_DEV_PATH_FIELD => 0; use constant VMEM_I2C_ADDR_FIELD => 1; -use constant VMEM_NODE_FIELD => 2; -use constant VMEM_POS_FIELD => 3; -use constant VMEM_ID_FIELD => 4; +use constant VMEM_ID_FIELD => 2; +use constant VMEM_NODE_FIELD => 3; +use constant VMEM_POS_FIELD => 4; my $vmemId = 0x0; @@ -202,7 +202,7 @@ foreach my $i (@{$vmemCentaur->{'centaur-vrd-connection'}}) ($vmemAddr eq $vmemDevAddr[$j][VMEM_I2C_ADDR_FIELD]) ) { $found =1; - $vmemValue=$vmemArray[$j]; + $vmemValue=$vmemDevAddr[$j][VMEM_ID_FIELD]; last; } else @@ -210,23 +210,18 @@ foreach my $i (@{$vmemCentaur->{'centaur-vrd-connection'}}) $found=0; } } - if ($found ==1) - { - push (@vmemArray,$vmemValue); - } - else + if ($found ==0) { $vmemValue=$newValue++; - push (@vmemArray,$vmemValue); + push (@vmemDevAddr,[$vmemDev, $vmemAddr, $vmemValue]); } - push (@vmemDevAddr,[$vmemDev, $vmemAddr]); my $vmemNode = $i->{'centaur'}->{'target'}->{'node'}; my $vmemPosition = $i->{'centaur'}->{'target'}->{'position'}; - push (@unsortedVmem,[$vmemDev, $vmemAddr, $vmemNode, $vmemPosition, - $vmemValue]); + push (@unsortedVmem,[$vmemDev, $vmemAddr, $vmemValue, $vmemNode, + $vmemPosition]); } @@ -918,8 +913,6 @@ my $membMcs; my $mba_count = 0; my $vmem_id =0; my $vmem_count =0; -my $vmemAddr_prev=""; -my $vmemDevPath_prev=""; for my $i ( 0 .. $#STargets ) { @@ -2366,10 +2359,6 @@ sub generate_centaur <default>affinity:sys-$sys/node-$node/proc-$proc/mcs-$mcs/" . "membuf-$ctaur</default> </attribute> - <attribute> - <id>VMEM_ID</id> - <default>$vmemId</default> - </attribute> <!-- TODO When MRW provides the information, these two attributes should be included. values of X come from MRW. <attribute> |