summaryrefslogtreecommitdiffstats
path: root/src/usr/sbeio
diff options
context:
space:
mode:
authorRoland Veloz <rveloz@us.ibm.com>2018-03-27 11:17:43 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-06-01 23:56:31 -0400
commitc6916a42d34bdd1c9502056740ec3a819c082099 (patch)
tree9876a2d6e6a72d66b6733a68dcb308f18db493a8 /src/usr/sbeio
parent6bb10d4941533e21d5b01c634d7f2fcaed83364c (diff)
downloadtalos-hostboot-c6916a42d34bdd1c9502056740ec3a819c082099.tar.gz
talos-hostboot-c6916a42d34bdd1c9502056740ec3a819c082099.zip
Add support for getting SBE Capabilites; extract SBE Version, Commit ID and Tags
Structure sbeCapabilities_t was added to the sbe_utils.H, a common file that can be shared among other files that need the sbeCapabilities_t struct. The psuCommand structure was updated, in file sbe_psudd.H, to facilitate the PSU call to get SBE Capabilities. Also structs fifoGetCapabilitiesResponse/ fifoGetCapabilitiesRequest were added to file sbe_fifodd to facilitate the FIFO call to get SBE Capabilities. Attributes SBE_COMMIT_ID, SBE_VERSION_INFO and SBE_RELEASE_TAGS were added to the target '<id>chip-processor</id>'. These attributes are the ultimate receiver of the SBE capabilities' version, commit id and release tags info. New file sbe_capabilities.C contains the call to getPsuSbeCapabilities and getFifoSbeCapabilities which ultimately perform the call to do the PSU chip operation, FIFO chip operation and update the attributes above. In step 6, host_discover_targets, and in step 8, call_proc_check_slave_sbe_seeprom_complete, is where the calls to getPsuSbeCapabilities and getFifoSbeCapabilities are made respectively. The file FipS_SBE_Interface_Specification_v1.3a.pdf (FIFO), file Host_SBE_Interface_Specification_v0.9d.pdf and looking at HW code were used to guide the coding of this. Change-Id: I32ccdeab7bf0a478298b199d42d74650a3f393f6 RTC:181139 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/56317 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Prachi Gupta <pragupta@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/sbeio')
-rw-r--r--src/usr/sbeio/makefile1
-rw-r--r--src/usr/sbeio/sbe_fifodd.H46
-rw-r--r--src/usr/sbeio/sbe_getCapabilities.C366
3 files changed, 413 insertions, 0 deletions
diff --git a/src/usr/sbeio/makefile b/src/usr/sbeio/makefile
index fccde6aa4..7885d6670 100644
--- a/src/usr/sbeio/makefile
+++ b/src/usr/sbeio/makefile
@@ -48,6 +48,7 @@ OBJS += sbe_getSBEFFDC.o
OBJS += sbe_memRegionMgr.o
OBJS += sbe_fifo_buffer.o
OBJS += sbe_ffdc_package_parser.o
+OBJS += sbe_getCapabilities.o
# sbeio's sub directories
SUBDIRS += test.d
diff --git a/src/usr/sbeio/sbe_fifodd.H b/src/usr/sbeio/sbe_fifodd.H
index e336ea08d..8f7478218 100644
--- a/src/usr/sbeio/sbe_fifodd.H
+++ b/src/usr/sbeio/sbe_fifodd.H
@@ -38,6 +38,7 @@
#include <errl/errlentry.H>
#include <util/singleton.H>
#include <error_info_defs.H>
+#include <sbeio/sbe_utils.H>
namespace SBEIO
{
@@ -119,6 +120,7 @@ class SbeFifo
enum fifoGenericMessage
{
SBE_FIFO_CMD_GET_SBE_FFDC = 0x01,
+ SBE_FIFO_CMD_GET_CAPABILITIES = 0x02,
};
/**
@@ -271,6 +273,27 @@ class SbeFifo
} PACKED;
/**
+ * @brief Struct for FIFO Get Capabilities Request
+ *
+ * Complies with document FipS_SBE_Interface_Specification_v1.5b-1.pdf
+ */
+ struct fifoGetCapabilitiesRequest
+ {
+ uint32_t wordCnt; // 0x02 (The number of 32 bits in msg)
+ uint16_t reserved;
+ uint8_t commandClass; // 0xA8 (SBE_FIFO_CLASS_GENERIC_MESSAGE)
+ uint8_t command; // 0x02 (SBE_FIFO_CMD_GET_CAPABILITIES)
+ fifoGetCapabilitiesRequest() :
+ wordCnt(2)
+ , reserved(0)
+ , commandClass(SBE_FIFO_CLASS_GENERIC_MESSAGE)
+ , command(SBE_FIFO_CMD_GET_CAPABILITIES)
+ {
+ }
+ } PACKED;
+
+
+ /**
* @brief enums for FIFO Magic values
*/
enum fifoMagic
@@ -385,6 +408,29 @@ class SbeFifo
fifoContinueMpiplResponse() {}
} PACKED;
+
+ /**
+ * @brief Struct for FIFO Get Capabilities response
+ *
+ * The actual number of returned words varies based on whether there was
+ * an error.
+ *
+ * Complies with document FipS_SBE_Interface_Specification_v1.5b-1.pdf
+ */
+ struct fifoGetCapabilitiesResponse
+ {
+ SBEIO::sbeCapabilities_t capabilities;
+ statusHeader status;
+ struct fapi2::ffdc_struct ffdc; // ffdc data
+ uint32_t status_distance; // distance to status
+ fifoGetCapabilitiesResponse() :
+ capabilities()
+ , status{ 0 }
+ , status_distance(0)
+ {
+ }
+ } PACKED;
+
/**
* @Brief perform SBE FIFO chip-op
*
diff --git a/src/usr/sbeio/sbe_getCapabilities.C b/src/usr/sbeio/sbe_getCapabilities.C
new file mode 100644
index 000000000..4a0d7d90a
--- /dev/null
+++ b/src/usr/sbeio/sbe_getCapabilities.C
@@ -0,0 +1,366 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/sbeio/sbe_getCapabilities.C $ */
+/* */
+/* 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 */
+/**
+* @file sbe_getCapabilities.C
+* @brief Get the capabilities from the SBE
+*/
+
+#include <errl/errlmanager.H> // errlHndl_t
+#include <sbeio/sbe_psudd.H> // SbeFifo::psuCommand
+#include "sbe_fifodd.H" // SbeFifo::fifoGetCapabilitiesRequest
+#include <sbeio/sbe_utils.H> // sbeCapabilities_t
+#include <sbeio/sbeioreasoncodes.H> // SBEIO_PSU, SBEIO_FIFO,
+#include <targeting/common/commontargeting.H> // get_huid
+#include <util/align.H> // ALIGN_X
+#include <sys/mm.h> // mm_virt_to_phys
+
+extern trace_desc_t* g_trac_sbeio;
+
+namespace SBEIO
+{
+using namespace TARGETING;
+using namespace ERRORLOG;
+
+ /**
+ * @brief Apply the SBE capabilities to the given target
+ *
+ * @param[in] i_target Target to apply the SBE capabilities on
+ *
+ * @param[in] i_capabilities The SBE capabilities themselves
+ *
+ */
+void applySbeCapabilities(TargetHandle_t i_target,
+ sbeCapabilities_t &i_capabilities)
+{
+ // Get the SBE Version from the SBE Capabilities and set the
+ // attribute associated with SBE Version
+ ATTR_SBE_VERSION_INFO_type l_sbeVersionInfo =
+ TWO_UINT16_TO_UINT32(i_capabilities.majorVersion,
+ i_capabilities.minorVersion);
+ i_target->setAttr<ATTR_SBE_VERSION_INFO>(l_sbeVersionInfo);
+ TRACFCOMP(g_trac_sbeio,"applySbeCapabilities: "
+ "Retrieved SBE Version: 0x%X", l_sbeVersionInfo);
+
+ // Get the SBE Commit ID from the SBE Capabilities and set the
+ // attribute associated with SBE Commit ID
+ ATTR_SBE_COMMIT_ID_type l_sbeCommitId = i_capabilities.commitId;
+ i_target->setAttr<ATTR_SBE_COMMIT_ID>(l_sbeCommitId);
+ TRACFCOMP(g_trac_sbeio,"applySbeCapabilities: "
+ "Retrieved SBE Commit ID: 0x%X", l_sbeCommitId);
+
+ // Get the SBE Release Tag from the SBE Capabilities and set the
+ // attribute associated with SBE Release Tag
+ ATTR_SBE_RELEASE_TAG_type l_sbeReleaseTagString = {0};
+
+ // Make sure the sizes are compatible.
+ static_assert(SBE_RELEASE_TAG_MAX_CHARS <= ATTR_SBE_RELEASE_TAG_max_chars,
+ "Copy error - size of source is greater than size of destination.");
+
+ // Copy the release tags over into a more compatible type and set
+ // the SBE Release Tags attribute
+ strncpy(l_sbeReleaseTagString,
+ i_capabilities.releaseTag,
+ SBE_RELEASE_TAG_MAX_CHARS);
+ i_target->setAttr<ATTR_SBE_RELEASE_TAG>(l_sbeReleaseTagString);
+ TRACFCOMP(g_trac_sbeio,"applySbeCapabilities: "
+ "Retrieved SBE Release Tag: %s", l_sbeReleaseTagString);
+}
+
+/**
+ * getPsuSbeCapabilities
+ */
+errlHndl_t getPsuSbeCapabilities(TargetHandle_t i_target)
+{
+ errlHndl_t l_errl(nullptr);
+
+ TRACDCOMP(g_trac_sbeio, ENTER_MRK "getPsuSbeCapabilities");
+
+ // Cache the SBE Capabilities' size for future uses
+ size_t l_sbeCapabilitiesSize = sizeof(sbeCapabilities_t);
+
+ // Set up the buffer which the SBE will copy the capabilities info to
+ // Create buffer with enough size to be properly aligned
+ uint8_t * l_sbeCapabilitiesReadBuffer = static_cast<uint8_t*>(
+ malloc(l_sbeCapabilitiesSize +
+ (SbePsu::SBE_CAPABILITIES_ALIGNMENT_SIZE_IN_BYTES - 1)) );
+
+ // Align the buffer
+ uint64_t l_sbeCapabilitiesReadBufferAligned =
+ ALIGN_X(reinterpret_cast<uint64_t>(l_sbeCapabilitiesReadBuffer),
+ SbePsu::SBE_CAPABILITIES_ALIGNMENT_SIZE_IN_BYTES);
+
+ // Clear buffer up to the size of the capabilities
+ memset(reinterpret_cast<uint8_t*>(l_sbeCapabilitiesReadBufferAligned),
+ 0, l_sbeCapabilitiesSize );
+
+ // Create a PSU request message and initialize it
+ SbePsu::psuCommand l_psuCommand(
+ SbePsu::SBE_REQUIRE_RESPONSE |
+ SbePsu::SBE_REQUIRE_ACK, //control flags
+ SbePsu::SBE_PSU_GENERIC_MESSAGE, //command class
+ SbePsu::SBE_PSU_MSG_GET_CAPABILITIES); //command
+ l_psuCommand.cd7_getSbeCapabilities_CapabilitiesSize =
+ ALIGN_X(l_sbeCapabilitiesSize,
+ SbePsu::SBE_CAPABILITIES_ALIGNMENT_SIZE_IN_BYTES);
+ l_psuCommand.cd7_getSbeCapabilities_CapabilitiesAddr =
+ mm_virt_to_phys(
+ reinterpret_cast<void*>(l_sbeCapabilitiesReadBufferAligned));
+
+ // Create a PSU response message
+ SbePsu::psuResponse l_psuResponse;
+
+ do
+ {
+ // Make the call to perform the PSU Chip Operation
+ l_errl = SbePsu::getTheInstance().performPsuChipOp(
+ i_target,
+ &l_psuCommand,
+ &l_psuResponse,
+ SbePsu::MAX_PSU_SHORT_TIMEOUT_NS,
+ SbePsu::SBE_GET_CAPABILITIES_REQ_USED_REGS,
+ SbePsu::SBE_GET_CAPABILITIES_RSP_USED_REGS);
+
+ // Before continuing, make sure this request is honored
+ if (SBE_PRI_INVALID_COMMAND == l_psuResponse.primaryStatus &&
+ SBE_SEC_COMMAND_NOT_SUPPORTED == l_psuResponse.secondaryStatus)
+ {
+ TRACFCOMP(g_trac_sbeio, "getPsuSbeCapabilities: SBE firmware does "
+ "not support PSU get capabilities request");
+
+ // Do not pass back any errors
+ delete l_errl;
+ l_errl = nullptr;
+ break;
+ }
+
+
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_sbeio,
+ "getPsuSbeCapabilities: "
+ "Call to performPsuChipOp failed, error returned");
+
+ TRACDBIN(g_trac_sbeio,
+ "getPsuSbeCapabilities: capabilities data",
+ reinterpret_cast<uint8_t*>(l_sbeCapabilitiesReadBufferAligned),
+ l_sbeCapabilitiesSize);
+
+ break;
+ }
+
+ // Sanity check - are HW and HB communications in sync?
+ if ((SbePsu::SBE_PSU_GENERIC_MESSAGE !=
+ l_psuResponse.sbe_commandClass) ||
+ (SbePsu::SBE_PSU_MSG_GET_CAPABILITIES !=
+ l_psuResponse.sbe_command))
+ {
+ TRACFCOMP(g_trac_sbeio,
+ "Call to performPsuChipOp returned an unexpected "
+ "message type; "
+ "command class returned:0x%X, "
+ "expected command class:0x%X, "
+ "command returned:0x%X, "
+ "expected command:0x%X",
+ l_psuResponse.sbe_commandClass,
+ SbePsu::SBE_PSU_GENERIC_MESSAGE,
+ l_psuResponse.sbe_command,
+ SbePsu::SBE_PSU_MSG_GET_CAPABILITIES);
+
+ /*@
+ * @errortype
+ * @moduleid SBEIO_PSU
+ * @reasoncode SBEIO_RECEIVED_UNEXPECTED_MSG
+ * @userdata1 Target HUID
+ * @userdata2[0:15] Requested command class
+ * @userdata2[16:31] Requested command
+ * @userdata2[32:47] Returned command class
+ * @userdata2[48:63] Returned command
+ * @devdesc Call to PSU Chip Op returned an
+ * unexpected message type.
+ */
+ l_errl = new ErrlEntry(
+ ERRL_SEV_INFORMATIONAL,
+ SBEIO_PSU,
+ SBEIO_RECEIVED_UNEXPECTED_MSG,
+ get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ TWO_UINT16_TO_UINT32(SbePsu::SBE_PSU_GENERIC_MESSAGE,
+ SbePsu::SBE_PSU_MSG_GET_CAPABILITIES),
+ TWO_UINT16_TO_UINT32(l_psuResponse.sbe_commandClass,
+ l_psuResponse.sbe_command) ));
+
+ l_errl->collectTrace(SBEIO_COMP_NAME, 256);
+
+ break;
+ }
+
+ // Check for any difference in sizes (expected vs returned)
+ // This may happen but it is not a show stopper, just note it
+ if (l_psuResponse.sbe_capabilities_size != l_sbeCapabilitiesSize)
+ {
+ TRACFCOMP(g_trac_sbeio, "getPsuSbeCapabilities:"
+ "Call to performPsuChipOp returned an unexpected size: "
+ "capabilities size returned:%d, "
+ "expected capabilities size:%d, ",
+ l_psuResponse.sbe_capabilities_size,
+ l_sbeCapabilitiesSize);
+ }
+
+ // Create an SBE Capabilities structure to make it easy to pull data;
+ // clear memory before use
+ sbeCapabilities_t l_sbeCapabilities;
+ memset(&l_sbeCapabilities, 0, sizeof(sbeCapabilities_t));
+
+ // If the returned size is greater than or equal to the needed size,
+ // then copy all of the SBE capabilities
+ if (l_psuResponse.sbe_capabilities_size >= l_sbeCapabilitiesSize)
+ {
+ memcpy (&l_sbeCapabilities,
+ reinterpret_cast<void*>(l_sbeCapabilitiesReadBufferAligned),
+ l_sbeCapabilitiesSize);
+ }
+ // If the returned size is less than the needed size and is not zero
+ // then copy what was given
+ else if (l_psuResponse.sbe_capabilities_size)
+ {
+ memcpy (&l_sbeCapabilities,
+ reinterpret_cast<void*>(l_sbeCapabilitiesReadBufferAligned),
+ l_psuResponse.sbe_capabilities_size);
+ }
+
+ // If data returned, retrieve it
+ if (l_psuResponse.sbe_capabilities_size)
+ {
+ applySbeCapabilities(i_target, l_sbeCapabilities);
+ }
+ } while (0);
+
+ // Free the buffer
+ if (l_sbeCapabilitiesReadBuffer)
+ {
+ free(l_sbeCapabilitiesReadBuffer);
+ l_sbeCapabilitiesReadBuffer = nullptr;
+ }
+
+ TRACFCOMP(g_trac_sbeio, EXIT_MRK "getPsuSbeCapabilities");
+
+ return l_errl;
+};
+
+
+/**
+ * getFifoSbeCapabilities
+ */
+errlHndl_t getFifoSbeCapabilities(TargetHandle_t i_target)
+{
+ errlHndl_t l_errl(nullptr);
+
+ TRACDCOMP(g_trac_sbeio, ENTER_MRK "getFifoSbeCapabilities");
+
+ do
+ {
+ // Get the needed structures to make the FIFO call
+ // Create a FIFO request message. Default ctor initializes correctly
+ SbeFifo::fifoGetCapabilitiesRequest l_fifoRequest;
+
+ // Create a FIFO response message. No need to iniitilaize
+ SbeFifo::fifoGetCapabilitiesResponse l_fifoResponse;
+
+ // Make the call to perform the FIFO Chip Operation
+ l_errl = SbeFifo::getTheInstance().performFifoChipOp(
+ i_target,
+ reinterpret_cast<uint32_t *>(&l_fifoRequest),
+ reinterpret_cast<uint32_t *>(&l_fifoResponse),
+ sizeof(l_fifoResponse));
+
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_sbeio,
+ "Call to performFifoChipOp failed, error returned");
+ break;
+ }
+
+ // Sanity check - are HW and HB communications in sync?
+ if ((SbeFifo::FIFO_STATUS_MAGIC != l_fifoResponse.status.magic) ||
+ (SbeFifo::SBE_FIFO_CLASS_GENERIC_MESSAGE !=
+ l_fifoResponse.status.commandClass) ||
+ (SbeFifo::SBE_FIFO_CMD_GET_CAPABILITIES !=
+ l_fifoResponse.status.command))
+ {
+ TRACFCOMP(g_trac_sbeio,
+ "Call to performFifoChipOp returned an unexpected "
+ "message type; "
+ "magic code returned:0x%X, "
+ "expected magic code:0x%X, "
+ "command class returned:0x%X, "
+ "expected command class:0x%X, "
+ "command returned:0x%X, "
+ "expected command:0x%X",
+ l_fifoResponse.status.magic,
+ SbeFifo::FIFO_STATUS_MAGIC,
+ l_fifoResponse.status.commandClass,
+ SbeFifo::SBE_FIFO_CLASS_GENERIC_MESSAGE,
+ l_fifoResponse.status.command,
+ SbeFifo::SBE_FIFO_CMD_GET_CAPABILITIES);
+
+ /*@
+ * @errortype
+ * @moduleid SBEIO_FIFO
+ * @reasoncode SBEIO_RECEIVED_UNEXPECTED_MSG
+ * @userdata1 Target HUID
+ * @userdata2[0:15] Requested command class
+ * @userdata2[16:31] Requested command
+ * @userdata2[32:47] Returned command class
+ * @userdata2[48:63] Returned command
+ * @devdesc Call to FIFO Chip Op returned an
+ * unexpected message type.
+ */
+ l_errl = new ErrlEntry(
+ ERRL_SEV_INFORMATIONAL,
+ SBEIO_FIFO,
+ SBEIO_RECEIVED_UNEXPECTED_MSG,
+ get_huid(i_target),
+ TWO_UINT32_TO_UINT64(
+ TWO_UINT16_TO_UINT32(SbeFifo::SBE_FIFO_CLASS_GENERIC_MESSAGE,
+ SbeFifo::SBE_FIFO_CMD_GET_CAPABILITIES),
+ TWO_UINT16_TO_UINT32(l_fifoResponse.status.commandClass,
+ l_fifoResponse.status.command) ));
+
+ l_errl->collectTrace(SBEIO_COMP_NAME, 256);
+
+ break;
+ }
+
+ applySbeCapabilities(i_target, l_fifoResponse.capabilities);
+ }
+ while(0);
+
+ TRACDCOMP(g_trac_sbeio, EXIT_MRK "getFifoSbeCapabilities");
+
+ return l_errl;
+};
+
+} //end namespace SBEIO
+
OpenPOWER on IntegriCloud