diff options
author | Bill Hoffa <wghoffa@us.ibm.com> | 2017-04-26 08:52:53 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-05-02 10:34:38 -0400 |
commit | 56a7aab1b97625940c62f06ba83a6359f25653b7 (patch) | |
tree | 7a3e1a9f2b1b62e124d504ed77699b6248040dda /src/usr/lpc | |
parent | 3818f8553f86bbacde079e95f566f8b16cbc3c7f (diff) | |
download | talos-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/usr/lpc')
-rw-r--r-- | src/usr/lpc/lpcdd.C | 22 |
1 files changed, 18 insertions, 4 deletions
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); |