summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBill Hoffa <wghoffa@us.ibm.com>2017-04-26 08:52:53 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-05-02 10:34:38 -0400
commit56a7aab1b97625940c62f06ba83a6359f25653b7 (patch)
tree7a3e1a9f2b1b62e124d504ed77699b6248040dda /src
parent3818f8553f86bbacde079e95f566f8b16cbc3c7f (diff)
downloadtalos-hostboot-56a7aab1b97625940c62f06ba83a6359f25653b7.tar.gz
talos-hostboot-56a7aab1b97625940c62f06ba83a6359f25653b7.zip
lpc: Add support for large read/write ops
On P9 the LPC is memory mapped. The LPC FW space used to map the flash is generally acccessed to read or write rather large amounts of data. Its inefficient to go through the whole dispatch and locking for every single 4 bytes read or written. This adds the ability to request reads or writes of larger quantities for FW space. The implementation uses memcpy whose current implementation in HostBoot will perform well for 8 bytes aligned accesses, but will downgrate to bytes accesses otherwise. Change-Id: I9770f22da99d1e1b917f4ba2101d459483f1dee1 Signed-off-by: Benjamin Herrenschmidt <bherren@au1.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/39386 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Dean Sanner <dsanner@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/lpc/lpc_const.H6
-rw-r--r--src/usr/lpc/lpcdd.C22
2 files changed, 22 insertions, 6 deletions
diff --git a/src/include/usr/lpc/lpc_const.H b/src/include/usr/lpc/lpc_const.H
index a7857e707..897a2df71 100644
--- a/src/include/usr/lpc/lpc_const.H
+++ b/src/include/usr/lpc/lpc_const.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -42,7 +42,9 @@ namespace LPC
/** Physical addr of the start of LPC address space*/
LPC_PHYS_BASE = 0x6030000000000,
+
+ FW_WINDOW_SIZE = 0x10000000, //Size of FW Window
};
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/usr/lpc/lpcdd.C b/src/usr/lpc/lpcdd.C
index 81577a5b0..adcd3aa11 100644
--- a/src/usr/lpc/lpcdd.C
+++ b/src/usr/lpc/lpcdd.C
@@ -93,10 +93,12 @@ errlHndl_t lpcRead(DeviceFW::OperationType i_opType,
uint64_t l_addr = va_arg(i_args,uint64_t);
errlHndl_t l_err = NULL;
- // Only able to do 1,2,4 byte LPC operations
+ // For speed, we support larger ops on FW space, otherwise
+ // we are only able to do 1,2,4 byte LPC operations
assert( (io_buflen == sizeof(uint8_t)) ||
(io_buflen == sizeof(uint16_t)) ||
- (io_buflen == sizeof(uint32_t)) );
+ (io_buflen == sizeof(uint32_t)) ||
+ (l_type == LPC::TRANS_FW) );
// if the request is for something besides the master sentinel
// then we have to use our special side copy of the driver
@@ -182,10 +184,12 @@ errlHndl_t lpcWrite(DeviceFW::OperationType i_opType,
uint64_t l_addr = va_arg(i_args,uint64_t);
errlHndl_t l_err = NULL;
- // Only able to do 1,2,4 byte LPC operations
+ // For speed, we support larger ops on FW space, otherwise
+ // we are only able to do 1,2,4 byte LPC operations
assert( (io_buflen == sizeof(uint8_t)) ||
(io_buflen == sizeof(uint16_t)) ||
- (io_buflen == sizeof(uint32_t)) );
+ (io_buflen == sizeof(uint32_t)) ||
+ (l_type == LPC::TRANS_FW) );
// if the request is for something besides the master sentinel
// then we have to use our special side copy of the driver
@@ -753,6 +757,11 @@ errlHndl_t LpcDD::_readLPC(LPC::TransType i_type,
uint32_t * o_ptr = reinterpret_cast<uint32_t*>(o_buffer);
*o_ptr = *l_ptr;
}
+ else if ( i_type == LPC::TRANS_FW
+ && (i_addr + io_buflen) < LPC::FW_WINDOW_SIZE)
+ {
+ memcpy( o_buffer, reinterpret_cast<void*>(l_addr), io_buflen );
+ }
#endif
else
{
@@ -826,6 +835,11 @@ errlHndl_t LpcDD::_writeLPC(LPC::TransType i_type,
const uint32_t * i_ptr =reinterpret_cast<const uint32_t*>(i_buffer);
*l_ptr = *i_ptr;
}
+ else if ( i_type == LPC::TRANS_FW
+ && (i_addr + io_buflen) < LPC::FW_WINDOW_SIZE)
+ {
+ memcpy( reinterpret_cast<void*>(l_addr), i_buffer, io_buflen );
+ }
eieio();
#endif
} while(0);
OpenPOWER on IntegriCloud