diff options
| author | Marty Gloff <mgloff@us.ibm.com> | 2017-03-20 14:25:27 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-04-10 13:26:13 -0400 |
| commit | d85536ac35dd97a666b7b8de090f255b1a33c7d8 (patch) | |
| tree | 07df13fd800c898b60659ad54920e7c719f6ee66 | |
| parent | 4a0692811d82840b2c6eed9c892c9a866586b989 (diff) | |
| download | blackbird-hostboot-d85536ac35dd97a666b7b8de090f255b1a33c7d8.tar.gz blackbird-hostboot-d85536ac35dd97a666b7b8de090f255b1a33c7d8.zip | |
SBE message passing interface - call appropriate command processor
Add definitions of SBE message and pass-through command.
Create mechanism to call functions to process commands.
Change-Id: Id14471b1e6f036c278fd5ae1950b942290282c1e
RTC: 170761
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38167
Tested-by: Jenkins Server <pfd-jenkins+hostboot@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: Christian R. Geddes <crgeddes@us.ibm.com>
Reviewed-by: Corey V. Swenson <cswenson@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
| -rw-r--r-- | src/include/usr/sbeio/runtime/sbe_msg_passing.H | 158 | ||||
| -rw-r--r-- | src/include/usr/sbeio/sbeioreasoncodes.H | 7 | ||||
| -rw-r--r-- | src/usr/sbeio/runtime/rt_sbeio.C | 299 | ||||
| -rw-r--r-- | src/usr/targeting/common/xmltohb/attribute_types_hb.xml | 4 |
4 files changed, 417 insertions, 51 deletions
diff --git a/src/include/usr/sbeio/runtime/sbe_msg_passing.H b/src/include/usr/sbeio/runtime/sbe_msg_passing.H new file mode 100644 index 000000000..48d3331ce --- /dev/null +++ b/src/include/usr/sbeio/runtime/sbe_msg_passing.H @@ -0,0 +1,158 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/sbeio/runtime/sbe_msg_passing.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2017 */ +/* [+] 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 SBE_MSG_PASSING_H +#define SBE_MSG_PASSING_H + +#include <stdint.h> +#include <map> +#include <errl/errlmanager.H> +#include <targeting/common/target.H> + + +namespace SBE_MSG +{ + // SBE Communication Buffer for Pass-through commands + /** + * @brief SBE Communication package size in number of pages + */ + const uint8_t SBE_COMM_PKG_SIZE = 1; + + /** + * @brief SBE Communication buffer size + */ + const uint32_t SBE_COMM_BUFFER_SIZE = SBE_COMM_PKG_SIZE * PAGESIZE; + + /** + * @brief SBE Message size / Pass-through Command size + */ + const uint32_t SBE_MSG_SIZE = SBE_COMM_BUFFER_SIZE; + + + // SBE Header Version enums for SBE Header version field + enum sbeHdrVersion + { + SBEHDRVER_FIRST = 0x00010000, // First SBE Header version + // NOTE: Update SBEHDRVER_LATEST with each new version + SBEHDRVER_LATEST = SBEHDRVER_FIRST + }; + + #define ENUM_SBEHDRVER_CHECK(version) (((version) >= SBEHDRVER_FIRST) \ + && ((version) <= SBEHDRVER_LATEST)) + + + // Command Header Version enums for Command Header version field + enum cmdHdrVersion + { + CMDHDRVER_FIRST = 0x00010000, // First Command Hdr version + // NOTE: Update CMDHDRVER_LATEST with each new version + CMDHDRVER_LATEST = CMDHDRVER_FIRST + }; + + #define ENUM_CMDHDRVER_CHECK(version) (((version) >= CMDHDRVER_FIRST) \ + && ((version) <= CMDHDRVER_LATEST)) + + + // Pass-Through Command enums for Command Header command field + enum passThruCmds + { + PASSTHRU_SET_OCC_STATE = 0x00E00001, // Set OCC State + PASSTHRU_GET_OCC_SENSOR = 0x00E00002, // Get OCC Sensor Readings + PASSTHRU_SET_HYPER_ENV = 0x00E00003, // Set Hypervisor Environment + PASSTHRU_QRY_MD_FN = 0x00E00004, // Query Mode and Function + PASSTHRU_RST_PM_COMPLEX = 0x00E00005, // Reset PM Complex + PASSTHRU_CTL_AUTOSLEW = 0x00E00006, // Control Autoslew + PASSTHRU_GET_PSTATE = 0x00E00007, // Get PState Table + }; + + + // SBE Header at start of SBE Message + typedef struct sbeHeader + { + uint32_t version; // SBE header version + uint32_t msgSize; // Message size (Pass-through cmd or rsp) + // Size includes SBE and Command Headers + uint32_t seqId; // Sequence ID + } PACKED sbeHeader_t; + + // Command Header following SBE Header in SBE Message + typedef struct cmdHeader + { + uint32_t version; // Command header version + uint32_t status; // Status of processing (rsp only) + uint32_t dataOffset; // Data offset (cmd or rsp) + // Offset is from beginning of Command Header + uint32_t dataSize; // Data size (cmd or rsp) + // Size does NOT include ANY Header fields + uint32_t command; // Pass-through command + } PACKED cmdHeader_t; + + // Max Pass-through command/response data size + const uint32_t SBE_MSG_MAX_DATA = + SBE_MSG_SIZE - sizeof(sbeHeader_t) - sizeof(cmdHeader_t); + + // SBE Message (Pass-through command or response) + typedef struct sbeMessage + { + sbeHeader_t sbeHdr; // SBE header + cmdHeader_t cmdHdr; // Command header + uint8_t data[SBE_MSG_MAX_DATA]; // Pass-through command/response data + } sbeMessage_t; + + + /** + * @brief Function to process pass-through command from SBE message + * + * @param[in] i_procTgt HB processor target + * @param[in] i_reqDataSize Pass-through command request data size + * @param[in] i_reqData Pass-through command request data + * @param[out] o_rspStatus Pass-through command response status + * @param[out] o_rspDataSize Pass-through command response data size + * @param[out] o_rspData Pass-through command response data + * + * @return errlHndl_t Error log handle on failure. + */ + typedef errlHndl_t (*processCmdFunction_t)(TARGETING::TargetHandle_t, + uint32_t, + uint8_t*, + uint32_t*, + uint32_t*, + uint8_t*); + + // Process Command Map of pass-through command to function used to process + typedef std::map<uint32_t, processCmdFunction_t> ProcessCmdMap_t; + + /** + * @brief Set process pass-through command function in Process Command Map + * + * @param[in] i_command Process pass-through command + * @param[in] i_function Function to process pass-through command + * + * @return int Return code. + */ + int setProcessCmdFunction(enum passThruCmds i_command, + processCmdFunction_t i_function); +} // namespace SBE_MSG + +#endif diff --git a/src/include/usr/sbeio/sbeioreasoncodes.H b/src/include/usr/sbeio/sbeioreasoncodes.H index 0cff071ba..83c3ec00e 100644 --- a/src/include/usr/sbeio/sbeioreasoncodes.H +++ b/src/include/usr/sbeio/sbeioreasoncodes.H @@ -47,6 +47,7 @@ enum sbeioModuleId SBEIO_FIFO = 0x02, SBEIO_FFDC_PARSER = 0x03, SBEIO_FIFO_CONTINUE_MPIPL = 0x04, + SBEIO_RUNTIME = 0x05, }; /** @@ -84,6 +85,12 @@ enum sbeioReasonCode //termination_rc SBEIO_DEAD_SBE = SBEIO_COMP_ID | 0x1B, + // SBEIO Runtime error codes + SBEIO_RT_INVALID_COMMAND = SBEIO_COMP_ID | 0x30, + SBEIO_RT_FUNCTION_NOT_SET = SBEIO_COMP_ID | 0x31, + SBEIO_RT_RSP_DATA_TOO_LARGE = SBEIO_COMP_ID | 0x32, + SBEIO_RT_NO_SBE_COMM_BUFFER = SBEIO_COMP_ID | 0x38, + // Remove once we collect the FFDC ourselves - @todo-RTC:144313 //termination_rc SBEIO_HWSV_COLLECT_SBE_RC = SBEIO_COMP_ID | 0xFF, diff --git a/src/usr/sbeio/runtime/rt_sbeio.C b/src/usr/sbeio/runtime/rt_sbeio.C index a0737e788..3b653bfcb 100644 --- a/src/usr/sbeio/runtime/rt_sbeio.C +++ b/src/usr/sbeio/runtime/rt_sbeio.C @@ -27,33 +27,169 @@ #include <vmmconst.h> #include <sys/misc.h> +#include <sbeio/runtime/sbe_msg_passing.H> +#include <sbeio/sbeioreasoncodes.H> +#include <util/singleton.H> #include <errno.h> #include <errl/errlentry.H> #include <errl/errlmanager.H> +#include <errl/errlreasoncodes.H> // targeting support #include <targeting/common/target.H> #include <targeting/common/commontargeting.H> #include <targeting/common/utilFilter.H> -//#include <targeting/common/targetservice.H> -//#include <targeting/common/util.H> #include <runtime/rt_targeting.H> -// fapi support -//#include <isteps/hwpf_reasoncodes.H> - using namespace TARGETING; +using namespace ERRORLOG; +using namespace SBE_MSG; // Trace -extern trace_desc_t* g_fapiTd; // defined in rt_fapiPlatUtil.C +trace_desc_t* g_trac_sbeio; +TRAC_INIT(&g_trac_sbeio, SBEIO_COMP_NAME, 6*KILOBYTE, TRACE::BUFFER_SLOW); + namespace RT_SBEIO { + // Map of process command functions for the pass-through commands + ProcessCmdMap_t g_processCmdMap; + //------------------------------------------------------------------------ //------------------------------------------------------------------------ + int process_sbe_msg_cmd_processor(TargetHandle_t i_proc, + sbeMessage_t& i_request, + sbeMessage_t& o_response) + { + errlHndl_t errl = nullptr; + int rc = 0; + uint32_t l_command = i_request.cmdHdr.command; + + if(g_processCmdMap.find(l_command) == g_processCmdMap.end()) + { + TRACFCOMP(g_trac_sbeio, ERR_MRK"process_sbe_msg: process " + "command, function pointer not found for command 0x%08x", + l_command); + + rc = -201; + + /*@ + * @errortype + * @moduleid SBEIO::SBEIO_RUNTIME + * @reasoncode SBEIO::SBEIO_RT_FUNCTION_NOT_SET + * @userdata1[0:31] Processor HUID + * @userdata1[32:63] Request Command + * @userdata2 Sequence ID + * + * @devdesc SBEIO RT Process Pass-through command function not + * set. + * @custdesc Firmware error communicating with boot device + */ + errl = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, + SBEIO::SBEIO_RUNTIME, + SBEIO::SBEIO_RT_FUNCTION_NOT_SET, + TWO_UINT32_TO_UINT64( + get_huid(i_proc), + l_command), + i_request.sbeHdr.seqId); + + errl->addFFDC( SBE_COMP_ID, + &(i_request), + sizeof(sbeHeader_t) + sizeof(cmdHeader_t), + 0, // Version + ERRL_UDT_NOFORMAT, // parser ignores data + // ^^^ @TODO RTC:172362 + false ); // merge + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH); + errl->collectTrace(SBEIO_COMP_NAME); + errlCommit(errl, SBE_COMP_ID); + } + else + { + // Trace command to be processed + TRACFCOMP(g_trac_sbeio, "process_sbe_msg: process " + "command, process command 0x%08x with sequence ID 0x%08x", + l_command, + i_request.sbeHdr.seqId); + + // Call function to process command + errl = g_processCmdMap[l_command](i_proc, + i_request.cmdHdr.dataSize, + i_request.data, + &o_response.cmdHdr.status, + &o_response.cmdHdr.dataSize, + o_response.data); + + if(o_response.cmdHdr.dataSize > SBE_MSG_MAX_DATA) + { + TRACFCOMP(g_trac_sbeio, ERR_MRK"process_sbe_msg: process " + "command, response data size 0x%08x too large", + o_response.cmdHdr.dataSize); + + rc = -202; + + /*@ + * @errortype + * @moduleid SBEIO::SBEIO_RUNTIME + * @reasoncode SBEIO::SBEIO_RT_RSP_DATA_TOO_LARGE + * @userdata1[0:31] Processor HUID + * @userdata1[32:63] Request Command + * @userdata2[0:31] Sequence ID + * @userdata2[32:63] Response Data Size + * + * @devdesc SBEIO RT Process Pass-through command response + * data size too large. + * @custdesc Firmware error communicating with boot device + */ + errl = new ErrlEntry(ERRL_SEV_INFORMATIONAL, + SBEIO::SBEIO_RUNTIME, + SBEIO::SBEIO_RT_RSP_DATA_TOO_LARGE, + TWO_UINT32_TO_UINT64( + get_huid(i_proc), + l_command), + TWO_UINT32_TO_UINT64( + i_request.sbeHdr.seqId, + o_response.cmdHdr.dataSize)); + + errl->addFFDC( SBE_COMP_ID, + &(i_request), + sizeof(sbeHeader_t) + sizeof(cmdHeader_t), + 0, // Version + ERRL_UDT_NOFORMAT, // parser ignores data + // ^^^ @TODO RTC:172362 + false ); // merge + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH); + errl->collectTrace(SBEIO_COMP_NAME); + errlCommit(errl, SBE_COMP_ID); + + // Calculate message size for response using max data + o_response.sbeHdr.msgSize = sizeof(sbeHeader_t) + + sizeof(cmdHeader_t) + SBE_MSG_MAX_DATA; + } + else + { + // Calculate message size for response + o_response.sbeHdr.msgSize = sizeof(sbeHeader_t) + + sizeof(cmdHeader_t) + o_response.cmdHdr.dataSize; + } + + // Trace response to command that was processed + TRACFCOMP(g_trac_sbeio, "process_sbe_msg: process " + "command, response to command 0x%08x with sequence ID " + "0x%08x was status 0x%08x", + o_response.cmdHdr.command, + o_response.sbeHdr.seqId, + o_response.cmdHdr.status); + } + + return rc; + } + //------------------------------------------------------------------------ //------------------------------------------------------------------------ @@ -61,34 +197,95 @@ namespace RT_SBEIO int process_sbe_msg(uint32_t i_procChipId) { int rc = 0; - errlHndl_t err = nullptr; + errlHndl_t errl = nullptr; + + // Used to store a local copy of the Pass-through command and preserve + // it during processing (response overlays SBE Communication buffer) + sbeMessage_t l_request; - // Convert chipId to HB target - TargetHandle_t l_proc = nullptr; - err = RT_TARG::getHbTarget(i_procChipId, l_proc); - if(err) + do { - rc = err->reasonCode(); - if (0 == rc) + // Convert chipId to HB target + TargetHandle_t l_proc = nullptr; + errl = RT_TARG::getHbTarget(i_procChipId, l_proc); + if(errl) { - // If there was a failure, be sure to return non-zero status - rc = -1; + rc = errl->reasonCode(); + if (0 == rc) + { + // If there was a failure, be sure to return non-zero status + rc = -1; + } + + TRACFCOMP(g_trac_sbeio, ERR_MRK"process_sbe_msg: getHbTarget " + "returned rc=0x%04X for procChipId: %llx", + rc, i_procChipId); + + errlCommit (errl, SBE_COMP_ID); + + break; } - TRACFCOMP(g_fapiTd, ERR_MRK"process_sbe_msg: getHbTarget " - "returned rc=0x%04X for procChipId: %llx", - rc, i_procChipId); + // Get SBE Communication Buffer for target processor + uint64_t l_sbeCommAddr = + l_proc->getAttr<TARGETING::ATTR_SBE_COMM_ADDR>(); - errlCommit (err, SBE_COMP_ID); - } + // Make sure SBE Communication Buffer is set + if(l_sbeCommAddr == NULL) + { + TRACFCOMP(g_trac_sbeio, ERR_MRK"process_sbe_msg: getAttr " + "did not get SBE Communication buffer address"); + + rc = -2; - /* TODO RTC 170760 process SBE message read command */ + /*@ + * @errortype + * @moduleid SBEIO::SBEIO_RUNTIME + * @reasoncode SBEIO::SBEIO_RT_NO_SBE_COMM_BUFFER + * @userdata1 Processor HUID + * @userdata2 Reserved + * + * @devdesc SBEIO RT Process Pass-through command SBE + * Communication buffer not set. + * @custdesc Firmware error communicating with boot device + */ + errl = new ErrlEntry(ERRL_SEV_INFORMATIONAL, + SBEIO::SBEIO_RUNTIME, + SBEIO::SBEIO_RT_NO_SBE_COMM_BUFFER, + get_huid(l_proc), + 0); - /* TODO RTC 170761 call appropriate command processor */ + errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE, + HWAS::SRCI_PRIORITY_HIGH); + errl->collectTrace(SBEIO_COMP_NAME); + errlCommit(errl, SBE_COMP_ID); + + break; + } - /* TODO RTC 170762 process SBE message write response */ + // Provide access to SBE Communication Buffer as an SBE Message + sbeMessage_t *l_sbeMessage = + reinterpret_cast<sbeMessage_t*>(l_sbeCommAddr); - /* TODO RTC 170763 assert CFAM register ??? */ + /* TODO RTC 170760 process SBE message read command */ + TRACFCOMP(g_trac_sbeio, "process_sbe_msg: read command"); + + // Call appropriate command processor + TRACFCOMP(g_trac_sbeio, "process_sbe_msg: call command processor"); + rc = process_sbe_msg_cmd_processor(l_proc, + l_request, + *l_sbeMessage); + if(rc != 0) + { + break; + } + + /* TODO RTC 170762 process SBE message write response */ + TRACFCOMP(g_trac_sbeio, "process_sbe_msg: write response"); + + /* TODO RTC 170763 assert CFAM register ??? */ + TRACFCOMP(g_trac_sbeio, "process_sbe_msg: assert CFAM register"); + } while(0); return rc; } @@ -115,34 +312,38 @@ namespace RT_SBEIO g_hostInterfaces->get_reserved_mem("ibm,sbe-comm", l_instance); l_procChip->setAttr<ATTR_SBE_COMM_ADDR>(l_sbeCommAddr); - - /* - * TODO RTC 170758 - * - * call performPsuChipOp to tell SBE where to write when SBE is ready - * - * psuCommand l_psuCommand( - * SBE_REQUIRE_RESPONSE, - * SBE_PSU_GENERIC_MESSAGE, - * SBE_CMD_CONTROL_SYSTEM_CONFIG); - * - * psuResponse l_psuResponse; - * - * // Create FFDCPackage struct in psuCommand union - * uint64_t cd4_FFDCPackage_MbxReg2reserved = &iv_ffdcPackageBuffer; - * - * performPsuChipOp(l_procChip, - * &l_psuCommand, - * &l_psuResponse, - * MAX_PSU_SHORT_TIMEOUT_NS, - * SBE_SYSTEM_CONFIG_REQ_USED_REGS, - * SBE_SYSTEM_CONFIG_RSP_USED_REGS); - * - */ } } }; registerSbeio g_registerSbeio; -} +} // namespace RT_SBEIO + +namespace SBE_MSG +{ + // Set an entry in list of process command functions + int setProcessCmdFunction(enum passThruCmds i_command, + processCmdFunction_t i_function) + { + int rc = 0; + + do + { + RT_SBEIO::g_processCmdMap[i_command] = i_function; + + if(RT_SBEIO::g_processCmdMap[i_command] != i_function) + { + TRACFCOMP(g_trac_sbeio, ERR_MRK"setProcessCmdFunction: " + "process command function not set for command 0x%08x", + i_command); + + rc = -1; + + break; + } + } while(0); + + return rc; + } +} // namespace SBE_MSG diff --git a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml index 9dc9ae5f5..f43b34688 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types_hb.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types_hb.xml @@ -486,7 +486,7 @@ <attribute> <id>SBE_FFDC_ADDR</id> <description> - Physical address where SBE FFDC is placed in mainstore. + Virtual address where SBE FFDC is placed in mainstore. </description> <simpleType> <uint64_t></uint64_t> @@ -500,7 +500,7 @@ <attribute> <id>SBE_COMM_ADDR</id> <description> - Physical address where SBE Communications are placed in mainstore. + Virtual address where SBE Communications are placed in mainstore. This area is used for SBE message passing and may contain an SBE command or the response to it from HBRT. </description> |

