diff options
| author | Andrew Jeffery <andrewrj@au1.ibm.com> | 2018-09-17 17:23:19 +0930 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2018-10-10 13:46:36 -0500 |
| commit | 9518b4c189c96a26cb80a57aa441e38f33bdc5cf (patch) | |
| tree | 3ee47d1136fae625b0ed7a8ccea91e8328682695 /src/usr/pnor | |
| parent | 7c16f3706b3c822e72d369d828939a800acccdd2 (diff) | |
| download | blackbird-hostboot-9518b4c189c96a26cb80a57aa441e38f33bdc5cf.tar.gz blackbird-hostboot-9518b4c189c96a26cb80a57aa441e38f33bdc5cf.zip | |
pnor: Fall back to AST mbox transport if IPMI is unavailable
Avoid a flag-day transition by allowing for old BMC releases. Eventually
support for the AST mailbox will be removed and the indirection with it.
Change-Id: Ic62ee6a0f2132583cba290098a52417d32eb772d
Signed-off-by: Andrew Jeffery <andrewrj@au1.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/66122
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/pnor')
| -rw-r--r-- | src/usr/pnor/makefile | 6 | ||||
| -rw-r--r-- | src/usr/pnor/pnor_hiomapdd.C | 260 | ||||
| -rw-r--r-- | src/usr/pnor/pnor_hiomapdd.H | 68 | ||||
| -rw-r--r-- | src/usr/pnor/pnor_ipmidd.C | 209 | ||||
| -rw-r--r-- | src/usr/pnor/pnor_ipmidd.H | 71 | ||||
| -rw-r--r-- | src/usr/pnor/pnor_mboxdd.C | 174 | ||||
| -rw-r--r-- | src/usr/pnor/pnor_mboxdd.H | 69 | ||||
| -rw-r--r-- | src/usr/pnor/pnorif.H | 81 | ||||
| -rw-r--r-- | src/usr/pnor/pnorvalid.C | 13 | ||||
| -rw-r--r-- | src/usr/pnor/test/pnorddtest.H | 15 |
10 files changed, 513 insertions, 453 deletions
diff --git a/src/usr/pnor/makefile b/src/usr/pnor/makefile index ceac32acb..d6b257321 100644 --- a/src/usr/pnor/makefile +++ b/src/usr/pnor/makefile @@ -25,15 +25,15 @@ # IBM_PROLOG_END_TAG ROOTPATH = ../../.. +HIOMAP_DEPS = ast_mboxdd.o pnor_mboxdd.o pnor_ipmidd.o pnor_hiomapdd.o MODULE = pnor OBJS += pnor_utils.o OBJS += pnorrp.o OBJS += $(if $(CONFIG_SECUREBOOT),spnorrp.o) OBJS += $(if $(CONFIG_PNORDD_IS_SFC),pnor_sfcdd.o) -OBJS += $(if $(CONFIG_PNORDD_IS_BMCMBOX),ast_mboxdd.o) -OBJS += $(if $(CONFIG_PNORDD_IS_BMCMBOX),pnor_mboxdd.o) -OBJS += $(if $(CONFIG_PNORDD_IS_IPMI),pnor_ipmidd.o) +OBJS += $(if $(CONFIG_PNORDD_IS_BMCMBOX),$(HIOMAP_DEPS)) +OBJS += $(if $(CONFIG_PNORDD_IS_IPMI),$(HIOMAP_DEPS)) OBJS += pnor_common.o OBJS += pnorvalid.o OBJS += ecc.o diff --git a/src/usr/pnor/pnor_hiomapdd.C b/src/usr/pnor/pnor_hiomapdd.C new file mode 100644 index 000000000..5f998fca1 --- /dev/null +++ b/src/usr/pnor/pnor_hiomapdd.C @@ -0,0 +1,260 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/pnor/pnor_hiomapdd.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* [+] 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. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <console/consoleif.H> +#include <devicefw/driverif.H> +#include <initservice/initserviceif.H> +#include <pnor/pnor_reasoncodes.H> +#include "pnor_ipmidd.H" +#include "pnor_mboxdd.H" +#include "pnor_hiomapdd.H" +#include "pnor_utils.H" + +namespace PNOR +{ + +/** + * @brief Performs an PNOR Read Operation + * This function performs a PNOR 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 PNOR 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 (usrif.H) + * @param[in] i_args This is an argument list for DD framework. + * In this function, there's only one argument, + * containing the PNOR address and chip select + * @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 l_addr = va_arg(i_args, uint64_t); + + do + { + //@todo (RTC:36951) - add support for unaligned data + // Ensure we are operating on a 32-bit (4-byte) boundary + assert( reinterpret_cast<uint64_t>(io_buffer) % 4 == 0 ); + assert( io_buflen % 4 == 0 ); + + // The PNOR device driver interface is initialized with the + // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL. Other target + // access requires a separate PnorHiomapDD class created + assert( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ); + + // Read the flash + l_err = Singleton<PnorHiomapDD>::instance().readFlash(io_buffer, + io_buflen, + l_addr); + + if(l_err) + { + break; + } + + } + while(0); + + return l_err; +} + +/** + * @brief Performs an PNOR Write Operation + * This function performs a PNOR 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 PNOR 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 (usrif.H) + * @param[in] i_args This is an argument list for DD framework. + * In this function, there's only one argument, + * containing the PNOR address and chip select + * @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; + uint64_t l_addr = va_arg(i_args, uint64_t); + + do + { + //@todo (RTC:36951) - add support for unaligned data + // Ensure we are operating on a 32-bit (4-byte) boundary + assert( reinterpret_cast<uint64_t>(io_buffer) % 4 == 0 ); + assert( io_buflen % 4 == 0 ); + + // The PNOR device driver interface is initialized with the + // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL. Other target + // access requires a separate PnorHiomapDD class created + assert( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ); + + // Write the flash + l_err = Singleton<PnorHiomapDD>::instance().writeFlash(io_buffer, + io_buflen, + l_addr); + + if(l_err) + { + break; + } + + } + while(0); + + return l_err; +} + +/** + * @brief Informs caller if the driver is using + * L3 Cache for fake PNOR or not. + * + * @return Indicate state of fake PNOR + * true = PNOR DD is using L3 Cache for fake PNOR + * false = PNOR DD not using L3 Cache for fake PNOR + */ +bool usingL3Cache() +{ + return false; +} + +/** + * @brief Retrieve some information about the PNOR/SFC hardware + */ +void getPnorInfo( PnorInfo_t& o_pnorInfo ) +{ + o_pnorInfo.mmioOffset = LPC_SFC_MMIO_OFFSET | LPC_FW_SPACE; + o_pnorInfo.norWorkarounds = + Singleton<PnorHiomapDD>::instance().getNorWorkarounds(); + o_pnorInfo.flashSize = + Singleton<PnorHiomapDD>::instance().getNorSize(); +} + +// Register access functions to DD framework +DEVICE_REGISTER_ROUTE(DeviceFW::READ, + DeviceFW::PNOR, + TARGETING::TYPE_PROC, + ddRead); + +DEVICE_REGISTER_ROUTE(DeviceFW::WRITE, + DeviceFW::PNOR, + TARGETING::TYPE_PROC, + ddWrite); + +}; //namespace PNOR + +errlHndl_t PnorHiomapDD::readFlash(void* o_buffer, + size_t& io_buflen, + uint64_t i_address) +{ + return iv_pnor->readFlash(o_buffer, io_buflen, i_address); +} + +errlHndl_t PnorHiomapDD::writeFlash(const void* i_buffer, + size_t& io_buflen, + uint64_t i_address) +{ + return iv_pnor->writeFlash(i_buffer, io_buflen, i_address); +} + +uint32_t PnorHiomapDD::getNorSize(void) +{ + return iv_pnor->getNorSize(); +} + +uint32_t PnorHiomapDD::getNorWorkarounds(void) +{ + return iv_pnor->getNorWorkarounds(); +} + +static PnorIf* probeHiomapTransport(TARGETING::Target* i_target) +{ + PnorIf* pnor; + + do { + if ((pnor = PnorIpmiDD::probe(i_target))) + { + break; + } + + if ((pnor = PnorMboxDD::probe(i_target))) + { + break; + } + } while (0); + + if (pnor) + { + return pnor; + } + + CONSOLE::displayf(NULL, "Probes for MBOX and IPMI HIOMAP transports failed\n"); + CONSOLE::displayf(NULL, "Cannot access PNOR!\n"); + CONSOLE::flush(); + INITSERVICE::doShutdown(PNOR::RC_PNOR_INIT_FAILURE); + + assert(false && "Unreachable"); + + return NULL; +} + +PnorHiomapDD::PnorHiomapDD(TARGETING::Target* i_target) +{ + iv_pnor = probeHiomapTransport(i_target); +} + +PnorHiomapDD::~PnorHiomapDD() +{ + delete iv_pnor; +} diff --git a/src/usr/pnor/pnor_hiomapdd.H b/src/usr/pnor/pnor_hiomapdd.H new file mode 100644 index 000000000..8bda811d5 --- /dev/null +++ b/src/usr/pnor/pnor_hiomapdd.H @@ -0,0 +1,68 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/pnor/pnor_hiomapdd.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2018 */ +/* [+] 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. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __PNOR_HIOMAPDD_H +#define __PNOR_HIOMAPDD_H + +/* + * The PnorHiomapDD class implements fallback semantics for the HIOMAP + * transport implementations (currently, AST mailbox and IPMI). The constructor + * probes each transport, preferring IPMI over the mailbox. If a transport's + * probe is successful the instance of the transport's class is stored in + * the iv_pnor member of PnorHiomapDD. + * + * With this in place, we register the readFlash() and writeFlash() methods + * of PnorHiomapDD as the handlers for the PNOR device driver route. Each + * method then delegates to the respective method on the instance of the class + * of transport that was successfully probed. + */ + +#include <errl/errlentry.H> +#include <targeting/common/target.H> + +#include "pnorif.H" + +class PnorHiomapDD : public PnorIf +{ + public: + PnorHiomapDD(TARGETING::Target* i_target = NULL); + ~PnorHiomapDD(); + + virtual errlHndl_t readFlash(void* o_buffer, + size_t& io_buflen, + uint64_t i_address); + + virtual errlHndl_t writeFlash(const void* i_buffer, + size_t& io_buflen, + uint64_t i_address); + + virtual uint32_t getNorSize(void); + + virtual uint32_t getNorWorkarounds(void); + + private: + PnorIf* iv_pnor; +}; + +#endif diff --git a/src/usr/pnor/pnor_ipmidd.C b/src/usr/pnor/pnor_ipmidd.C index 6d68e593b..078195dad 100644 --- a/src/usr/pnor/pnor_ipmidd.C +++ b/src/usr/pnor/pnor_ipmidd.C @@ -93,170 +93,6 @@ enum { // Initialized in pnorrp.C extern trace_desc_t* g_trac_pnor; -namespace PNOR -{ - -/** - * @brief Performs an PNOR Read Operation - * This function performs a PNOR 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 PNOR 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 (usrif.H) - * @param[in] i_args This is an argument list for DD framework. - * In this function, there's only one argument, - * containing the PNOR address and chip select - * @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 l_addr = va_arg(i_args, uint64_t); - - do - { - //@todo (RTC:36951) - add support for unaligned data - // Ensure we are operating on a 32-bit (4-byte) boundary - assert( reinterpret_cast<uint64_t>(io_buffer) % 4 == 0 ); - assert( io_buflen % 4 == 0 ); - - // The PNOR device driver interface is initialized with the - // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL. Other target - // access requires a separate PnorIpmiDD class created - assert( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ); - - // Read the flash - l_err = Singleton<PnorIpmiDD>::instance().readFlash(io_buffer, - io_buflen, - l_addr); - - if(l_err) - { - break; - } - - } - while(0); - - return l_err; -} - -/** - * @brief Performs an PNOR Write Operation - * This function performs a PNOR 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 PNOR 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 (usrif.H) - * @param[in] i_args This is an argument list for DD framework. - * In this function, there's only one argument, - * containing the PNOR address and chip select - * @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; - uint64_t l_addr = va_arg(i_args, uint64_t); - - do - { - //@todo (RTC:36951) - add support for unaligned data - // Ensure we are operating on a 32-bit (4-byte) boundary - assert( reinterpret_cast<uint64_t>(io_buffer) % 4 == 0 ); - assert( io_buflen % 4 == 0 ); - - // The PNOR device driver interface is initialized with the - // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL. Other target - // access requires a separate PnorIpmiDD class created - assert( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ); - - // Write the flash - l_err = Singleton<PnorIpmiDD>::instance().writeFlash(io_buffer, - io_buflen, - l_addr); - - if(l_err) - { - break; - } - - } - while(0); - - return l_err; -} - -/** - * @brief Informs caller if the driver is using - * L3 Cache for fake PNOR or not. - * - * @return Indicate state of fake PNOR - * true = PNOR DD is using L3 Cache for fake PNOR - * false = PNOR DD not using L3 Cache for fake PNOR - */ -bool usingL3Cache() -{ - return false; -} - -/** - * @brief Retrieve some information about the PNOR/SFC hardware - */ -void getPnorInfo( PnorInfo_t& o_pnorInfo ) -{ - o_pnorInfo.mmioOffset = LPC_SFC_MMIO_OFFSET | LPC_FW_SPACE; - o_pnorInfo.norWorkarounds = - Singleton<PnorIpmiDD>::instance().getNorWorkarounds(); - o_pnorInfo.flashSize = - Singleton<PnorIpmiDD>::instance().getNorSize(); -} - -// Register access functions to DD framework -DEVICE_REGISTER_ROUTE(DeviceFW::READ, - DeviceFW::PNOR, - TARGETING::TYPE_PROC, - ddRead); - -DEVICE_REGISTER_ROUTE(DeviceFW::WRITE, - DeviceFW::PNOR, - TARGETING::TYPE_PROC, - ddWrite); - -}; //namespace PNOR - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - /** * @brief Performs a PNOR Read Operation */ @@ -866,3 +702,48 @@ PnorIpmiDD::PnorIpmiDD( TARGETING::Target* i_target ) PnorIpmiDD::~PnorIpmiDD() { } + +PnorIf* PnorIpmiDD::probe(TARGETING::Target* i_target) +{ + errlHndl_t l_err = NULL; + + /* + * Test if the daemon is alive by sending an ack message. Make it a no-op + * by not setting any flags in the mask argument + */ + HiomapMessage* l_msg = new HiomapMessage(HIOMAP_C_ACK); + l_msg->put8(0, 0); + + /* Open-code the exchange to avoid constructing the class for sendCommand */ + IPMI::completion_code l_cc = IPMI::CC_UNKBAD; + + l_msg->iv_seq = 0; + + uint8_t old_seq = l_msg->iv_seq; + uint8_t* l_data = reinterpret_cast <uint8_t*>((char*)l_msg); + size_t l_len = 2 + 1; /* Account for command and sequence number */ + bool success; + + l_err = IPMI::sendrecv( + IPMI::pnor_hiomap_request(), l_cc, l_len, l_data); + if (!l_err && (l_cc == IPMI::CC_OK)) + { + /* Don't look too closely, storage size doesn't necessarily match */ + assert(l_len >= 2); + l_msg = reinterpret_cast<HiomapMessage *>((char *)l_data); + success = (old_seq == l_msg->iv_seq); + delete l_msg; + } + else + { + success = false; + } + + if (success) + { + TRACFCOMP(g_trac_pnor, "PnorIpmiDD: Detected IPMI HIOMAP transport"); + return new PnorIpmiDD(i_target); + } + + return nullptr; +} diff --git a/src/usr/pnor/pnor_ipmidd.H b/src/usr/pnor/pnor_ipmidd.H index 74ffed7f2..fc843db6a 100644 --- a/src/usr/pnor/pnor_ipmidd.H +++ b/src/usr/pnor/pnor_ipmidd.H @@ -33,6 +33,8 @@ #include <limits.h> #include <config.h> +#include "pnorif.H" + namespace PNOR { class UdPnorDDParms; @@ -112,59 +114,14 @@ class HiomapMessage * @brief PNOR Device Driver Class * Provides access to the PNOR flash via the LPC MBOX hardware */ -class PnorIpmiDD +class PnorIpmiDD : public PnorIf { public: - /** - * @brief Performs a PNOR Read Operation - * - * @parm o_buffer Buffer to read data into - * @parm io_buflen Input: Number of bytes to read, - * Output: Number of bytes actually read - * @parm i_address Offset into flash to read - * - * @return Error from operation - */ - errlHndl_t readFlash(void* o_buffer, - size_t& io_buflen, - uint64_t i_address); - - /** - * @brief Performs a PNOR Write Operation - * - * @parm i_buffer Buffer to write data from - * @parm io_buflen Input: Number of bytes to write, - * Output: Number of bytes actually written - * @parm i_address Offset into flash to write - * - * @return Error from operation - */ - errlHndl_t writeFlash(const void* i_buffer, - size_t& io_buflen, - uint64_t i_address); - - /** - * @brief Informs caller if PNORDD is using - * L3 Cache for fake PNOR or not. - * - * @return Indicate state of fake PNOR - * true = PNOR DD is using L3 Cache for fake PNOR - * false = PNOR DD not using L3 Cache for fake PNOR + /** @brief Test for the IPMI HIOMAP transport and return an appropriate + * PnorDD instance if detected, otherwise nullptr. */ - bool usingL3Cache( ); - - /** - * @brief Retrieve size of NOR flash - * @return Size of PNOR in bytes - */ - uint32_t getNorSize( void ); - - /** - * @brief Retrieve bitstring of NOR workarounds - * @return NOR workarounds (see VendorWorkarounds in norflash.H) - */ - uint32_t getNorWorkarounds( void ); + static PnorIf* probe(TARGETING::Target* target); /** * @brief Constructor @@ -173,11 +130,19 @@ class PnorIpmiDD * NOTE: i_target can only be used after targeting is loaded */ PnorIpmiDD( TARGETING::Target* i_target = NULL ); + virtual ~PnorIpmiDD(); - /** - * @brief Destructor - */ - ~PnorIpmiDD(); + virtual errlHndl_t readFlash(void* o_buffer, + size_t& io_buflen, + uint64_t i_address); + + virtual errlHndl_t writeFlash(const void* i_buffer, + size_t& io_buflen, + uint64_t i_address); + + virtual uint32_t getNorSize(void); + + virtual uint32_t getNorWorkarounds(void); protected: diff --git a/src/usr/pnor/pnor_mboxdd.C b/src/usr/pnor/pnor_mboxdd.C index edb1f4a18..a156ffb8f 100644 --- a/src/usr/pnor/pnor_mboxdd.C +++ b/src/usr/pnor/pnor_mboxdd.C @@ -60,172 +60,6 @@ // Initialized in pnorrp.C extern trace_desc_t* g_trac_pnor; -namespace PNOR -{ - -/** - * @brief Performs an PNOR Read Operation - * This function performs a PNOR 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 PNOR 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 (usrif.H) - * @param[in] i_args This is an argument list for DD framework. - * In this function, there's only one argument, - * containing the PNOR address and chip select - * @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 l_addr = va_arg(i_args, uint64_t); - - do - { - //@todo (RTC:36951) - add support for unaligned data - // Ensure we are operating on a 32-bit (4-byte) boundary - assert( reinterpret_cast<uint64_t>(io_buffer) % 4 == 0 ); - assert( io_buflen % 4 == 0 ); - - // The PNOR device driver interface is initialized with the - // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL. Other target - // access requires a separate PnorMboxDD class created - assert( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ); - - // Read the flash - l_err = Singleton<PnorMboxDD>::instance().readFlash(io_buffer, - io_buflen, - l_addr); - - if(l_err) - { - break; - } - - } - while(0); - - return l_err; -} - -/** - * @brief Performs an PNOR Write Operation - * This function performs a PNOR 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 PNOR 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 (usrif.H) - * @param[in] i_args This is an argument list for DD framework. - * In this function, there's only one argument, - * containing the PNOR address and chip select - * @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; - uint64_t l_addr = va_arg(i_args, uint64_t); - - do - { - //@todo (RTC:36951) - add support for unaligned data - // Ensure we are operating on a 32-bit (4-byte) boundary - assert( reinterpret_cast<uint64_t>(io_buffer) % 4 == 0 ); - assert( io_buflen % 4 == 0 ); - - // The PNOR device driver interface is initialized with the - // MASTER_PROCESSOR_CHIP_TARGET_SENTINEL. Other target - // access requires a separate PnorMboxDD class created - assert( i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL ); - - // Write the flash - l_err = Singleton<PnorMboxDD>::instance().writeFlash(io_buffer, - io_buflen, - l_addr); - - if(l_err) - { - break; - } - - } - while(0); - - return l_err; -} - -/** - * @brief Informs caller if the driver is using - * L3 Cache for fake PNOR or not. - * - * @return Indicate state of fake PNOR - * true = PNOR DD is using L3 Cache for fake PNOR - * false = PNOR DD not using L3 Cache for fake PNOR - */ -bool usingL3Cache() -{ - return false; -} - -/** - * @brief Retrieve some information about the PNOR/SFC hardware - */ -void getPnorInfo( PnorInfo_t& o_pnorInfo ) -{ - o_pnorInfo.mmioOffset = LPC_SFC_MMIO_OFFSET | LPC_FW_SPACE; - o_pnorInfo.norWorkarounds = - Singleton<PnorMboxDD>::instance().getNorWorkarounds(); - o_pnorInfo.flashSize = - Singleton<PnorMboxDD>::instance().getNorSize(); -} - - - -// Register MBOXDD access functions to DD framework -DEVICE_REGISTER_ROUTE(DeviceFW::READ, - DeviceFW::PNOR, - TARGETING::TYPE_PROC, - ddRead); - -DEVICE_REGISTER_ROUTE(DeviceFW::WRITE, - DeviceFW::PNOR, - TARGETING::TYPE_PROC, - ddWrite); - -}; //namespace PNOR - - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - - /** * @brief Performs a PNOR Read Operation */ @@ -675,3 +509,11 @@ PnorMboxDD::PnorMboxDD( TARGETING::Target* i_target ) PnorMboxDD::~PnorMboxDD() { } + +PnorIf* PnorMboxDD::probe(TARGETING::Target* i_target) +{ + /* If we get so far as to probe mbox, it better be available */ + TRACFCOMP(g_trac_pnor, "PnorMboxDD: Detected AST mailbox HIOMAP transport"); + + return new PnorMboxDD(i_target); +} diff --git a/src/usr/pnor/pnor_mboxdd.H b/src/usr/pnor/pnor_mboxdd.H index 2a10c0695..16105efe2 100644 --- a/src/usr/pnor/pnor_mboxdd.H +++ b/src/usr/pnor/pnor_mboxdd.H @@ -27,6 +27,8 @@ #include <limits.h> #include <config.h> +#include "pnorif.H" + namespace PNOR { class UdPnorDDParms; @@ -46,59 +48,14 @@ class astMbox; * @brief PNOR Device Driver Class * Provides access to the PNOR flash via the LPC MBOX hardware */ -class PnorMboxDD +class PnorMboxDD: public PnorIf { public: - /** - * @brief Performs a PNOR Read Operation - * - * @parm o_buffer Buffer to read data into - * @parm io_buflen Input: Number of bytes to read, - * Output: Number of bytes actually read - * @parm i_address Offset into flash to read - * - * @return Error from operation + /** @brief Test for the AST mailbox HIOMAP transport and return an + * appropriate PnorDD instance if detected, otherwise nullptr. */ - errlHndl_t readFlash(void* o_buffer, - size_t& io_buflen, - uint64_t i_address); - - /** - * @brief Performs a PNOR Write Operation - * - * @parm i_buffer Buffer to write data from - * @parm io_buflen Input: Number of bytes to write, - * Output: Number of bytes actually written - * @parm i_address Offset into flash to write - * - * @return Error from operation - */ - errlHndl_t writeFlash(const void* i_buffer, - size_t& io_buflen, - uint64_t i_address); - - /** - * @brief Informs caller if PNORDD is using - * L3 Cache for fake PNOR or not. - * - * @return Indicate state of fake PNOR - * true = PNOR DD is using L3 Cache for fake PNOR - * false = PNOR DD not using L3 Cache for fake PNOR - */ - bool usingL3Cache( ); - - /** - * @brief Retrieve size of NOR flash - * @return Size of PNOR in bytes - */ - uint32_t getNorSize( void ); - - /** - * @brief Retrieve bitstring of NOR workarounds - * @return NOR workarounds (see VendorWorkarounds in norflash.H) - */ - uint32_t getNorWorkarounds( void ); + static PnorIf* probe(TARGETING::Target* i_target); /** * @brief Constructor @@ -111,7 +68,19 @@ class PnorMboxDD /** * @brief Destructor */ - ~PnorMboxDD(); + virtual ~PnorMboxDD(); + + virtual errlHndl_t readFlash(void* o_buffer, + size_t& io_buflen, + uint64_t i_address); + + virtual errlHndl_t writeFlash(const void* i_buffer, + size_t& io_buflen, + uint64_t i_address); + + virtual uint32_t getNorSize(void); + + virtual uint32_t getNorWorkarounds(void); protected: diff --git a/src/usr/pnor/pnorif.H b/src/usr/pnor/pnorif.H new file mode 100644 index 000000000..598ea2555 --- /dev/null +++ b/src/usr/pnor/pnorif.H @@ -0,0 +1,81 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/pnor/pnorif.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2018 */ +/* [+] 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. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __PNORIF_H +#define __PNORIF_H + +#include <errl/errlentry.H> + +class PnorIf +{ + public: + /** + * @brief Performs a PNOR Read Operation + * + * @parm o_buffer Buffer to read data into + * @parm io_buflen Input: Number of bytes to read, + * Output: Number of bytes actually read + * @parm i_address Offset into flash to read + * + * @return Error from operation + */ + virtual errlHndl_t readFlash(void* o_buffer, + size_t& io_buflen, + uint64_t i_address) = 0; + + /** + * @brief Performs a PNOR Write Operation + * + * @parm i_buffer Buffer to write data from + * @parm io_buflen Input: Number of bytes to write, + * Output: Number of bytes actually written + * @parm i_address Offset into flash to write + * + * @return Error from operation + */ + virtual errlHndl_t writeFlash(const void* i_buffer, + size_t& io_buflen, + uint64_t i_address) = 0; + + /** + * @brief Retrieve size of NOR flash + * @return Size of PNOR in bytes + */ + virtual uint32_t getNorSize(void) = 0; + + /** + * @brief Retrieve bitstring of NOR workarounds + * @return NOR workarounds (see VendorWorkarounds in norflash.H) + */ + virtual uint32_t getNorWorkarounds(void) = 0; + + /** + * @brief Destructor + */ + virtual ~PnorIf(void) + { + } +}; + +#endif diff --git a/src/usr/pnor/pnorvalid.C b/src/usr/pnor/pnorvalid.C index 342959b05..91b10109f 100644 --- a/src/usr/pnor/pnorvalid.C +++ b/src/usr/pnor/pnorvalid.C @@ -47,17 +47,14 @@ #include <pnor/pnorif.H> #include <pnor/pnor_reasoncodes.H> #include <lpc/lpcif.H> -#ifdef CONFIG_PNORDD_IS_SFC +#if defined(CONFIG_PNORDD_IS_SFC) #include "pnor_sfcdd.H" using PnorDD = PnorSfcDD; -#elif CONFIG_PNORDD_IS_BMCMBOX -#include "pnor_mboxdd.H" -using PnorDD = PnorMboxDD; -#elif CONFIG_PNORDD_IS_IPMI -#include "pnor_ipmidd.H" -using PnorDD = PnorIpmiDD; +#elif (defined(CONFIG_PNORDD_IS_BMCMBOX) || defined(CONFIG_PNORDD_IS_IPMI)) +#include "pnor_hiomapdd.H" +using PnorDD = PnorHiomapDD; #else -#error "No PNOR DD implementation configured" +#error "No PNOR DD configured" #endif // Used for creating an Invalid TOC ("PNOR") diff --git a/src/usr/pnor/test/pnorddtest.H b/src/usr/pnor/test/pnorddtest.H index 44491d973..fa38413ff 100644 --- a/src/usr/pnor/test/pnorddtest.H +++ b/src/usr/pnor/test/pnorddtest.H @@ -40,19 +40,16 @@ #include <devicefw/userif.H> #include <kernel/console.H> #include <sys/time.h> -#ifdef CONFIG_PNORDD_IS_SFC +#if defined(CONFIG_PNORDD_IS_SFC) #include "pnor_sfcdd.H" using PnorDD = PnorSfcDD; -#elif CONFIG_PNORDD_IS_BMCMBOX -#include "pnor_mboxdd.H" -using PnorDD = PnorMboxDD; -#elif CONFIG_PNORDD_IS_IPMI -#include "pnor_ipmidd.H" -using PnorDD = PnorIpmiDD; +#elif (defined(CONFIG_PNORDD_IS_BMCMBOX) || defined(CONFIG_PNORDD_IS_IPMI)) +#include "pnor_hiomapdd.H" +using PnorDD = PnorHiomapDD; #else -#error "No PNOR DD implementation configured" +#error "No PNOR DD configured" #endif -#include "../pnorrp.H" +#include "pnorrp.H" #include <list> #include <targeting/common/attributes.H> |

