From 56a7aab1b97625940c62f06ba83a6359f25653b7 Mon Sep 17 00:00:00 2001 From: Bill Hoffa Date: Wed, 26 Apr 2017 08:52:53 -0500 Subject: 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 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/39386 Tested-by: Jenkins Server Reviewed-by: Dean Sanner Tested-by: Jenkins OP Build CI Tested-by: FSP CI Jenkins Reviewed-by: Christian R. Geddes Reviewed-by: Daniel M. Crowell --- src/usr/lpc/lpcdd.C | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src/usr/lpc/lpcdd.C') 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(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(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(i_buffer); *l_ptr = *i_ptr; } + else if ( i_type == LPC::TRANS_FW + && (i_addr + io_buflen) < LPC::FW_WINDOW_SIZE) + { + memcpy( reinterpret_cast(l_addr), i_buffer, io_buflen ); + } eieio(); #endif } while(0); -- cgit v1.2.1