Skip to content

Commit

Permalink
Route scom operations on OCMB chips to exp_i2c_scom interface
Browse files Browse the repository at this point in the history
Before we get OMI targets trained we must use i2c to access scom
registers on the OCMB chip. This commit does all of the plumbing so
when HWP calls getScom() on a OCMB target, the hostboot platform
recognizes this as a special scom and routes it to a new i2scom DD.
This device driver will truncate the scom address to 32 bits and
run the exp_i2c_putscom/exp_i2c_getscom interfaces to perform
the operation. Eventually we need to also support MMIO scoms to
the OCMB chip, the MMIO scoms will be used after the OMI training
is complete.

Change-Id: I0018cc8d25f74d1253b72c3112d3e344a4248416
RTC: 196806
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67976
Reviewed-by: Matt Derksen <mderkse1@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Ilya Smirnov <ismirno@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: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
crgeddes authored and dcrowell77 committed Nov 15, 2018
1 parent 73cad1f commit 6cf801f
Show file tree
Hide file tree
Showing 18 changed files with 879 additions and 38 deletions.
11 changes: 9 additions & 2 deletions src/include/usr/devicefw/driverif.H
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2011,2017 */
/* Contributors Listed Below - COPYRIGHT 2011,2018 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -56,7 +56,7 @@ namespace DeviceFW
HOSTI2C,
FSI_I2C,
SBEFIFOSCOM,

I2CSCOM,
LAST_DRIVER_ACCESS_TYPE
};

Expand Down Expand Up @@ -109,6 +109,13 @@ namespace DeviceFW
#define DEVICE_IBSCOM_ADDRESS(i_address) \
DeviceFW::IBSCOM, static_cast<uint64_t>((i_address))

/** Construct the device addressing parameters for I2CSCOM (i2c scom)
* device ops.
* @param[in] i_address - I2CSCOM address to operate on.
*/
#define DEVICE_I2CSCOM_ADDRESS(i_address) \
DeviceFW::I2CSCOM, static_cast<uint64_t>((i_address))

/**
* @brief Macro that handles the I2C parameters
*/
Expand Down
48 changes: 48 additions & 0 deletions src/include/usr/expscom/expscom_reasoncodes.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/include/usr/expscom/expscom_reasoncodes.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 __EXPSCOM_REASONCODES_H
#define __EXPSCOM_REASONCODES_H

#include <hbotcompid.H>

namespace EXPSCOM
{
enum EXPSCOMModuleId
{
MOD_OCMBSCOM_INVALID = 0x00, // Zero is an invalid module id
MOD_I2CSCOM_PERFORM_OP = 0x01, // i2cscom.C : i2cScomPerformOp
};

enum EXPSCOMReasonCode
{
RC_INVALID = EXPSCOM_COMP_ID | 0x00,
RC_INVALID_LENGTH = EXPSCOM_COMP_ID | 0x01,
RC_INVALID_MODEL_TYPE = EXPSCOM_COMP_ID | 0x02,
RC_INVALID_OPTYPE = EXPSCOM_COMP_ID | 0x03,
RC_INVALID_ADDRESS = EXPSCOM_COMP_ID | 0x04,
};
};

#endif
10 changes: 9 additions & 1 deletion src/include/usr/hbotcompid.H
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,14 @@ const compId_t NVDIMM_COMP_ID = 0x3500;
const char NVDIMM_COMP_NAME[] = "nvdimm";
//@}

/** @name EXPSCOM
* Explorer OCMB Scom DDs (MMIO and I2C explorer scom drivers)
*/
//@{
const compId_t EXPSCOM_COMP_ID = 0x3600;
const char EXPSCOM_COMP_NAME[] = "expscom";
//@}

/** @name NVRAM
* NVRAM Support component
*/
Expand All @@ -461,7 +469,7 @@ const char NVRAM_COMP_NAME[] = "nvram";
//@{
const compId_t HDAT_COMP_ID = 0x9000;
const char HDAT_COMP_NAME[] = "hdat";

//@}

/** @name PRDF
* PRDF component
Expand Down
1 change: 1 addition & 0 deletions src/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ EXTENDED_MODULES += $(if $(CONFIG_NVDIMM),nvdimm)
EXTENDED_MODULES += $(if $(CONFIG_FSP_BUILD),,nvram)
EXTENDED_MODULES += mmio
EXTENDED_MODULES += smf
EXTENDED_MODULES += expscom

#***************************************
# Working test modules
Expand Down
141 changes: 141 additions & 0 deletions src/usr/expscom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
## Overall Description
The expscom module contains Hostboots device drivers to communicate with scom regs
on the Explorer Open-Capi Memory Buffer (OCMB) chip. Initially when Hostboot starts
the SCOM_SWITCHES attribute on all OCMB chips will be set such that useI2cScom field
is 1 and all other fields are 0. After OMI 's are trained the SCOM_SWITCHES attribute
on the OCMB targets will change so that the useIbScom field will be set to 1 and
all other fields will be 0.

### Explorer I2C SCOM

When the useI2cScom field is set in SCOM_SWITCHES this is how the
fapi2::getScom API for OCMB targets will be processed (lets say for now this is IBM scom address):

* Generic FAPI2 getScom API that will be called in a hardware procedure (HWP)


fapi2::getScom(myOcmbTarget, scomAddr, io_buffer);
* Platform Specifc FAPI2 getScom API which the generic wrapper immediately calls


fapi2::platGetScom(myOcmbTarget, scomAddr, io_buffer);
* Platform Specifc FAPI2 getScom API resolves to calling into Hostboot's device framework to whatever
function is registered to read OCMB target for DeviceFW::SCOM operations


DeviceFW::deviceRead(myOcmbTarget, io_buffer,
sizeof(uint64_t), DeviceFW::SCOM,
scomAddr, READ)
* scomPeformOp is what is defined to handle DeviceFW::SCOM operations to the OCMB chip targets


SCOM::scomPerformOp(READ, myOCMBTarget, io_buffer,
sizeof(uint64_t), DeviceFW::SCOM,
scomAddr)
* scomPeformOp is basically a wrapper for checkIndirectAndDoScom There are no indirect scoms for
OCMB target scoms so we will end up calling doScomOp


checkIndirectAndDoScom(READ, myOCMBTarget, io_buffer,
sizeof(uint64_t), DeviceFW::SCOM,
scomAddr)

* doScomOp looks at the SCOM_SWITCHES attribute and decides which type of scom to do for the given target.


doScomOp(READ, myOCMBTarget, io_buffer,
sizeof(uint64_t), DeviceFW::SCOM,
scomAddr)

* If the useI2cScom field is set to 1 then we will call the function that is registered to i2c scoms for OCMB targets


deviceOp(READ, myOCMBTarget, io_buffer,
sizeof(uint64_t), DeviceFW::I2CSCOM,
scomAddr)

* i2cScomPerformOp is the function that is registered to handle i2cScom operations,
this function will perform some simple param validation before deciding whether to
call the getScom or putScom depending if the op is READ or WRITE respectively


i2cScomPerformOp(READ, myOCMBTarget, io_buffer,
sizeof(uint64_t), DeviceFW::I2CSCOM,
scomAddr)

* The base device drivers are defined as EKB HWPs so we must run FAPI_EXEC_HWP in order to correctly call the i2c_get_scom hwp\
**Note: that EXEC and not INVOKE is used because it is likely this path
will be called within other HWPs and nesting INVOKE calls causes deadlock
due to the way we use mutexes.**


FAPI_EXEC_HWP(l_rc , mss::exp::i2c::i2c_get_scom,
myOCMBTarget, static_cast<uint32_t>(l_scomAddr),
io_buffer);

* The Explorer chip nativly uses 32-bit regs so we must perform two 32-bit operations
(LHS and RHS) in order to get the 64-bits that we expect from the IBM scom


fw_reg_read(myOCMBTarget,
translateIbmI2cScomAddr(i_addr, LHS),
l_readBuffer);

fw_reg_read(myOCMBTarget,
translateIbmI2cScomAddr(i_addr, RHS),
l_readBuffer);

* The RHS and LHS fw_reg_read calls are nearly identical except the address is 4 bytes more
for the RHS. In both cases the way the fw_reg_read works is to first perform an i2cWrite stating
what address and how many bytes we want to read, then perform an i2c read to get the buffer


< build up l_cmd_vector w/ FW_REG_ADDR_LATCH op, op size, addr >
fapi2::putI2c(myOCMBTarget, FW_I2C_SCOM_READ_SIZE,
l_cmd_vector, l_read_data);

< build up l_cmd_vector w/ FW_REG_READ op >
fapi2::getI2c(myOCMBTarget, FW_I2C_SCOM_READ_SIZE,
l_cmd_vector, l_read_data);

* The fapi2::getI2c/putI2c calls will drill down into the drive routing similar to how we drilled down to find the i2cScom driver


platGetI2c( myOCMBTarget, FW_I2C_SCOM_READ_SIZE
l_cmd_vector, l_read_data)

* The hostboot platform specific implementation of platGetI2c will lookup the device route for FAPI_I2C ops to OCMB chips


deviceRead( myOCMBTarget, l_read_data,
FW_I2C_SCOM_READ_SIZE, DeviceFW::FAPI_I2C,
sizeof(l_cmd_vector), l_cmd_vector);

* The function associated with FAPI_I2C ops to OCMB chips is fapiI2cPerformOp. This
wrapper function will look up i2c information about the OCMB target and determine
the i2c address for this operation


fapiI2cPerformOp(READ , myOCMBTarget,
l_read_data, FW_I2C_SCOM_READ_SIZE,
DeviceFW::FAPI_I2C, sizeof(l_cmd_vector),
l_cmd_vector);

* Eventually when the i2c info is known we call i2cRead/i2cWrite which will lookup
the device op route for I2C address on the OCMB's master I2c device (which will be a processor).


i2cRead( myOCMBTargeti2cMaster, l_read_data,
FW_I2C_SCOM_READ_SIZE, &l_myOCMBTargeti2cInfo,
l_cmd_vector, sizeof(l_cmd_vector));

* At this point we will drill down into the platform I2C device driver code


deviceOp( DeviceFW::READ, myOCMBTargeti2cMaster,
l_read_data, FW_I2C_SCOM_READ_SIZE,
DEVICE_I2C_ADDRESS_OFFSET(l_myOCMBTargeti2cInfo->port,
l_myOCMBTargeti2cInfo->engine,
l_myOCMBTargeti2cInfo->devAddr,
sizeof(l_cmd_vector),
l_cmd_vector) );
38 changes: 38 additions & 0 deletions src/usr/expscom/expscomtrace.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/expscom/expscomtrace.C $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,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 */
///
/// @file expscomtrace.C
///
/// @brief Initialized trace descriptor for expscom
///


#include "expscomtrace.H"
#include <limits.h>
#include <hbotcompid.H>

// Trace definition
trace_desc_t* g_trac_expscom = nullptr;
TRAC_INIT(&g_trac_expscom, EXPSCOM_COMP_NAME, 2*KILOBYTE);
39 changes: 39 additions & 0 deletions src/usr/expscom/expscomtrace.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: src/usr/expscom/expscomtrace.H $ */
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,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 */
///
/// @file expscomtrace.H
/// @brief Defines the extern expscom trace
///

#ifndef expscom_TRACE_H_
#define expscom_TRACE_H_

#include <trace/interface.H>
//******************************************************************************
// Trace descriptors that are defined in matching C file
//******************************************************************************
extern trace_desc_t* g_trac_expscom;

#endif // expscom_TRACE_H_

0 comments on commit 6cf801f

Please sign in to comment.