summaryrefslogtreecommitdiffstats
path: root/src/usr/pnor
diff options
context:
space:
mode:
authorAndrew Jeffery <andrewrj@au1.ibm.com>2018-09-17 17:23:19 +0930
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-10-10 13:46:36 -0500
commit9518b4c189c96a26cb80a57aa441e38f33bdc5cf (patch)
tree3ee47d1136fae625b0ed7a8ccea91e8328682695 /src/usr/pnor
parent7c16f3706b3c822e72d369d828939a800acccdd2 (diff)
downloadblackbird-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/makefile6
-rw-r--r--src/usr/pnor/pnor_hiomapdd.C260
-rw-r--r--src/usr/pnor/pnor_hiomapdd.H68
-rw-r--r--src/usr/pnor/pnor_ipmidd.C209
-rw-r--r--src/usr/pnor/pnor_ipmidd.H71
-rw-r--r--src/usr/pnor/pnor_mboxdd.C174
-rw-r--r--src/usr/pnor/pnor_mboxdd.H69
-rw-r--r--src/usr/pnor/pnorif.H81
-rw-r--r--src/usr/pnor/pnorvalid.C13
-rw-r--r--src/usr/pnor/test/pnorddtest.H15
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>
OpenPOWER on IntegriCloud