summaryrefslogtreecommitdiffstats
path: root/src/usr/mbox
diff options
context:
space:
mode:
authorMissy Connell <missyc@us.ibm.com>2012-04-11 11:01:32 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-05-08 16:37:36 -0500
commit5d0c443dd8e532f2e6779d2b83ce6218db11e000 (patch)
tree8880d69997f70d474866df893acf89156bef8926 /src/usr/mbox
parentcb5ba5f436c90aa169519b8776ec45112a25d575 (diff)
downloadtalos-hostboot-5d0c443dd8e532f2e6779d2b83ce6218db11e000.tar.gz
talos-hostboot-5d0c443dd8e532f2e6779d2b83ce6218db11e000.zip
Update MboxDD to fix up remaining code review comments from handoff.
Added enums for the status control register Added comments in the dd code Removed the check on a read if input buf is larger than the max amount of data read. Made changes to read/write not on a 32bit boundary Remove Mboxdd class and used mbox namespace RTC: 38020 Change-Id: Ia2842a380ed90d370dd1503aa0b189813229c7a4 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/886 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/mbox')
-rw-r--r--src/usr/mbox/mailboxsp.C44
-rw-r--r--src/usr/mbox/mboxdd.C295
-rw-r--r--src/usr/mbox/mboxdd.H209
-rw-r--r--src/usr/mbox/test/mboxddtest.H16
4 files changed, 306 insertions, 258 deletions
diff --git a/src/usr/mbox/mailboxsp.C b/src/usr/mbox/mailboxsp.C
index 601390726..dd5988841 100644
--- a/src/usr/mbox/mailboxsp.C
+++ b/src/usr/mbox/mailboxsp.C
@@ -95,7 +95,7 @@ errlHndl_t MailboxSp::_init()
if(!err)
{
- err = MboxDD::init(iv_trgt);
+ err = mboxInit(iv_trgt);
task_create(MailboxSp::msg_handler, NULL);
}
@@ -160,26 +160,26 @@ void MailboxSp::msgHandler()
TRACDCOMP(g_trac_mbox,"MBOXSP status=%lx",mbox_status);
- if(mbox_status & MboxDD::MBOX_HW_ACK)
+ if(mbox_status & MBOX_HW_ACK)
{
// send next message if there is one.
iv_rts = true;
send_msg();
}
- if(mbox_status & MboxDD::MBOX_DATA_PENDING)
+ if(mbox_status & MBOX_DATA_PENDING)
{
recv_msg(mbox_msg);
}
// Look for error status from MB hardware
- if(mbox_status & MboxDD::MBOX_DOORBELL_ERROR)
+ if(mbox_status & MBOX_DOORBELL_ERROR)
{
TRACFCOMP(g_trac_mbox,
ERR_MRK"MBOX status 0x%lx",
mbox_status);
- if(mbox_status & MboxDD::MBOX_DATA_WRITE_ERR)
+ if(mbox_status & MBOX_DATA_WRITE_ERR)
{
// Write attempted before ACK - HB code error
/*@ errorlog tag
@@ -205,7 +205,7 @@ void MailboxSp::msgHandler()
// will assert later below
}
- else if(mbox_status & MboxDD::MBOX_PARITY_ERR)
+ else if(mbox_status & MBOX_PARITY_ERR)
{
// Hardware detected parity error
// - TODO How does BB handle this error ???
@@ -213,8 +213,8 @@ void MailboxSp::msgHandler()
/*@ errorlog tag
* @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid MOD_MBOXSRV_HNDLR
- * @reasoncode RC_PARITY_ERR
+ * @moduleid MBOX::MOD_MBOXSRV_HNDLR
+ * @reasoncode MBOX::RC_PARITY_ERR
* @userdata1 Status from MB device driver
* @defdesc Mailbox Hardware detected
* parity error.
@@ -232,15 +232,15 @@ void MailboxSp::msgHandler()
errlCommit(err,HBMBOX_COMP_ID);
// err = NULL
}
- else if(mbox_status & MboxDD::MBOX_ILLEGAL_OP)
+ else if(mbox_status & MBOX_ILLEGAL_OP)
{
// Code problem could be FSP or HB
// - log error and continue.
/*@ errorlog tag
* @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid MOD_MBOXSRV_HNDLR
- * @reasoncode RC_ILLEGAL_OP
+ * @moduleid MBOX::MOD_MBOXSRV_HNDLR
+ * @reasoncode MBOX::RC_ILLEGAL_OP
* @userdata1 Status from MB device driver
* @defdesc Retry failed. Bad status
* indicated in PIB status reg.
@@ -259,7 +259,7 @@ void MailboxSp::msgHandler()
// err = NULL
}
- //else if(mbox_status & MboxDD::MBOX_DATA_READ_ERR)
+ //else if(mbox_status & MBOX_DATA_READ_ERR)
//{
// // Read when no message available
// - Just ignore this one per Dean.
@@ -352,8 +352,8 @@ void MailboxSp::msgHandler()
/*@ errorlog tag
* @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid MOD_MBOXSRV_HNDLR
- * @reasoncode RC_INVALID_MBOX_MSG_TYPE
+ * @moduleid MBOX::MOD_MBOXSRV_HNDLR
+ * @reasoncode MBOX::RC_INVALID_MBOX_MSG_TYPE
* @userdata1 Message type
* @defdesc Invalid message type sent to mailbox msgQ
*/
@@ -584,8 +584,8 @@ void MailboxSp::recv_msg(mbox_msg_t & i_mbox_msg)
{
/*@ errorlog tag
* @errortype ERRL_SEV_CRITICAL_SYS_TERM
- * @moduleid MOD_MBOXSRV_RCV
- * @reasoncode RC_INVALID_QUEUE
+ * @moduleid MBOX::MOD_MBOXSRV_RCV
+ * @reasoncode MBOX::RC_INVALID_QUEUE
* @userdata1 rc from msg_send()
* @userdata2 msg queue id
* @defdesc Ivalid msg or msg queue
@@ -632,8 +632,8 @@ void MailboxSp::recv_msg(mbox_msg_t & i_mbox_msg)
/*@ errorlog tag
* @errortype ERRL_SEV_INFORMATIONAL
- * @moduleid MOD_MBOXSRV_RCV
- * @reasoncode RC_INVALID_MESSAGE_TYPE
+ * @moduleid MBOX::MOD_MBOXSRV_RCV
+ * @reasoncode MBOX::RC_INVALID_MESSAGE_TYPE
* @userdata1 msg queue
* @userdata2 msg type
* @defdesc Message from FSP. Message type is not
@@ -678,8 +678,8 @@ void MailboxSp::recv_msg(mbox_msg_t & i_mbox_msg)
/*@ errorlog tag
* @errortype ERRL_SEV_CRITICAL_SYS_TERM
- * @moduleid MOD_MBOXSRV_RCV
- * @reasoncode RC_UNREGISTERED_MSG_QUEUE
+ * @moduleid MBOX::MOD_MBOXSRV_RCV
+ * @reasoncode MBOX::RC_UNREGISTERED_MSG_QUEUE
* @userdata1 msg queueid
* @defdesc msg queue type is not registered with the
* mailbox. Message dropped.
@@ -742,8 +742,8 @@ errlHndl_t MailboxSp::send(queue_id_t i_q_id, msg_t * io_msg)
{
/*@ errorlog tag
* @errortype ERRL_SEV_CRITICAL_SYS_TERM
- * @moduleid MOD_MBOXSRV_SEND
- * @reasoncode RC_INVALID_QUEUE
+ * @moduleid MBOX::MOD_MBOXSRV_SEND
+ * @reasoncode MBOX::RC_INVALID_QUEUE
* @userdata1 returncode from msg_sendrecv()
*
* @defdesc Invalid message or message queue
diff --git a/src/usr/mbox/mboxdd.C b/src/usr/mbox/mboxdd.C
index adf4e2512..7391564e2 100644
--- a/src/usr/mbox/mboxdd.C
+++ b/src/usr/mbox/mboxdd.C
@@ -28,38 +28,10 @@
#include <errl/errlentry.H>
#include <targeting/common/targetservice.H>
-using namespace MBOX;
trace_desc_t* g_trac_mbox = NULL;
TRAC_INIT(&g_trac_mbox, "MBOX", 4096); //4K
-//TODO - May or may not be necessary for MBOX error logs
-uint64_t target_to_uint64(const TARGETING::Target* i_target)
-{
- uint64_t id = 0;
- if( i_target == NULL )
- {
- id = 0x0;
- }
- else if( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL )
- {
- id = 0xFFFFFFFFFFFFFFFF;
- }
- else
- {
- // physical path, 3 nibbles per type/instance pair
- // TIITIITII... etc.
- TARGETING::EntityPath epath;
- i_target->tryGetAttr<TARGETING::ATTR_PHYS_PATH>(epath);
- for( uint32_t x = 0; x < epath.size(); x++ )
- {
- id = id << 12;
- id |= (uint64_t)((epath[x].type << 8) & 0xF00);
- id |= (uint64_t)(epath[x].instance & 0x0FF);
- }
- }
- return id;
-}
namespace MBOX
{
@@ -78,7 +50,6 @@ namespace MBOX
* @param[in/out] io_buflen Input: size of io_buffer (in bytes)
* Output:
* Read: Size of output data
- * Write: Size of data written
* @param[in] i_accessType DeviceFW::AccessType enum (userif.H)
* @param[in] i_args This is an argument list for DD framework.
*
@@ -96,8 +67,7 @@ errlHndl_t ddRead(DeviceFW::OperationType i_opType,
do
{
- l_err = Singleton<MboxDD>::instance().read(i_target,io_buffer,
- io_buflen,o_status);
+ l_err = mboxRead(i_target,io_buffer,io_buflen,o_status);
if (l_err)
{
break;
@@ -120,7 +90,6 @@ errlHndl_t ddRead(DeviceFW::OperationType i_opType,
* Write: Pointer to input data storage
* @param[in/out] io_buflen Input: size of io_buffer (in bytes)
* Output:
- * Read: Size of output data
* Write: Size of data written
* @param[in] i_accessType DeviceFW::AccessType enum (userif.H)
* @param[in] i_args This is an argument list for DD framework.
@@ -138,8 +107,8 @@ errlHndl_t ddWrite(DeviceFW::OperationType i_opType,
do
{
- l_err = Singleton<MboxDD>::instance().write(i_target,io_buffer,
- io_buflen);
+ l_err = mboxWrite(i_target,io_buffer,io_buflen);
+
if(l_err)
{
break;
@@ -160,12 +129,11 @@ DEVICE_REGISTER_ROUTE(DeviceFW::WRITE,
TARGETING::TYPE_PROC,
ddWrite);
-}; //end MBOX namespace
/**
* @brief Performs a mailbox read operation
*/
-errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
+errlHndl_t mboxRead(TARGETING::Target* i_target,void *o_buffer,
size_t &io_buflen,uint64_t* o_status)
{
uint64_t l_stat = 0;
@@ -174,37 +142,22 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
uint32_t l_StatusReg[2] = {0};
uint32_t l_IntReg[2] = {0};
size_t l_64bitSize = sizeof(uint64_t);
- size_t buflen = io_buflen;
+ size_t input_buflen = io_buflen;
io_buflen = 0;
do
{
- if (MBOX_MAX_DATA_BYTES < buflen)
- {
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Invalid data length : io_buflen=%d", buflen);
- /*@
- * @errortype
- * @moduleid MBOX::MOD_MBOXDD_READ
- * @reasoncode MBOX::RC_INVALID_LENGTH
- * @userdata1 Target ID String...
- * @userdata2 Data Length
- * @devdesc MboxDD::read> Invalid data length (< msg_t size)
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MBOX::MOD_MBOXDD_READ,
- MBOX::RC_INVALID_LENGTH,
- target_to_uint64(i_target),
- TO_UINT64(buflen));
- l_err->collectTrace("MBOX",1024);
- break;
- }
+ // no longer check for buffer length.. MBox DD will pass back the max
+ // allowed data if the buflen is > the max size. This is done prior
+ // to reading the data from the mbox registers.
+ // Read the Int Reg B
l_err = deviceOp(DeviceFW::READ,i_target,
l_IntReg,l_64bitSize,
DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to read PIB Interrupt Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to read PIB Interrupt Register");
break;
}
@@ -214,23 +167,28 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
break;
}
+ // Check to see if there is an error bit set.
if ((l_IntReg[0] & MBOX_DOORBELL_ERROR) ==
MBOX_DOORBELL_ERROR)
{
- TRACFCOMP(g_trac_mbox, INFO_MRK "MBOX::read> Found interrupt on error status register");
- l_err = getErrStat(i_target,l_stat);
+ TRACFCOMP(g_trac_mbox, INFO_MRK
+ "mboxRead> Found interrupt on error status register");
+ // Go get the error info
+ l_err = mboxGetErrStat(i_target,l_stat);
+
if (l_err)
{
break;
}
}
+ // No errors so read the doorbell status and control 1a register
l_err = deviceOp(DeviceFW::READ,i_target,
l_64bitBuf,l_64bitSize,
DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to read Doorbell Status/Control Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to read Doorbell Status/Control Register");
break;
}
/*
@@ -248,59 +206,107 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
* Bit11-8 : Header Count LBUS Slave B Doorbell 1
* Bit7-0 : Data Count LBUS Slave B Doorbell 1
*/
- //Check for Xup
+
+ //If the Acknowledge bit is on and the Xup bit is on
if ((l_IntReg[0] & MBOX_HW_ACK) ==
MBOX_HW_ACK &&
- (l_64bitBuf[0] & 0x02000000) == 0x02000000)
+ (l_64bitBuf[0] & MBOX_XUP) == MBOX_XUP)
{
l_stat |= MBOX_HW_ACK;
- l_StatusReg[0] |= 0x02000000;
+ l_StatusReg[0] |= MBOX_XUP;
}
- //Check for PIB Pending
+ //Check for PIB Pending. If PIB pending is found then we need
+ // to go read the data from the mailbox registers.
if ((l_IntReg[0] & MBOX_DATA_PENDING) ==
MBOX_DATA_PENDING &&
- (l_64bitBuf[0] & 0x10000000) == 0x10000000)
+ (l_64bitBuf[0] & MBOX_PIB_SLAVE_A_PND) == MBOX_PIB_SLAVE_A_PND)
{
l_stat |= MBOX_DATA_PENDING;
- //Read how many bytes are significant
- io_buflen = (l_64bitBuf[0] & 0x000000FF);
- if (buflen < io_buflen)
+
+ //Set the io_buflen to the number of bytes of data available to
+ // be read.
+ io_buflen = (l_64bitBuf[0] & MBOX_DATA_LBUS_SLAVE_B);
+
+ // If the buffer length passed in is less than the data size read,
+ // then set the buffer length to the passed in size and only read
+ // that much data. (truncate the data to fit into the buffer)
+ // Conversely, if the input_buflen is greater than the size of the
+ // data read, the io_buflen returned to the user becomes the size
+ // of the data read.
+ if (input_buflen < io_buflen)
{
- TRACFCOMP(g_trac_mbox, INFO_MRK "MBOX::read> Data truncated, input buffer length less than number of significant bytes");
- io_buflen = buflen;
+ TRACFCOMP(g_trac_mbox, INFO_MRK
+
+ "mboxRead> Data truncated, input buffer length less than number of significant bytes");
+ // set the io_buflen to the size of the buffer passed in.
+ // which will only read enough data to fill the buffer.
+ io_buflen = input_buflen;
}
- uint32_t i = 0;
+
+ // Current register counter indicating which of the mbox registers
+ // we are currently reading from.
+ uint32_t cur_reg_cntr = 0;
uint32_t l_data[2];
- uint8_t l_numRegs = (io_buflen*sizeof(uint8_t))/sizeof(uint32_t);
- if ((io_buflen*sizeof(uint8_t))%sizeof(uint32_t) != 0) l_numRegs++;
- uint8_t *l_buf = static_cast<uint8_t *>(o_buffer);
- //Extract Data
- while (i < l_numRegs)
+
+ // Total number of registers to read to get all the data.
+ uint8_t l_numRegsToRead = (io_buflen*sizeof(uint8_t))/sizeof(uint32_t);
+
+ uint8_t l_numBytesLeft =
+ (io_buflen*sizeof(uint8_t))%sizeof(uint32_t);
+
+ if (l_numBytesLeft != 0)
+ {
+ l_numRegsToRead++;
+ }
+
+ uint32_t *local_buf = static_cast<uint32_t *>(o_buffer);
+ // For the read we extract the data from the MBOX data registers.
+ // MBOX_DATA_LBUS_START = 0x00050080 and the end address is
+ // MBOX_DATA_LBUS_END = 0x0005008F
+ // each address inbetween increments by 1.
+
+ //Loop through the mbox registers until all the data to be read has
+ // been extracted from the mbox registers.
+ while (cur_reg_cntr < l_numRegsToRead)
{
l_err = deviceOp(DeviceFW::READ,i_target,
l_data,l_64bitSize,
- DEVICE_XSCOM_ADDRESS(MBOX_DATA_LBUS_START+i));
+ DEVICE_XSCOM_ADDRESS(MBOX_DATA_LBUS_START+cur_reg_cntr));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to read Data Area Register 0x%X",MBOX_DATA_LBUS_START+i);
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to read Data Area Register 0x%X",MBOX_DATA_LBUS_START+cur_reg_cntr);
break;
}
- //TODO Use memcpy() since byte aligned?
- for (uint8_t byteNum = 0;byteNum<sizeof(uint32_t);++byteNum)
+
+ // Need to check here to make sure we are not overrunning our
+ // buffer.
+
+ // If this is the last register we need to read and we are not word aligned
+ if ((cur_reg_cntr -1 == l_numRegsToRead) &&
+ (l_numBytesLeft != 0))
{
- *(l_buf+(byteNum+i*sizeof(uint32_t))) =
- (l_data[0]>>(sizeof(uint32_t)*8-(byteNum+1)*8) & 0x000000FF);
+ // Only copy the number of bytes remaining..
+ memcpy( local_buf + cur_reg_cntr,
+ &l_data[0], l_numBytesLeft);
}
- i++;
+ // normal copy path.. copy the entire word.
+ else
+ {
+ memcpy( local_buf + cur_reg_cntr, &l_data[0], sizeof(uint32_t));
+ }
+
+ cur_reg_cntr++;
}
if (l_err)
{
break;
}
- //Write-to-Clear PIB Pending,and bits 20-32 (data and header count)
- //Write to set Xup
- l_StatusReg[0] |= 0x14000FFF;
+ //Write-to-Clear Xup,and bits 20-32 (data and header count)
+ //Write to set Xup (by setting PIB_SLAVE_PND)
+ //Write the Xdn to indicate read is done
+ l_StatusReg[0] |= MBOX_PIB_SLAVE_A_PND | MBOX_XDN |
+ MBOX_HDR_LBUS_SLAVE_B | MBOX_DATA_LBUS_SLAVE_B;
}
@@ -312,7 +318,7 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to clear Doorbell Status/Control Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to clear Doorbell Status/Control Register");
break;
}
}
@@ -325,7 +331,7 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to clear PIB Interrupt Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxRead> Unable to clear PIB Interrupt Register");
break;
}
}
@@ -340,7 +346,7 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
/**
* @brief Performs a mailbox write operation
*/
-errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
+errlHndl_t mboxWrite(TARGETING::Target* i_target,void* i_buffer,
size_t& i_buflen)
{
errlHndl_t l_err = NULL;
@@ -349,7 +355,8 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
do
{
- //Expect size in bytes
+ //If the expected siZe in bytes is bigger than the max data allowed
+ // send back an error.
if (i_buflen > MBOX_MAX_DATA_BYTES)
{
TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Invalid data length : i_buflen=%d", i_buflen);
@@ -364,18 +371,23 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MBOX::MOD_MBOXDD_WRITE,
MBOX::RC_INVALID_LENGTH,
- target_to_uint64(i_target),
+ TARGETING::get_huid(i_target),
TO_UINT64(i_buflen));
l_err->collectTrace("MBOX",1024);
+
+ // Set the i_buflen to 0 to indicate no write occured
+ i_buflen = 0;
+
break;
}
+ // read the DB_STATUS_1A_REG: doorbell status and control 1a
l_err = deviceOp(DeviceFW::READ,i_target,
l_64bitBuf,l_64bitSize,
DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to read Doorbell Status/Control Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Unable to read Doorbell Status/Control Register");
break;
}
@@ -394,47 +406,91 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
* Bit11-8 : Header Count LBUS Slave B Doorbell 1
* Bit7-0 : Data Count LBUS Slave B Doorbell 1
*/
- //Verify LBUS Pending,
- if ((l_64bitBuf[0] & 0x20FFF000) == 0)
+
+ //Verify There is no LBUS Pending,
+ if ((l_64bitBuf[0] &
+ (MBOX_LBUS_SLAVE_B_PND | MBOX_HDR_PIB_SLAVE_A | MBOX_DATA_PIB_SLAVE_A)) == 0)
{
- uint32_t i = 0;
+ // Current register counter indicating which of the mbox registers
+ // to write to
+ uint32_t cur_reg_cntr = 0;
uint32_t l_data[2] = {0};
- uint8_t l_numRegs = (i_buflen*sizeof(uint8_t))/sizeof(uint32_t);
- if ((i_buflen*sizeof(uint8_t))%sizeof(uint32_t) != 0) l_numRegs++;
+
+ // Total number of registers to read to get all the data.
+ uint8_t l_numRegsToWrite = (i_buflen*sizeof(uint8_t))/sizeof(uint32_t);
+
+ uint8_t l_numBytesLeft =
+ (i_buflen*sizeof(uint8_t))%sizeof(uint32_t);
+
+ if (l_numBytesLeft != 0)
+ {
+ l_numRegsToWrite++;
+ }
+
uint32_t *l_buf = static_cast<uint32_t *>(i_buffer);
- //Write Data registers
- while (i < l_numRegs)
+
+ // For the write we put the data into the MBOX data registers.
+ // MBOX_DATA_PIB_START = 0x00050040 and the end address is
+ // MBOX_DATA_PIB_END = 0x0005004F
+ // each address inbetween increments by 1.
+
+ //Write Data registers. Start at the first and increment through
+ //the registers until all the data has been written.
+ while (cur_reg_cntr < l_numRegsToWrite)
{
- l_data[0] = *(l_buf+i);
+
+ // If this is the last register we need to write and are not word aligned
+ if ((cur_reg_cntr -1 == l_numRegsToWrite) &&
+ (l_numBytesLeft != 0))
+ {
+ // zero out the data reg.
+ l_data[0] = 0;
+
+ // Only copy the number of bytes remaining..
+ memcpy(&l_data[0], l_buf+cur_reg_cntr,l_numBytesLeft);
+
+ }
+ else
+ {
+ // point to the next 32bits of data in the buffer.
+ l_data[0] = *(l_buf+cur_reg_cntr);
+
+ }
+
l_err = deviceOp(DeviceFW::WRITE,i_target,
l_data,l_64bitSize,
- DEVICE_XSCOM_ADDRESS(MBOX_DATA_PIB_START+i));
+ DEVICE_XSCOM_ADDRESS(MBOX_DATA_PIB_START+cur_reg_cntr));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to write Data Area Register 0x%X",MBOX_DATA_PIB_START+i);
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Unable to write Data Area Register 0x%X",MBOX_DATA_PIB_START+cur_reg_cntr);
break;
}
- i++;
+ //increment counter so we are at the next register
+ cur_reg_cntr++;
}
if (l_err)
{
break;
}
- //Write LBUS Pending(28) and Data Count bits(11-0)
- l_64bitBuf[0] = 0x20000000 | (0x000FF000 & (i_buflen << 12));
+ //Write LBUS Pending(28) and Data Count bits(11-0) to indicate
+ // data has been written.
+ l_64bitBuf[0] = MBOX_LBUS_SLAVE_B_PND | (MBOX_DATA_PIB_SLAVE_A &
+ (i_buflen << 12));
+
l_err = deviceOp(DeviceFW::WRITE,i_target,
l_64bitBuf,l_64bitSize,
DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
+
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to set Doorbell Status/Control Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Unable to set Doorbell Status/Control Register");
break;
}
}
else
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Message still pending : MBOX_DB_STAT_CNTRL_1=%X", l_64bitBuf[0]);
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxWrite> Message still pending : MBOX_DB_STAT_CNTRL_1=%X", l_64bitBuf[0]);
/*@
* @errortype
* @moduleid MBOX::MOD_MBOXDD_WRITE
@@ -446,7 +502,7 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
MBOX::MOD_MBOXDD_WRITE,
MBOX::RC_MSG_PENDING,
- target_to_uint64(i_target),
+ TARGETING::get_huid(i_target),
reinterpret_cast<uint64_t>(l_64bitBuf));
l_err->collectTrace("MBOX",1024);
break;
@@ -460,7 +516,7 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
/**
* @brief Reads the mailbox PIB error status register
*/
-errlHndl_t MboxDD::getErrStat(TARGETING::Target* i_target,uint64_t &o_status)
+errlHndl_t mboxGetErrStat(TARGETING::Target* i_target,uint64_t &o_status)
{
errlHndl_t l_err = NULL;
uint32_t l_64bitBuf[2] = {0};
@@ -473,7 +529,7 @@ errlHndl_t MboxDD::getErrStat(TARGETING::Target* i_target,uint64_t &o_status)
DEVICE_XSCOM_ADDRESS(MBOX_DB_ERR_STAT_PIB));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::getErrStat> Unable to read PIB Error Status");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxGetErrStat> Unable to read PIB Error Status");
break;
}
else
@@ -512,7 +568,7 @@ errlHndl_t MboxDD::getErrStat(TARGETING::Target* i_target,uint64_t &o_status)
DEVICE_XSCOM_ADDRESS(MBOX_DB_ERR_STAT_PIB));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::getErrStat> Unable to clear PIB Error Status");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "mboxGetErrStat> Unable to clear PIB Error Status");
break;
}
@@ -521,15 +577,8 @@ errlHndl_t MboxDD::getErrStat(TARGETING::Target* i_target,uint64_t &o_status)
return l_err;
}
-/**
- * @brief Constructor
- */
-MboxDD::MboxDD()
-{
- TRACFCOMP(g_trac_mbox, "MboxDD::MboxDD()> ");
-}
-errlHndl_t MboxDD::init(TARGETING::Target* i_target)
+errlHndl_t mboxInit(TARGETING::Target* i_target)
{
errlHndl_t err = NULL;
// Setup mailbox intr mask reg
@@ -552,9 +601,5 @@ errlHndl_t MboxDD::init(TARGETING::Target* i_target)
}
-/**
- * @brief Destructor
- */
-MboxDD::~MboxDD()
-{
-}
+
+}; //end MBOX namespace
diff --git a/src/usr/mbox/mboxdd.H b/src/usr/mbox/mboxdd.H
index 5fa291178..ac5063d14 100644
--- a/src/usr/mbox/mboxdd.H
+++ b/src/usr/mbox/mboxdd.H
@@ -32,118 +32,121 @@
namespace MBOX
{
-class MboxDD
-{
-
- public:
-
- /*
- * Mbox device driver public constants
- */
- enum
- {
- MBOX_MAX_DATA_BYTES = 64, //16 32-bit Data Registers
- };
-
- /*
- * Mbox device driver status values
- */
- enum MboxReadStatus
- {
- MBOX_DOORBELL_ERROR = 0x00000004, /* Error Set In Error Register */
- MBOX_HW_ACK = 0x00000002, /* LBUS Data Acknowledgment */
- MBOX_DATA_PENDING = 0x00000001, /* PIB Data Pending */
- MBOX_ILLEGAL_OP = 0x08000000, /* Illegal Operation Attempted */
- MBOX_DATA_WRITE_ERR = 0x04000000, /* Write Full LBUS Mailbox Error */
- MBOX_DATA_READ_ERR = 0x02000000, /* Read Empty LBUS Mailbox Error */
- MBOX_PARITY_ERR = 0x01000000, /* LBUS RAM Parity Error Detected */
- };
-
- static errlHndl_t init(TARGETING::Target* i_target);
-
- /**
- * @brief Performs a mailbox read operation
- *
- * @param[in] i_target - Chip target of MBOX operation
- * @param[out] o_buffer - Destination buffer for data
- * @param[in/out] io_buflen - Size of buffer
- * @param[out] o_status - Contains any error status bits
- *
- * @return errlHndl_t NULL on success
- */
- errlHndl_t read(TARGETING::Target* i_target,
+ /*
+ * Mbox device driver public constants
+ */
+ enum
+ {
+ MBOX_MAX_DATA_BYTES = 64, //16 32-bit Data Registers
+ };
+
+ /*
+ * Mbox device driver status values
+ */
+ enum MboxReadStatus
+ {
+ MBOX_DOORBELL_ERROR = 0x00000004, /* Error Set In Error Register */
+ MBOX_HW_ACK = 0x00000002, /* LBUS Data Acknowledgment */
+ MBOX_DATA_PENDING = 0x00000001, /* PIB Data Pending */
+ MBOX_ILLEGAL_OP = 0x08000000, /* Illegal Operation Attempted */
+ MBOX_DATA_WRITE_ERR = 0x04000000, /* Write Full LBUS Mailbox Error */
+ MBOX_DATA_READ_ERR = 0x02000000, /* Read Empty LBUS Mailbox Error */
+ MBOX_PARITY_ERR = 0x01000000, /* LBUS RAM Parity Error Detected */
+ };
+
+ errlHndl_t mboxInit(TARGETING::Target* i_target);
+
+ /**
+ * @brief Performs a mailbox read operation
+ *
+ * @param[in] i_target - Chip target of MBOX operation
+ * @param[out] o_buffer - Destination buffer for data
+ * @param[in/out] io_buflen - Size of buffer
+ * @param[out] o_status - Contains any error status bits
+ *
+ * @return errlHndl_t NULL on success
+ */
+ errlHndl_t mboxRead(TARGETING::Target* i_target,
void* o_buffer,
size_t& io_buflen,
uint64_t* o_status);
- /**
- * @brief Performs a mailbox write operation
- *
- * @param[in] i_target - Chip target of MBOX operation
- * @param[in] i_buffer - Location of data to be written
- * @param[in] i_buflen - Size of data
- *
- * @return errlHndl_t NULL on success
- */
- errlHndl_t write(TARGETING::Target* i_target,
+ /**
+ * @brief Performs a mailbox write operation
+ *
+ * @param[in] i_target - Chip target of MBOX operation
+ * @param[in] i_buffer - Location of data to be written
+ * @param[in] i_buflen - Size of data
+ *
+ * @return errlHndl_t NULL on success
+ */
+ errlHndl_t mboxWrite(TARGETING::Target* i_target,
void* i_buffer,
size_t& i_buflen);
- /**
- * @brief Reads the mailbox PIB error status register
- *
- * @param[in] i_target - Chip target of MBOX operation
- * @param[out] o_status - Bits set to errors found
- */
- errlHndl_t getErrStat(TARGETING::Target* i_target,
+ /**
+ * @brief Reads the mailbox PIB error status register
+ *
+ * @param[in] i_target - Chip target of MBOX operation
+ * @param[out] o_status - Bits set to errors found
+ */
+ errlHndl_t mboxGetErrStat(TARGETING::Target* i_target,
uint64_t &o_status);
- protected:
-
- /**
- * @brief Constructor
- */
- MboxDD();
-
- /**
- * @brief Destructor
- */
- ~MboxDD();
-
- private:
-
- //Mailbox 1 Status & Interrupt register addresses
- enum MboxRegs {
- MBOX_DB_STAT_CNTRL_1 = 0x00050020, //LBUS(rw),PIB(rw) Stat/Cntrl 1
- MBOX_DB_ERR_STAT_PIB = 0x00050031, //LBUS(ro),PIB(rw) Err Stat B
- MBOX_DB_ERR_STAT_LBUS = 0x00050030, //LBUS(rw),PIB(ro) Err Stat A
- MBOX_DB_INT_REG_LBUS = 0x00050035, //LBUS(rw),PIB(ro) Int Reg A
- MBOX_DB_INT_MASK_LBUS_RS = 0x00050036, //LBUS(r/set),PIB(ro) Int Mask A
- MBOX_DB_INT_MASK_LBUS_RC = 0x00050037, //LBUS(r/clear),PIB(ro/zero)
- MBOX_DB_INT_REG_PIB = 0x00050032, //LBUS(ro),PIB(rw) Int Reg B
- MBOX_DB_INT_MASK_PIB_RS = 0x00050033, //LBUS(ro),PIB(r/set) Int Mask B
- MBOX_DB_INT_MASK_PIB_RC = 0x00050034, //LBUS(ro/zero,PIB(r/clear)
- };
-
- //Mailbox 1 Header/Command register addresses
- enum MboxHeadCmdRegs {
- MBOX_HEAD_CMD_LBUS0 = 0x00050025, //LBUS(rw),PIB(ro) H/C 0A
- MBOX_HEAD_CMD_LBUS1 = 0x00050026, //LBUS(rw),PIB(ro) H/C 1A
- MBOX_HEAD_CMD_LBUS2 = 0x00050027, //LBUS(rw),PIB(ro) H/C 2A
- MBOX_HEAD_CMD_PIB0 = 0x00050021, //LBUS(ro),PIB(rw) H/C 0B
- MBOX_HEAD_CMD_PIB1 = 0x00050022, //LBUS(ro),PIB(rw) H/C 1B
- MBOX_HEAD_CMD_PIB2 = 0x00050023, //LBUS(ro),PIB(rw) H/C 2B
- };
-
- //Mailbox 1 Data register address boundaries
- enum MboxDataRegs {
- MBOX_DATA_LBUS_START = 0x00050080, //LBUS(rw),PIB(ro) First address
- MBOX_DATA_LBUS_END = 0x0005008F, //LBUS(rw),PIB(ro) Last address
- MBOX_DATA_PIB_START = 0x00050040, //LBUS(ro),PIB(rw) First address
- MBOX_DATA_PIB_END = 0x0005004F, //LBUS(ro),PIB(rw) Last address
- };
-
-};
+
+ //Mailbox 1 Status & Interrupt register addresses
+ enum MboxRegs {
+ MBOX_DB_STAT_CNTRL_1 = 0x00050020, //LBUS(rw),PIB(rw) Stat/Cntrl 1
+ MBOX_DB_ERR_STAT_PIB = 0x00050031, //LBUS(ro),PIB(rw) Err Stat B
+ MBOX_DB_ERR_STAT_LBUS = 0x00050030, //LBUS(rw),PIB(ro) Err Stat A
+ MBOX_DB_INT_REG_LBUS = 0x00050035, //LBUS(rw),PIB(ro) Int Reg A
+ MBOX_DB_INT_MASK_LBUS_RS = 0x00050036, //LBUS(r/set),PIB(ro) Int Mask A
+ MBOX_DB_INT_MASK_LBUS_RC = 0x00050037, //LBUS(r/clear),PIB(ro/zero)
+ MBOX_DB_INT_REG_PIB = 0x00050032, //LBUS(ro),PIB(rw) Int Reg B
+ MBOX_DB_INT_MASK_PIB_RS = 0x00050033, //LBUS(ro),PIB(r/set) Int Mask B
+ MBOX_DB_INT_MASK_PIB_RC = 0x00050034, //LBUS(ro/zero,PIB(r/clear)
+ };
+
+ //Mailbox 1 Header/Command register addresses
+ enum MboxHeadCmdRegs {
+ MBOX_HEAD_CMD_LBUS0 = 0x00050025, //LBUS(rw),PIB(ro) H/C 0A
+ MBOX_HEAD_CMD_LBUS1 = 0x00050026, //LBUS(rw),PIB(ro) H/C 1A
+ MBOX_HEAD_CMD_LBUS2 = 0x00050027, //LBUS(rw),PIB(ro) H/C 2A
+ MBOX_HEAD_CMD_PIB0 = 0x00050021, //LBUS(ro),PIB(rw) H/C 0B
+ MBOX_HEAD_CMD_PIB1 = 0x00050022, //LBUS(ro),PIB(rw) H/C 1B
+ MBOX_HEAD_CMD_PIB2 = 0x00050023, //LBUS(ro),PIB(rw) H/C 2B
+ };
+
+ //Mailbox 1 Data register address boundaries
+ enum MboxDataRegs {
+ MBOX_DATA_LBUS_START = 0x00050080, //LBUS(rw),PIB(ro) First address
+ MBOX_DATA_LBUS_END = 0x0005008F, //LBUS(rw),PIB(ro) Last address
+ MBOX_DATA_PIB_START = 0x00050040, //LBUS(ro),PIB(rw) First address
+ MBOX_DATA_PIB_END = 0x0005004F, //LBUS(ro),PIB(rw) Last address
+ };
+
+ // DB_STATUS_1A_REG: doorbell status and control 1a bit masks
+ enum MboxDBStausReg1a {
+ MBOX_PERM_TO_SND = 0x80000000, //Permission to Send Doorbell
+ MBOX_ABORT = 0x40000000, //Abort Doorbell 1
+ MBOX_LBUS_SLAVE_B_PND = 0x20000000, //Lbus save B pending
+ // Doorbell 1
+ MBOX_PIB_SLAVE_A_PND = 0x10000000, //PIB Slave A Pending
+ // DoorBell 1
+ // bit 27 - reserved
+ MBOX_XDN = 0x04000000, //Xdn Doorbell 1
+ MBOX_XUP = 0x02000000, //Xup Doorbell 1
+ // bit 24 - reserved
+ MBOX_HDR_PIB_SLAVE_A = 0x00F00000, // Header Count PIB Slave A
+ // Doorbell 1
+ MBOX_DATA_PIB_SLAVE_A = 0x000FF000, // Data Count PIB Slave A
+ // Doorbell 1
+ MBOX_HDR_LBUS_SLAVE_B = 0x00000F00, // Header Count LBUS Slave B
+ // Doorbell 1
+ MBOX_DATA_LBUS_SLAVE_B =0x000000FF, // Data Count LBUS Slave B
+ }; // Doorbell 1
+
+
}; // namespace MBOX
#endif
diff --git a/src/usr/mbox/test/mboxddtest.H b/src/usr/mbox/test/mboxddtest.H
index 5b6c7e0fa..d60eb5e68 100644
--- a/src/usr/mbox/test/mboxddtest.H
+++ b/src/usr/mbox/test/mboxddtest.H
@@ -302,7 +302,7 @@ class MboxDDTest : public CxxTest::TestSuite
TRACFCOMP(g_trac_mbox, "MboxDDTest::testWRPoll> Waiting for FSP to send # tests...");
/* Wait for FSP to ack message before starting the test*/
- while ((o_status & MboxDD::MBOX_DATA_PENDING) != MboxDD::MBOX_DATA_PENDING)
+ while ((o_status & MBOX_DATA_PENDING) != MBOX_DATA_PENDING)
{
read_size = CTL_SIZE * sizeof(uint32_t);
l_err = readMessage(my_target, read_mboxMsg, read_size, o_status);
@@ -349,7 +349,7 @@ class MboxDDTest : public CxxTest::TestSuite
}
/*If we have a message for us, process it*/
- if(o_status & MboxDD::MBOX_DATA_PENDING)
+ if(o_status & MBOX_DATA_PENDING)
{
if(!read_size)
{
@@ -384,7 +384,7 @@ class MboxDDTest : public CxxTest::TestSuite
/*see if we can send a message to the FSP*/
- if ((o_status & MboxDD::MBOX_HW_ACK) && (num_msg_send || reply_num))
+ if ((o_status & MBOX_HW_ACK) && (num_msg_send || reply_num))
{
TRACFCOMP(g_trac_mbox, "MboxDDTest::testWRPoll> Send msg -- reply_num[%d] send_num[%d]",
reply_num, num_msg_send);
@@ -478,10 +478,10 @@ class MboxDDTest : public CxxTest::TestSuite
}
TRACFCOMP(g_trac_mbox, "MboxDDTest::testWRInt> Enable interrupts on MBOX");
- l_err = MboxDD::init(my_target);
+ l_err = mboxInit(my_target);
if(l_err)
{
- TS_FAIL("Errl from MboxDD::init()");
+ TS_FAIL("Errl from MboxInit()");
delete l_err;
l_err = NULL;
}
@@ -501,7 +501,7 @@ class MboxDDTest : public CxxTest::TestSuite
/*Ack the IRQ*/
msg_respond(msgQ,msg);
- if ((o_status & MboxDD::MBOX_DATA_PENDING) != MboxDD::MBOX_DATA_PENDING
+ if ((o_status & MBOX_DATA_PENDING) != MBOX_DATA_PENDING
|| !read_size)
{
TS_FAIL("First message Unable to read FSP control response\n");
@@ -550,7 +550,7 @@ class MboxDDTest : public CxxTest::TestSuite
msg_respond(msgQ,msg);
/*If we have a message for us, process it*/
- if(o_status & MboxDD::MBOX_DATA_PENDING)
+ if(o_status & MBOX_DATA_PENDING)
{
if(!read_size)
{
@@ -585,7 +585,7 @@ class MboxDDTest : public CxxTest::TestSuite
/*see if we can send a message to the FSP*/
- if ((o_status & MboxDD::MBOX_HW_ACK) && (num_msg_send || reply_num))
+ if ((o_status & MBOX_HW_ACK) && (num_msg_send || reply_num))
{
TRACFCOMP(g_trac_mbox, "MboxDDTest::testWRInt> Send msg -- reply_num[%d] send_num[%d]",
reply_num, num_msg_send);
OpenPOWER on IntegriCloud