summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorayma <ayma@us.ibm.com>2012-12-13 16:29:39 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-12-18 15:46:41 -0600
commit7f36ca65b3ce2c358fcfff0ab4d30204fa9e89cc (patch)
tree4e3ddccf3fc4518ab25e4184093f7e97783478fa /src/usr
parent3147572991fa9eff4be6095b08b0299421e596b5 (diff)
downloadtalos-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.C188
-rw-r--r--src/usr/hwpf/hwp/dram_training/hbVddrMsg.C425
-rw-r--r--src/usr/hwpf/hwp/dram_training/hbVddrMsg.H250
-rw-r--r--src/usr/hwpf/hwp/dram_training/makefile3
-rw-r--r--src/usr/hwpf/hwp/mc_config/mc_config.C121
-rwxr-xr-xsrc/usr/targeting/xmltohb/genHwsvMrwXml.pl27
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>
OpenPOWER on IntegriCloud