Skip to content

Commit

Permalink
pnor: Fall back to AST mbox transport if IPMI is unavailable
Browse files Browse the repository at this point in the history
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>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67401
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
  • Loading branch information
Andrew Jeffery authored and dcrowell77 committed Oct 17, 2018
1 parent aa42e9d commit d649d2d
Show file tree
Hide file tree
Showing 10 changed files with 514 additions and 453 deletions.
6 changes: 3 additions & 3 deletions src/usr/pnor/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
261 changes: 261 additions & 0 deletions src/usr/pnor/pnor_hiomapdd.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
/* 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/pnorif.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;
}
68 changes: 68 additions & 0 deletions src/usr/pnor/pnor_hiomapdd.H
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit d649d2d

Please sign in to comment.