summaryrefslogtreecommitdiffstats
path: root/src/usr/mbox/mboxdd.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/mbox/mboxdd.C')
-rw-r--r--src/usr/mbox/mboxdd.C230
1 files changed, 129 insertions, 101 deletions
diff --git a/src/usr/mbox/mboxdd.C b/src/usr/mbox/mboxdd.C
index 441925fd1..3c41dee34 100644
--- a/src/usr/mbox/mboxdd.C
+++ b/src/usr/mbox/mboxdd.C
@@ -28,6 +28,8 @@
#include <errl/errlentry.H>
#include <targeting/targetservice.H>
+using namespace MBOX;
+
trace_desc_t* g_trac_mbox = NULL;
TRAC_INIT(&g_trac_mbox, "MBOX", 4096); //4K
@@ -169,14 +171,17 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
uint64_t l_stat = 0;
errlHndl_t l_err = NULL;
uint32_t l_64bitBuf[2] = {0};
+ uint32_t l_StatusReg[2] = {0};
uint32_t l_IntReg[2] = {0};
size_t l_64bitSize = sizeof(uint64_t);
+ size_t buflen = io_buflen;
+ io_buflen = 0;
do
{
- if (MBOX::MBOX_MAX_DATA_BYTES < io_buflen)
+ if (MBOX_MAX_DATA_BYTES < buflen)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Invalid data length : io_buflen=%d", io_buflen);
+ TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Invalid data length : io_buflen=%d", buflen);
/*@
* @errortype
* @moduleid MBOX::MOD_MBOXDD_READ
@@ -189,7 +194,7 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
MBOX::MOD_MBOXDD_READ,
MBOX::RC_INVALID_LENGTH,
target_to_uint64(i_target),
- TO_UINT64(io_buflen));
+ TO_UINT64(buflen));
l_err->collectTrace("MBOX",1024);
break;
}
@@ -202,8 +207,15 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to read PIB Interrupt Register");
break;
}
- if ((l_IntReg[0] & MBOX::MBOX_DOORBELL_ERROR) ==
- MBOX::MBOX_DOORBELL_ERROR)
+
+ /*if nothing on in the interrupt reg -- nothing for this function to do*/
+ if(!(l_IntReg[0]))
+ {
+ break;
+ }
+
+ 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);
@@ -237,29 +249,33 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
* Bit7-0 : Data Count PIB Slave B Doorbell 1
*/
//Check for Abort
- if ((l_IntReg[0] & MBOX::MBOX_ABORT_LAST_MSG) ==
- MBOX::MBOX_ABORT_LAST_MSG &&
+ if ((l_IntReg[0] & MBOX_ABORT_LAST_MSG) ==
+ MBOX_ABORT_LAST_MSG &&
(l_64bitBuf[0] & 0x40000000) == 0x40000000)
{
- l_stat |= MBOX::MBOX_ABORT_LAST_MSG;
+ l_stat |= MBOX_ABORT_LAST_MSG;
+ l_StatusReg[0] |= 0x40000000;
}
//Check for Xdn
- if ((l_IntReg[0] & MBOX::MBOX_XDN_ACK) ==
- MBOX::MBOX_XDN_ACK &&
+ if ((l_IntReg[0] & MBOX_XDN_ACK) ==
+ MBOX_XDN_ACK &&
(l_64bitBuf[0] & 0x04000000) == 0x04000000)
{
- l_stat |= MBOX::MBOX_XDN_ACK;
+ l_stat |= MBOX_XDN_ACK;
+ l_StatusReg[0] |= 0x04000000;
}
//Check for PIB Pending
- if ((l_IntReg[0] & MBOX::MBOX_DATA_PENDING) ==
- MBOX::MBOX_DATA_PENDING &&
+ if ((l_IntReg[0] & MBOX_DATA_PENDING) ==
+ MBOX_DATA_PENDING &&
(l_64bitBuf[0] & 0x20000000) == 0x20000000)
{
- l_stat |= MBOX::MBOX_DATA_PENDING;
+ l_stat |= MBOX_DATA_PENDING;
//Read how many bytes are significant
- if (io_buflen < ((l_64bitBuf[0] & 0x000FF000) >> 12))
+ io_buflen = ((l_64bitBuf[0] & 0x000FF000) >> 12);
+ if (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;
}
uint32_t i = 0;
uint32_t l_data[2];
@@ -290,10 +306,17 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
break;
}
- //Write-to-Clear PIB Pending,Xup,and bits 23-12
- l_64bitBuf[0] = 0x22FFF000;
+ //Write-to-Clear PIB Pending,and bits 23-12 (data and header count)
+ //Write to set Xup
+ l_StatusReg[0] |= 0x22FFF000;
+ }
+
+
+ //Write to clear PIB Pending, Abort, and Xdn (all that apply)
+ if(l_StatusReg[0])
+ {
l_err = deviceOp(DeviceFW::WRITE,i_target,
- l_64bitBuf,l_64bitSize,
+ l_StatusReg,l_64bitSize,
DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
if (l_err)
{
@@ -303,18 +326,22 @@ errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer,
}
//Write-to-Clear 'on' bits of interrupt reg
- l_err = deviceOp(DeviceFW::WRITE,i_target,
- l_IntReg,l_64bitSize,
- DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_REG_PIB));
- if (l_err)
+ if(l_IntReg[0])
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to clear PIB Interrupt Register");
- break;
+ l_err = deviceOp(DeviceFW::WRITE,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 clear PIB Interrupt Register");
+ break;
+ }
}
- (*o_status) = l_stat;
-
} while(0);
+ (*o_status) = l_stat;
+
+
return l_err;
}
@@ -331,7 +358,7 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
do
{
//Expect size in bytes
- if (i_buflen > MBOX::MBOX_MAX_DATA_BYTES)
+ if (i_buflen > MBOX_MAX_DATA_BYTES)
{
TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Invalid data length : i_buflen=%d", i_buflen);
/*@
@@ -343,17 +370,17 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
* @devdesc MboxDD::write> Invalid data length (> msg_t size)
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MBOX::MOD_MBOXDD_WRITE,
- MBOX::RC_INVALID_LENGTH,
- target_to_uint64(i_target),
- TO_UINT64(i_buflen));
+ MBOX::MOD_MBOXDD_WRITE,
+ MBOX::RC_INVALID_LENGTH,
+ target_to_uint64(i_target),
+ TO_UINT64(i_buflen));
l_err->collectTrace("MBOX",1024);
break;
}
l_err = deviceOp(DeviceFW::READ,i_target,
- l_64bitBuf,l_64bitSize,
- DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
+ 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");
@@ -375,83 +402,60 @@ errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer,
* Bit11-8 : Header Count PIB Slave B Doorbell 1
* Bit7-0 : Data Count PIB Slave B Doorbell 1
*/
- //Verify Permission-to-Send
- if ((l_64bitBuf[0] & 0x80000000) == 0x80000000)
+ //Verify LBUS Pending,
+ if ((l_64bitBuf[0] & 0x10000FFF) == 0)
{
- //Verify LBUS Pending,
- if ((l_64bitBuf[0] & 0x10000FFF) == 0)
+ uint32_t i = 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++;
+ uint32_t *l_buf = static_cast<uint32_t *>(i_buffer);
+ //Write Data registers
+ while (i < l_numRegs)
{
- uint32_t i = 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++;
- uint32_t *l_buf = static_cast<uint32_t *>(i_buffer);
- //Write Data registers
- while (i < l_numRegs)
- {
- l_data[0] = *(l_buf+i);
- l_err = deviceOp(DeviceFW::WRITE,i_target,
- l_data,l_64bitSize,
- DEVICE_XSCOM_ADDRESS(MBOX_DATA_PIB_START+i));
- if (l_err)
- {
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to write Data Area Register 0x%X",MBOX_DATA_PIB_START+i);
- break;
- }
- i++;
- }
- if (l_err)
- {
- break;
- }
-
- //Write LBUS Pending(28) and Data Count bits(11-0)
- l_64bitBuf[0] = 0x10000000 | i_buflen;
+ l_data[0] = *(l_buf+i);
l_err = deviceOp(DeviceFW::WRITE,i_target,
- l_64bitBuf,l_64bitSize,
- DEVICE_XSCOM_ADDRESS(MBOX_DB_STAT_CNTRL_1));
+ l_data,l_64bitSize,
+ DEVICE_XSCOM_ADDRESS(MBOX_DATA_PIB_START+i));
if (l_err)
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to set Doorbell Status/Control Register");
+ TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to write Data Area Register 0x%X",MBOX_DATA_PIB_START+i);
break;
}
+ i++;
+ }
+ if (l_err)
+ {
+ break;
}
- else
+
+ //Write LBUS Pending(28) and Data Count bits(11-0)
+ l_64bitBuf[0] = 0x10000000 | i_buflen;
+ 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> Message still pending : MBOX_DB_STAT_CNTRL_1=%X", l_64bitBuf[0]);
- /*@
- * @errortype
- * @moduleid MBOX::MOD_MBOXDD_WRITE
- * @reasoncode MBOX::RC_MSG_PENDING
- * @userdata1 Target ID String...
- * @userdata2 Status/Control Register
- * @devdesc MboxDD::write> Message still pending
- */
- l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MBOX::MOD_MBOXDD_WRITE,
- MBOX::RC_MSG_PENDING,
- target_to_uint64(i_target),
- reinterpret_cast<uint64_t>(l_64bitBuf));
- l_err->collectTrace("MBOX",1024);
+ TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to set Doorbell Status/Control Register");
break;
}
}
else
{
- TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Permission-to-Send bit not set : MBOX_DB_STAT_CNTRL_1=%X", l_64bitBuf[0]);
+ TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Message still pending : MBOX_DB_STAT_CNTRL_1=%X", l_64bitBuf[0]);
/*@
* @errortype
* @moduleid MBOX::MOD_MBOXDD_WRITE
- * @reasoncode MBOX::RC_NO_PERM_TO_SEND
+ * @reasoncode MBOX::RC_MSG_PENDING
* @userdata1 Target ID String...
* @userdata2 Status/Control Register
- * @devdesc MboxDD::write> Permission-to-Send not set
+ * @devdesc MboxDD::write> Message still pending
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
- MBOX::MOD_MBOXDD_WRITE,
- MBOX::RC_NO_PERM_TO_SEND,
- target_to_uint64(i_target),
- reinterpret_cast<uint64_t>(l_64bitBuf));
+ MBOX::MOD_MBOXDD_WRITE,
+ MBOX::RC_MSG_PENDING,
+ target_to_uint64(i_target),
+ reinterpret_cast<uint64_t>(l_64bitBuf));
l_err->collectTrace("MBOX",1024);
break;
}
@@ -483,28 +487,28 @@ errlHndl_t MboxDD::getErrStat(TARGETING::Target* i_target,uint64_t &o_status)
else
{
//Check for Illegal Op
- if ((l_64bitBuf[0] & MBOX::MBOX_ILLEGAL_OP) ==
- MBOX::MBOX_ILLEGAL_OP)
+ if ((l_64bitBuf[0] & MBOX_ILLEGAL_OP) ==
+ MBOX_ILLEGAL_OP)
{
- o_status |= MBOX::MBOX_ILLEGAL_OP;
+ o_status |= MBOX_ILLEGAL_OP;
}
//Check for Write Full
- if ((l_64bitBuf[0] & MBOX::MBOX_DATA_WRITE_ERR) ==
- MBOX::MBOX_DATA_WRITE_ERR)
+ if ((l_64bitBuf[0] & MBOX_DATA_WRITE_ERR) ==
+ MBOX_DATA_WRITE_ERR)
{
- o_status |= MBOX::MBOX_DATA_WRITE_ERR;
+ o_status |= MBOX_DATA_WRITE_ERR;
}
//Check for Read Empty
- if ((l_64bitBuf[0] & MBOX::MBOX_DATA_READ_ERR) ==
- MBOX::MBOX_DATA_READ_ERR)
+ if ((l_64bitBuf[0] & MBOX_DATA_READ_ERR) ==
+ MBOX_DATA_READ_ERR)
{
- o_status |= MBOX::MBOX_DATA_READ_ERR;
+ o_status |= MBOX_DATA_READ_ERR;
}
//Check for Parity Error & add address of parity error
- if ((l_64bitBuf[0] & MBOX::MBOX_PARITY_ERR) ==
- MBOX::MBOX_PARITY_ERR)
+ if ((l_64bitBuf[0] & MBOX_PARITY_ERR) ==
+ MBOX_PARITY_ERR)
{
- o_status |= MBOX::MBOX_PARITY_ERR;
+ o_status |= MBOX_PARITY_ERR;
uint64_t l_temp = (l_64bitBuf[0] & 0x00FF0000);
o_status |= (l_temp << 40);
}
@@ -533,6 +537,30 @@ MboxDD::MboxDD()
TRACFCOMP(g_trac_mbox, "MboxDD::MboxDD()> ");
}
+errlHndl_t MboxDD::init(TARGETING::Target* i_target)
+{
+ errlHndl_t err = NULL;
+ // Setup mailbox intr mask reg
+ // Set bits 6,4,2,0
+ // assume we always use mailbox 1
+ uint64_t scom_data = (static_cast<uint64_t>(MBOX_ABORT_LAST_MSG) |
+ static_cast<uint64_t>(MBOX_DOORBELL_ERROR) |
+ static_cast<uint64_t>(MBOX_XDN_ACK) |
+ static_cast<uint64_t>(MBOX_DATA_PENDING)) << 32;
+
+ size_t scom_len = sizeof(uint64_t);
+
+
+ err = deviceOp(DeviceFW::WRITE,
+ i_target,
+ reinterpret_cast<void*>(&scom_data),
+ scom_len,
+ DEVICE_XSCOM_ADDRESS(MBOX_DB_INT_MASK_PIB_RS));
+
+ return err;
+
+}
+
/**
* @brief Destructor
*/
OpenPOWER on IntegriCloud