diff options
author | Matthew Barth <msbarth@us.ibm.com> | 2012-02-17 15:50:22 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-03-06 10:18:58 -0600 |
commit | f538d4cbe355a98be2675468da6f3a24078893e8 (patch) | |
tree | 2eca68492641c61f8714f6d7ed790ece29a1e969 /src/usr | |
parent | 18036e00119f1b3757678331173a02eb71b5d179 (diff) | |
download | blackbird-hostboot-f538d4cbe355a98be2675468da6f3a24078893e8.tar.gz blackbird-hostboot-f538d4cbe355a98be2675468da6f3a24078893e8.zip |
Base Mailbox device driver read/write function
Change-Id: I71cee7950d4dff6279422b6ee7fbcc94dcfaf8df
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/679
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Tested-by: Jenkins Server
Diffstat (limited to 'src/usr')
-rw-r--r-- | src/usr/makefile | 2 | ||||
-rw-r--r-- | src/usr/mbox/makefile | 30 | ||||
-rw-r--r-- | src/usr/mbox/mboxdd.C | 541 | ||||
-rw-r--r-- | src/usr/mbox/mboxdd.H | 121 | ||||
-rw-r--r-- | src/usr/mbox/test/makefile | 28 | ||||
-rw-r--r-- | src/usr/mbox/test/mboxddtest.H | 123 |
6 files changed, 844 insertions, 1 deletions
diff --git a/src/usr/makefile b/src/usr/makefile index 579a2159a..4737ffd6e 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -27,6 +27,6 @@ OBJS = module_init.o SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \ scom.d xscom.d targeting.d initservice.d hwpf.d \ ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d fsiscom.d \ - intr.d spd.d pore.d util.d + intr.d spd.d pore.d util.d mbox.d include ${ROOTPATH}/config.mk diff --git a/src/usr/mbox/makefile b/src/usr/mbox/makefile new file mode 100644 index 000000000..816d6dd37 --- /dev/null +++ b/src/usr/mbox/makefile @@ -0,0 +1,30 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/mbox/makefile $ +# +# 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 other- +# wise divested of its trade secrets, irrespective of what has +# been deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END +ROOTPATH = ../../.. +MODULE = mbox + +OBJS = mboxdd.o + +SUBDIRS = test.d + +include ${ROOTPATH}/config.mk diff --git a/src/usr/mbox/mboxdd.C b/src/usr/mbox/mboxdd.C new file mode 100644 index 000000000..441925fd1 --- /dev/null +++ b/src/usr/mbox/mboxdd.C @@ -0,0 +1,541 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/mbox/mboxdd.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 other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +#include "mboxdd.H" +#include <mbox/mboxif.H> +#include <mbox/mbox_reasoncodes.H> +#include <devicefw/driverif.H> +#include <trace/interface.H> +#include <errl/errlentry.H> +#include <targeting/targetservice.H> + +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 +{ + +/** + * @brief Performs an MBOX Read Operation + * This function performs a MBOX Read operation. It follows a pre-defined + * prototype functions in order to be registered with the device-driver + * framework. + * + * @param[in] i_opType Operation type, see DeviceFW::OperationType + * in driverif.H + * @param[in] i_target MBOX target + * @param[in/out] io_buffer Read: Pointer to output data storage + * 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. + * + * @return errlHndl_t + */ +errlHndl_t ddRead(DeviceFW::OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, + size_t& io_buflen, + int64_t i_accessType, + va_list i_args) +{ + errlHndl_t l_err = NULL; + uint64_t* o_status = va_arg(i_args,uint64_t*); + + do + { + l_err = Singleton<MboxDD>::instance().read(i_target,io_buffer, + io_buflen,o_status); + if (l_err) + { + break; + } + } while(0); + + return l_err; +} + +/** + * @brief Performs an MBOX Write Operation + * This function performs a MBOX Write operation. It follows a pre-defined + * prototype functions in order to be registered with the device-driver + * framework. + * + * @param[in] i_opType Operation type, see DeviceFW::OperationType + * in driverif.H + * @param[in] i_target MBOX target + * @param[in/out] io_buffer Read: Pointer to output data storage + * 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. + * + * @return errlHndl_t + */ +errlHndl_t ddWrite(DeviceFW::OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, + size_t& io_buflen, + int64_t i_accessType, + va_list i_args) +{ + errlHndl_t l_err = NULL; + + do + { + l_err = Singleton<MboxDD>::instance().write(i_target,io_buffer, + io_buflen); + if(l_err) + { + break; + } + } while(0); + + return l_err; +} + +// Register MBOXDD access functions to DD framework +DEVICE_REGISTER_ROUTE(DeviceFW::READ, + DeviceFW::MAILBOX, + TARGETING::TYPE_PROC, + ddRead); + +DEVICE_REGISTER_ROUTE(DeviceFW::WRITE, + DeviceFW::MAILBOX, + TARGETING::TYPE_PROC, + ddWrite); + +}; //end MBOX namespace + +/** + * @brief Performs a mailbox read operation + */ +errlHndl_t MboxDD::read(TARGETING::Target* i_target,void *o_buffer, + size_t &io_buflen,uint64_t* o_status) +{ + uint64_t l_stat = 0; + errlHndl_t l_err = NULL; + uint32_t l_64bitBuf[2] = {0}; + uint32_t l_IntReg[2] = {0}; + size_t l_64bitSize = sizeof(uint64_t); + + do + { + if (MBOX::MBOX_MAX_DATA_BYTES < io_buflen) + { + TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Invalid data length : io_buflen=%d", io_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(io_buflen)); + l_err->collectTrace("MBOX",1024); + break; + } + + 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"); + break; + } + if ((l_IntReg[0] & MBOX::MBOX_DOORBELL_ERROR) == + MBOX::MBOX_DOORBELL_ERROR) + { + TRACFCOMP(g_trac_mbox, INFO_MRK "MBOX::read> Found interrupt on error status register"); + l_err = getErrStat(i_target,l_stat); + if (l_err) + { + break; + } + } + + 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"); + break; + } + /* + * DB_STATUS_1A_REG: doorbell status and control 1a + * Bit31(MSB) : Permission to Send Doorbell 1 + * Bit30 : Abort Doorbell 1 + * Bit29 : PIB Slave B Pending Doorbell 1 + * Bit28 : LBUS Slave A Pending Doorbell 1 + * Bit27 : Reserved + * Bit26 : Xdn Doorbell 1 + * Bit25 : Xup Doorbell 1 + * Bit24 : Reserved + * Bit23-20 : Header Count LBUS Slave A Doorbell 1 + * Bit19-12 : Data Count LBUS Slave A Doorbell 1 + * Bit11-8 : Header Count PIB Slave B Doorbell 1 + * 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 && + (l_64bitBuf[0] & 0x40000000) == 0x40000000) + { + l_stat |= MBOX::MBOX_ABORT_LAST_MSG; + } + //Check for Xdn + if ((l_IntReg[0] & MBOX::MBOX_XDN_ACK) == + MBOX::MBOX_XDN_ACK && + (l_64bitBuf[0] & 0x04000000) == 0x04000000) + { + l_stat |= MBOX::MBOX_XDN_ACK; + } + //Check for PIB Pending + if ((l_IntReg[0] & MBOX::MBOX_DATA_PENDING) == + MBOX::MBOX_DATA_PENDING && + (l_64bitBuf[0] & 0x20000000) == 0x20000000) + { + l_stat |= MBOX::MBOX_DATA_PENDING; + //Read how many bytes are significant + if (io_buflen < ((l_64bitBuf[0] & 0x000FF000) >> 12)) + { + TRACFCOMP(g_trac_mbox, INFO_MRK "MBOX::read> Data truncated, input buffer length less than number of significant bytes"); + } + uint32_t i = 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) + { + l_err = deviceOp(DeviceFW::READ,i_target, + l_data,l_64bitSize, + DEVICE_XSCOM_ADDRESS(MBOX_DATA_LBUS_START+i)); + if (l_err) + { + TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to read Data Area Register 0x%X",MBOX_DATA_LBUS_START+i); + break; + } + //TODO Use memcpy() since byte aligned? + for (uint8_t byteNum = 0;byteNum<sizeof(uint32_t);++byteNum) + { + *(l_buf+(byteNum+i*sizeof(uint32_t))) = + (l_data[0]>>(sizeof(uint32_t)*8-(byteNum+1)*8) & 0x000000FF); + } + i++; + } + if (l_err) + { + break; + } + + //Write-to-Clear PIB Pending,Xup,and bits 23-12 + l_64bitBuf[0] = 0x22FFF000; + 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::read> Unable to clear Doorbell Status/Control Register"); + break; + } + } + + //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) + { + TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::read> Unable to clear PIB Interrupt Register"); + break; + } + (*o_status) = l_stat; + + } while(0); + + return l_err; +} + +/** + * @brief Performs a mailbox write operation + */ +errlHndl_t MboxDD::write(TARGETING::Target* i_target,void* i_buffer, + size_t& i_buflen) +{ + errlHndl_t l_err = NULL; + uint32_t l_64bitBuf[2] = {0}; + size_t l_64bitSize = sizeof(uint64_t); + + do + { + //Expect size in bytes + if (i_buflen > MBOX::MBOX_MAX_DATA_BYTES) + { + TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Invalid data length : i_buflen=%d", i_buflen); + /*@ + * @errortype + * @moduleid MBOX::MOD_MBOXDD_WRITE + * @reasoncode MBOX::RC_INVALID_LENGTH + * @userdata1 Target ID String... + * @userdata2 Data Length + * @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)); + 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)); + if (l_err) + { + TRACFCOMP(g_trac_mbox, ERR_MRK "MBOX::write> Unable to read Doorbell Status/Control Register"); + break; + } + + /* + * DB_STATUS_1A_REG: doorbell status and control 1a + * Bit31(MSB) : Permission to Send Doorbell 1 + * Bit30 : Abort Doorbell 1 + * Bit29 : PIB Slave B Pending Doorbell 1 + * Bit28 : LBUS Slave A Pending Doorbell 1 + * Bit27 : Reserved + * Bit26 : Xdn Doorbell 1 + * Bit25 : Xup Doorbell 1 + * Bit24 : Reserved + * Bit23-20 : Header Count LBUS Slave A Doorbell 1 + * Bit19-12 : Data Count LBUS Slave A Doorbell 1 + * 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) + { + 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_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"); + break; + } + } + else + { + 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); + 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]); + /*@ + * @errortype + * @moduleid MBOX::MOD_MBOXDD_WRITE + * @reasoncode MBOX::RC_NO_PERM_TO_SEND + * @userdata1 Target ID String... + * @userdata2 Status/Control Register + * @devdesc MboxDD::write> Permission-to-Send not set + */ + 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)); + l_err->collectTrace("MBOX",1024); + break; + } + + } while(0); + + return l_err; +} + +/** + * @brief Reads the mailbox PIB error status register + */ +errlHndl_t MboxDD::getErrStat(TARGETING::Target* i_target,uint64_t &o_status) +{ + errlHndl_t l_err = NULL; + uint32_t l_64bitBuf[2] = {0}; + size_t l_64bitSize = sizeof(uint64_t); + + do + { + l_err = deviceOp(DeviceFW::READ,i_target, + l_64bitBuf,l_64bitSize, + 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"); + break; + } + else + { + //Check for Illegal Op + if ((l_64bitBuf[0] & MBOX::MBOX_ILLEGAL_OP) == + MBOX::MBOX_ILLEGAL_OP) + { + o_status |= MBOX::MBOX_ILLEGAL_OP; + } + //Check for Write Full + if ((l_64bitBuf[0] & MBOX::MBOX_DATA_WRITE_ERR) == + MBOX::MBOX_DATA_WRITE_ERR) + { + o_status |= MBOX::MBOX_DATA_WRITE_ERR; + } + //Check for Read Empty + if ((l_64bitBuf[0] & MBOX::MBOX_DATA_READ_ERR) == + MBOX::MBOX_DATA_READ_ERR) + { + o_status |= MBOX::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) + { + o_status |= MBOX::MBOX_PARITY_ERR; + uint64_t l_temp = (l_64bitBuf[0] & 0x00FF0000); + o_status |= (l_temp << 40); + } + } + //Write '1' to Clear Status(16) + l_64bitBuf[0] = 0x00010000; + l_err = deviceOp(DeviceFW::WRITE,i_target, + l_64bitBuf,l_64bitSize, + 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"); + break; + } + + } while(0); + + return l_err; +} + +/** + * @brief Constructor + */ +MboxDD::MboxDD() +{ + TRACFCOMP(g_trac_mbox, "MboxDD::MboxDD()> "); +} + +/** + * @brief Destructor + */ +MboxDD::~MboxDD() +{ +} diff --git a/src/usr/mbox/mboxdd.H b/src/usr/mbox/mboxdd.H new file mode 100644 index 000000000..46df5db30 --- /dev/null +++ b/src/usr/mbox/mboxdd.H @@ -0,0 +1,121 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/mbox/mboxdd.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 other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +#ifndef __MBOX_MBOXDD_H +#define __MBOX_MBOXDD_H + +#include <errl/errlentry.H> +#include <usr/devicefw/driverif.H> + +/** @file mboxdd.H + * @brief Provides the interfaces to the MBOX Device Driver + */ +class MboxDD +{ + + public: + + /** + * @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, + 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, + 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, + 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 = 0x00050024, //LBUS(rw),PIB(rw) Stat/Cntrl 1 + MBOX_DB_ERR_STAT_PIB = 0x00050030, //LBUS(ro),PIB(rw) Err Stat B + MBOX_DB_ERR_STAT_LBUS = 0x00050031, //LBUS(rw),PIB(ro) Err Stat A + MBOX_DB_INT_REG_LBUS = 0x00050032, //LBUS(rw),PIB(ro) Int Reg A + MBOX_DB_INT_MASK_LBUS_RS = 0x00050033, //LBUS(r/set),PIB(ro) Int Mask A + MBOX_DB_INT_MASK_LBUS_RC = 0x00050034, //LBUS(r/clear),PIB(ro/zero) + MBOX_DB_INT_REG_PIB = 0x00050035, //LBUS(ro),PIB(rw) Int Reg B + MBOX_DB_INT_MASK_PIB_RS = 0x00050036, //LBUS(ro),PIB(r/set) Int Mask B + MBOX_DB_INT_MASK_PIB_RC = 0x00050037, //LBUS(ro/zero,PIB(r/clear) + }; + + //Mailbox 1 Header/Command register addresses + enum MboxHeadCmdRegs { + MBOX_HEAD_CMD_LBUS0 = 0x00050021, //LBUS(rw),PIB(ro) H/C 0A + MBOX_HEAD_CMD_LBUS1 = 0x00050022, //LBUS(rw),PIB(ro) H/C 1A + MBOX_HEAD_CMD_LBUS2 = 0x00050023, //LBUS(rw),PIB(ro) H/C 2A + MBOX_HEAD_CMD_PIB0 = 0x00050025, //LBUS(ro),PIB(rw) H/C 0B + MBOX_HEAD_CMD_PIB1 = 0x00050026, //LBUS(ro),PIB(rw) H/C 1B + MBOX_HEAD_CMD_PIB2 = 0x00050027, //LBUS(ro),PIB(rw) H/C 2B + }; + + //Mailbox 1 Data register address boundaries + enum MboxDataRegs { + MBOX_DATA_LBUS_START = 0x00050040, //LBUS(rw),PIB(ro) First address + MBOX_DATA_LBUS_END = 0x0005004F, //LBUS(rw),PIB(ro) Last address + MBOX_DATA_PIB_START = 0x00050080, //LBUS(ro),PIB(rw) First address + MBOX_DATA_PIB_END = 0x0005008F, //LBUS(ro),PIB(rw) Last address + }; + +}; + +#endif diff --git a/src/usr/mbox/test/makefile b/src/usr/mbox/test/makefile new file mode 100644 index 000000000..1c9c09f95 --- /dev/null +++ b/src/usr/mbox/test/makefile @@ -0,0 +1,28 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/mbox/test/makefile $ +# +# 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 other- +# wise divested of its trade secrets, irrespective of what has +# been deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END +ROOTPATH = ../../../.. + +MODULE = testmbox +TESTS = *.H + +include ${ROOTPATH}/config.mk diff --git a/src/usr/mbox/test/mboxddtest.H b/src/usr/mbox/test/mboxddtest.H new file mode 100644 index 000000000..a1920d891 --- /dev/null +++ b/src/usr/mbox/test/mboxddtest.H @@ -0,0 +1,123 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/mbox/test/mboxddtest.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 other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +#ifndef __MBOXDDTEST_H +#define __MBOXDDTEST_H + +/** + * @file mboxddtest.H + * + * @brief Test cases for MBOX Device Driver +*/ + +#include <cxxtest/TestSuite.H> +#include <errl/errlentry.H> +#include <errl/hberrltypes.H> +#include <limits.h> +#include <devicefw/driverif.H> +#include <mbox/mboxif.H> + +extern trace_desc_t* g_trac_mbox; + +using namespace TARGETING; + +class MboxDDTest : public CxxTest::TestSuite +{ + public: + + /** + * @brief MBOX DD test - Write (STUB) + * Perform basic write operation + */ + void testWrite(void) + { + TRACFCOMP(g_trac_mbox, "MboxDDTest::testWrite(STUB)> Begin"); + /* + * This test function should be updated to perform TWO write + * operations. Without the SIMICS data loopback update, this + * should cause errors to occur due to no ack back from FSP. + * + * Currently, without proper SIMICS support, this test function + * will be stubbed out to allow checkin of this file. + */ + TRACFCOMP(g_trac_mbox, "MboxDDTest::testWrite(STUB)> End"); + } + + /** + * @brief MBOX DD test - Write/Read + * Perform basic write then read operation + * Requires SIMICS data loopback from SP-to-Host (PIB-to-LBUS) + */ + void _testWriteRead(void) + { + uint64_t o_status = 0; + errlHndl_t l_err = NULL; + uint32_t in_mboxMsg [] = {0x12345678, 0x14785236, 0x96325874, + 0x98765432, 0x78910112, 0x66660000}; + size_t in_size = sizeof(in_mboxMsg); + uint32_t out_mboxMsg[16] = {0}; + size_t out_size = sizeof(out_mboxMsg); + + TRACFCOMP(g_trac_mbox, "MboxDDTest::testWriteRead> Begin"); + + TARGETING::EntityPath epath(TARGETING::EntityPath::PATH_PHYSICAL); + epath.addLast(TARGETING::TYPE_SYS,0); + epath.addLast(TARGETING::TYPE_NODE,0); + epath.addLast(TARGETING::TYPE_PROC,0); + + l_err = DeviceFW::deviceWrite( + TARGETING::targetService().toTarget(epath), + static_cast<void*>(in_mboxMsg),in_size, + DEVICE_MBOX_ADDRESS(&o_status)); + if (l_err) + { + TS_FAIL("Unable to write to mailbox device.\n"); + } + + l_err = DeviceFW::deviceRead( + TARGETING::targetService().toTarget(epath), + static_cast<void*>(out_mboxMsg),out_size, + DEVICE_MBOX_ADDRESS(&o_status)); + if (l_err) + { + TS_FAIL("Unable to read mailbox device.\n"); + } + if (o_status != 0x00000005)//Xdn & PIB Pending + { + TS_FAIL("PIB interrupt register shows unexpected interrupt.\n"); + } + + for (uint32_t i=0; i<sizeof(in_mboxMsg)/sizeof(uint32_t); ++i) + { + if (out_mboxMsg[i] != in_mboxMsg[i]) + { + TS_FAIL("Loopback data area mismatch.\n"); + break; + } + } + + TRACFCOMP(g_trac_mbox, "MboxDDTest::testWriteRead> End"); + }; + +}; + +#endif |