summaryrefslogtreecommitdiffstats
path: root/src/usr/fsi
diff options
context:
space:
mode:
authorMike Baiocchi <baiocchi@us.ibm.com>2014-08-26 00:08:39 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2014-10-28 03:20:29 -0500
commitb08e186c26f57cdbf396af57f84002018c0c3350 (patch)
treecb46f059e165d0f2eb0de3ce152f78c5f1dd85a5 /src/usr/fsi
parentf3f4aa436ae1c0aac413f6cde928f77f1a156600 (diff)
downloadtalos-hostboot-b08e186c26f57cdbf396af57f84002018c0c3350.tar.gz
talos-hostboot-b08e186c26f57cdbf396af57f84002018c0c3350.zip
Enable FSI-based I2C Device Driver Support
This commit adds FSI I2C Device Driver read and write support. The majority of interfaces are common, with the main difference being the registers that are being used. The FSI Device Driver also had to be udpated to support non-4-byte reads and writes. Change-Id: Ife3cfaedc6f23a161192710d1e9f1e74a942d399 RTC: 109926 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/13300 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: ANIRUDH BAGEPALLI <abagepa@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/fsi')
-rw-r--r--src/usr/fsi/fsidd.C92
-rw-r--r--src/usr/fsi/fsidd.H28
2 files changed, 89 insertions, 31 deletions
diff --git a/src/usr/fsi/fsidd.C b/src/usr/fsi/fsidd.C
index 865e27f89..6fd24209e 100644
--- a/src/usr/fsi/fsidd.C
+++ b/src/usr/fsi/fsidd.C
@@ -106,7 +106,10 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
mutex_lock(&g_fsiOpMux);
do{
- if (unlikely(io_buflen < sizeof(uint32_t)))
+
+ if (unlikely( ( io_buflen != 4 ) &&
+ ( io_buflen != 2 ) &&
+ ( io_buflen != 1 ) ) )
{
TRACFCOMP( g_trac_fsi, ERR_MRK "FSI::ddOp> Invalid data length : io_buflen=%d", io_buflen );
/*@
@@ -115,9 +118,9 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
* @reasoncode FSI::RC_INVALID_LENGTH
* @userdata1 FSI Address
* @userdata2 Data Length
- * @devdesc FsiDD::ddOp> Invalid data length (!= 4 bytes)
- * @custdesc A problem occurred during the
- * IPL of the system.
+ * @devdesc FsiDD::ddOp> Invalid data length (!= 4,2,1 bytes)
+ * @custdesc An internal function called the FSI device driver
+ * with an improper data length.
*/
l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
FSI::MOD_FSIDD_DDOP,
@@ -125,13 +128,11 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
i_addr,
TO_UINT64(io_buflen),
true /*SW error*/);
+
l_err->collectTrace(FSI_COMP_NAME);
break;
}
- // default to the fail path
- io_buflen = 0;
-
// look for NULL
if( NULL == i_target )
{
@@ -184,24 +185,24 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
{
l_err = Singleton<FsiDD>::instance().read(i_target,
i_addr,
- static_cast<uint32_t*>(io_buffer));
+ static_cast<uint32_t*>(io_buffer),
+ io_buflen);
if(l_err)
{
break;
}
- io_buflen = sizeof(uint32_t);
}
// do the write
else if( DeviceFW::WRITE == i_opType )
{
l_err = Singleton<FsiDD>::instance().write(i_target,
i_addr,
- static_cast<uint32_t*>(io_buffer));
+ static_cast<uint32_t*>(io_buffer),
+ io_buflen);
if(l_err)
{
break;
}
- io_buflen = sizeof(uint32_t);
}
else
{
@@ -228,6 +229,12 @@ errlHndl_t ddOp(DeviceFW::OperationType i_opType,
}while(0);
+ if ( l_err )
+ {
+ // On fail, assume no data was read or written
+ io_buflen = 0;
+ }
+
mutex_unlock(&g_fsiOpMux);//@fixme - RTC:98898
return l_err;
@@ -368,7 +375,8 @@ void getFsiLinkInfo( TARGETING::Target* i_slave,
*/
errlHndl_t FsiDD::read(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen)
{
TRACDCOMP(g_trac_fsi, "FsiDD::read(i_target=%.8X,i_address=0x%llX)> ", TARGETING::get_huid(i_target), i_address);
errlHndl_t l_err = NULL;
@@ -393,7 +401,8 @@ errlHndl_t FsiDD::read(TARGETING::Target* i_target,
}
// perform the read operation
- l_err = read( addr_info, o_buffer );
+ l_err = read( addr_info, o_buffer, i_buflen );
+
if(l_err)
{
break;
@@ -408,7 +417,8 @@ errlHndl_t FsiDD::read(TARGETING::Target* i_target,
*/
errlHndl_t FsiDD::write(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::write(i_target=%.8X,i_address=0x%llX)> ", TARGETING::get_huid(i_target), i_address);
errlHndl_t l_err = NULL;
@@ -433,7 +443,7 @@ errlHndl_t FsiDD::write(TARGETING::Target* i_target,
}
// perform the write operation
- l_err = write( addr_info, o_buffer );
+ l_err = write( addr_info, o_buffer, i_buflen );
if(l_err)
{
break;
@@ -1052,7 +1062,8 @@ FsiDD::~FsiDD()
* using the master processor chip to drive it
*/
errlHndl_t FsiDD::read(uint64_t i_address,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::read(i_address=0x%llx)> ", i_address);
@@ -1063,7 +1074,7 @@ errlHndl_t FsiDD::read(uint64_t i_address,
addr_info.absAddr = i_address;
// call to low-level read function
- errlHndl_t l_err = read( addr_info, o_buffer );
+ errlHndl_t l_err = read( addr_info, o_buffer, i_buflen );
return l_err;
}
@@ -1074,7 +1085,8 @@ errlHndl_t FsiDD::read(uint64_t i_address,
* using the master processor chip to drive it
*/
errlHndl_t FsiDD::write(uint64_t i_address,
- uint32_t* i_buffer)
+ uint32_t* i_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::write(i_address=0x%llx)> ", i_address);
@@ -1085,7 +1097,7 @@ errlHndl_t FsiDD::write(uint64_t i_address,
addr_info.absAddr = i_address;
// call to low-level write function
- errlHndl_t l_err = write( addr_info, i_buffer );
+ errlHndl_t l_err = write( addr_info, i_buffer, i_buflen );
return l_err;
}
@@ -1095,7 +1107,8 @@ errlHndl_t FsiDD::write(uint64_t i_address,
* @brief Performs an FSI Read Operation
*/
errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
- uint32_t* o_buffer)
+ uint32_t* o_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::read(relAddr=0x%.8X,absAddr=0x%.8X)> ", i_addrInfo.relAddr, i_addrInfo.absAddr );
errlHndl_t l_err = NULL;
@@ -1105,7 +1118,22 @@ errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
do {
// setup the OPB command register
- uint64_t fsicmd = i_addrInfo.absAddr | 0x60000000; // 011=Read Full Word
+
+ uint64_t fsicmd = 0;
+
+ if ( i_buflen == 4 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0x60000000; // 011=Read Full Word
+ }
+ else if ( i_buflen == 1 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0x00000000; // 000=Read 1 Byte
+ }
+ else
+ {
+ fsicmd = i_addrInfo.absAddr | 0x20000000; // 001=Read 2 Bytes
+ }
+
fsicmd <<= 32; // Command is in the upper word
// generate the proper OPB SCOM address
@@ -1181,7 +1209,8 @@ errlHndl_t FsiDD::read(FsiAddrInfo_t& i_addrInfo,
* @brief Write FSI Register
*/
errlHndl_t FsiDD::write(FsiAddrInfo_t& i_addrInfo,
- uint32_t* i_buffer)
+ uint32_t* i_buffer,
+ uint64_t i_buflen )
{
TRACDCOMP(g_trac_fsi, "FsiDD::write(relAddr=0x%.8X,absAddr=0x%.8X)> ", i_addrInfo.relAddr, i_addrInfo.absAddr );
errlHndl_t l_err = NULL;
@@ -1195,7 +1224,22 @@ errlHndl_t FsiDD::write(FsiAddrInfo_t& i_addrInfo,
uint32_t fsidata = *i_buffer;
// setup the OPB command register
- uint64_t fsicmd = i_addrInfo.absAddr | 0xE0000000; // 111=Write Full Word
+
+ uint64_t fsicmd = 0;
+
+ if ( i_buflen == 4 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0xE0000000; // 111=Write Full Word
+ }
+ else if ( i_buflen == 1 )
+ {
+ fsicmd = i_addrInfo.absAddr | 0x80000000; // 100=Write 1 Byte
+ }
+ else
+ {
+ fsicmd = i_addrInfo.absAddr | 0xA0000000; // 101=Write 2 Bytes
+ }
+
fsicmd <<= 32; // Command is in the upper 32-bits
fsicmd |= fsidata; // Data is in the bottom 32-bits
size_t scom_size = sizeof(uint64_t);
@@ -2733,7 +2777,7 @@ errlHndl_t FsiDD::errorCleanup( FsiAddrInfo_t& i_addrInfo,
r++ )
{
l_err = read( i_addrInfo.accessInfo.master,
- MFSI_CONTROL_REG|FSI_MSIEP0_030, &data );
+ MFSI_CONTROL_REG|FSI_MSIEP0_030, &data );
if(l_err) break;
TRACFCOMP( g_trac_fsi, "errorCleanup> %.8X->%.6X = %.8X", TARGETING::get_huid(i_addrInfo.accessInfo.master), grabregs[r], data );
}
diff --git a/src/usr/fsi/fsidd.H b/src/usr/fsi/fsidd.H
index 06c030b57..999b38d02 100644
--- a/src/usr/fsi/fsidd.H
+++ b/src/usr/fsi/fsidd.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2014 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -60,12 +62,14 @@ class FsiDD
* @param[in] i_target Chip target of FSI operation
* @param[in] i_address Address to read (relative to target)
* @param[out] o_buffer Destination buffer for data
+ * @parm[in] i_buflen Length of data to read in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t read(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* o_buffer);
+ uint32_t* o_buffer,
+ size_t i_buflen = 4);
/**
* @brief Performs an FSI Write Operation
@@ -73,12 +77,14 @@ class FsiDD
* @param[in] i_target Chip target of FSI operation
* @param[in] i_address Address to write (relative to target)
* @param[out] i_buffer Source buffer for data
+ * @parm[in] i_buflen Length of data to write in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t write(TARGETING::Target* i_target,
uint64_t i_address,
- uint32_t* i_buffer);
+ uint32_t* i_buffer,
+ size_t i_buflen = 4);
/**
@@ -160,11 +166,13 @@ class FsiDD
* @param[in] i_address Absolute FSI address to read relative to
* the OPB master processor chip
* @param[out] o_buffer Destination buffer for data
+ * @parm[in] i_buflen Length of data to read in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t read(uint64_t i_address,
- uint32_t* o_buffer);
+ uint32_t* o_buffer,
+ size_t i_buflen = 4);
/**
* @brief Performs an FSI Write Operation to an absolute address
@@ -173,11 +181,13 @@ class FsiDD
* @param[in] i_address Absolute FSI address to write relative to
* the OPB master processor chip
* @param[out] i_buffer Source buffer for data
+ * @parm[in] i_buflen Length of data to write in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t write(uint64_t i_address,
- uint32_t* i_buffer);
+ uint32_t* i_buffer,
+ size_t i_buflen = 4);
/**
* Common id to identify a FSI position to use in error logs and traces
@@ -248,22 +258,26 @@ class FsiDD
*
* @param[in] i_addrInfo Addressing information
* @param[out] o_buffer Destination buffer for data
+ * @parm[in] i_buflen Length of data to read in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t read(FsiAddrInfo_t& i_addrInfo,
- uint32_t* o_buffer);
+ uint32_t* o_buffer,
+ size_t i_buflen = 4);
/**
* @brief Performs an FSI Write Operation to an absolute address
*
* @param[in] i_addrInfo Addressing information
* @param[out] i_buffer Source buffer for data
+ * @parm[in] i_buflen Length of data to write in bytes
*
* @return errlHndl_t NULL on success
*/
errlHndl_t write(FsiAddrInfo_t& i_addrInfo,
- uint32_t* i_buffer);
+ uint32_t* i_buffer,
+ size_t i_buflen = 4);
/**
* @brief Initializes the FSI master control registers
OpenPOWER on IntegriCloud