summaryrefslogtreecommitdiffstats
path: root/src/sbefw
diff options
context:
space:
mode:
authorRaja Das <rajadas2@in.ibm.com>2018-05-25 00:14:45 -0500
committerSachin Gupta <sgupta2m@in.ibm.com>2018-08-14 08:49:11 -0500
commit4a2a88ff80811d061f55b7c7758781cc84edbc04 (patch)
tree9763563a86f6365e8fc3221ede09543ff7672063 /src/sbefw
parent3163363f9b24de944cf1450436e6d676de407aba (diff)
downloadtalos-sbe-4a2a88ff80811d061f55b7c7758781cc84edbc04.tar.gz
talos-sbe-4a2a88ff80811d061f55b7c7758781cc84edbc04.zip
[SBE-ARCH2] Format register dump and SBE Capturing the Data
1. Format of the register dump by SBE on the Host Memory (Interface) 2. SBE Capturing the architected state for all cores/threads and dumping it out in the hostboot reserved area. Change-Id: I80be7e3fa18679aa29aa2cda92eebbf85ce02fca Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/59372 Reviewed-by: Shakeeb A. Pasha B K <shakeebbk@in.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Diffstat (limited to 'src/sbefw')
-rw-r--r--src/sbefw/app/power/apppowerfiles.mk1
-rw-r--r--src/sbefw/app/power/sbearchregdump.C270
-rw-r--r--src/sbefw/app/power/sbearchregdump.H44
-rw-r--r--src/sbefw/core/sbeHostMsg.H21
-rw-r--r--src/sbefw/core/sbe_sp_intf.H1
-rw-r--r--src/sbefw/core/sbes0handler.C10
6 files changed, 347 insertions, 0 deletions
diff --git a/src/sbefw/app/power/apppowerfiles.mk b/src/sbefw/app/power/apppowerfiles.mk
index 42a967ea..ba4814ef 100644
--- a/src/sbefw/app/power/apppowerfiles.mk
+++ b/src/sbefw/app/power/apppowerfiles.mk
@@ -46,6 +46,7 @@ APPPOWERSEEPROM-CPP-SOURCES += sbecmdmpipl.C
APPPOWERSEEPROM-CPP-SOURCES += sbecmdfastarray.C
APPPOWERSEEPROM-CPP-SOURCES += sbecmdgeneric.C
APPPOWERSEEPROM-CPP-SOURCES += sbecmdtracearray.C
+APPPOWERSEEPROM-CPP-SOURCES += sbearchregdump.C
APPPOWERSEEPROM-C-SOURCES =
APPPOWERSEEPROM-S-SOURCES =
diff --git a/src/sbefw/app/power/sbearchregdump.C b/src/sbefw/app/power/sbearchregdump.C
new file mode 100644
index 00000000..ef33556e
--- /dev/null
+++ b/src/sbefw/app/power/sbearchregdump.C
@@ -0,0 +1,270 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/app/power/sbearchregdump.C $ */
+/* */
+/* OpenPOWER sbe 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 */
+
+#include "sbefifo.H"
+#include "sbeSpMsg.H"
+#include "sbe_sp_intf.H"
+#include "sbeHostMsg.H"
+#include "sbetrace.H"
+#include "sbeFifoMsgUtils.H"
+#include "sbecmdmpipl.H"
+#include "sberegaccess.H"
+#include "sbefapiutil.H"
+#include "sbearchregdump.H"
+#include "sbeglobals.H"
+#include "p9_query_core_access_state.H"
+#include "p9_ram_core.H"
+#include "sbeMemAccessInterface.H"
+#include "sbecmdcntlinst.H"
+#include "p9_thread_control.H"
+#include "p9_perv_scom_addresses.H"
+
+#include "fapi2.H"
+
+using namespace fapi2;
+
+p9_query_core_access_state_FP_t p9_query_core_access_state_hwp = &p9_query_core_access_state;
+#define SPR_LIST_SIZE 63
+#define GPR_LIST_SIZE 32
+// This is defined in Hostboot src/include/usr/sbeio/sbeioif.H, this is just a
+// copy, so that SBE refers to the same count.
+#define STASH_KEY_CNT_FOR_ARCH_DUMP_ADDR 0x4
+
+///////////////////////////////////////////////////////////////////////
+// @brief sbeFetchRegDumpAddrFromStash
+//
+///////////////////////////////////////////////////////////////////////
+uint64_t sbeFetchRegDumpAddrFromStash(void)
+{
+ #define SBE_FUNC " sbeFetchRegDumpAddrFromStash "
+ SBE_ENTER(SBE_FUNC);
+ uint64_t addr = 0;
+ for(uint8_t cnt=0; cnt<MAX_ROW_COUNT; cnt++)
+ {
+ if(SBE_GLOBAL->sbeKeyAddrPair.keyValuePairfromHost.key[cnt] ==
+ STASH_KEY_CNT_FOR_ARCH_DUMP_ADDR)
+ {
+ addr = SBE_GLOBAL->sbeKeyAddrPair.keyValuePairfromHost.addr[cnt];
+ break;
+ }
+ }
+ SBE_EXIT(SBE_FUNC);
+ return addr;
+ #undef SBE_FUNC
+}
+///////////////////////////////////////////////////////////////////////
+// @brief sbeDumpArchRegs Dump out the architected registers
+//
+///////////////////////////////////////////////////////////////////////
+ReturnCode sbeDumpArchRegs()
+{
+ #define SBE_FUNC " sbeDumpArchRegs "
+ SBE_ENTER(SBE_FUNC);
+ ReturnCode fapiRc = FAPI2_RC_SUCCESS;
+ uint64_t dumpAddr = 0;
+ sbeArchRegDumpFormat_t dump = {};
+ sbe_pir_t pir = {};
+
+ // Combined list of SPRs GPRs
+ static const uint16_t SPR_GPR_list[] = {
+ // List for SPRs to be collected in MPIPL path
+ 2001,2000, 2002, 8, 9, 815, 28, 1, 26, 27, 19, 18,
+ 314, 315, 307, 306, 152, 48, 144, 272, 273, 274, 275, 304,
+ 305, 153, 190, 176, 29, 349, 157, 128, 129, 130, 268, 849,
+ 22, 310, 309, 308, 317, 885, 336, 337, 313, 318, 319, 464,
+ 25, 180, 188, 17, 339, 1008, 338, 884, 921, 922, 256, 813,
+ 814, 186, 855,
+ // List for GPRs to be collected in MPIPL path
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+ };
+
+ do
+ {
+ Target<TARGET_TYPE_PROC_CHIP > procTgt = plat_getChipTarget();
+ dumpAddr = sbeFetchRegDumpAddrFromStash();
+ if(dumpAddr == 0xFFFFFFFFFFFFFFFFULL || dumpAddr == 0)
+ {
+ // Return failure
+ SBE_ERROR(SBE_FUNC "Invalid Dump address from Stash [0x%08X %08X]",
+ SBE::higher32BWord(dumpAddr), SBE::lower32BWord(dumpAddr));
+ break;
+ }
+ SBE_INFO(SBE_FUNC "Stash Dump Addr = [0x%08X %08X] ",
+ SBE::higher32BWord(dumpAddr), SBE::lower32BWord(dumpAddr));
+
+ // Initialise the PBA with the above address from stash,
+ // The access API would use it in auto-increment mode.
+ p9_PBA_oper_flag pbaFlag;
+ pbaFlag.setOperationType(p9_PBA_oper_flag::INJ);
+ sbeMemAccessInterface PBAInterface(
+ SBE_MEM_ACCESS_PBA,
+ dumpAddr,
+ &pbaFlag,
+ SBE_MEM_ACCESS_WRITE,
+ sbeMemAccessInterface::PBA_GRAN_SIZE_BYTES);
+
+ // Go for each core under this Proc
+ for(auto &coreTgt : procTgt.getChildren<fapi2::TARGET_TYPE_CORE>())
+ {
+ bool isScanEn = false;
+ bool isScomEn = false;
+ uint8_t chipUnitNum = 0;
+ uint8_t procGrpId = 0;
+ uint8_t procChipId = 0;
+ // Required for PIR calculation
+ FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, coreTgt, chipUnitNum);
+ FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_GROUP_ID, procTgt, procGrpId);
+ FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_CHIP_ID, procTgt, procChipId);
+
+ // Check for Scommable states for each core
+ SBE_EXEC_HWP(fapiRc, p9_query_core_access_state_hwp, coreTgt,
+ isScomEn, isScanEn)
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "p9_query_core_access_state failed, "
+ "For Proc [0x%02X ]Core [0x%02X]", procChipId, chipUnitNum);
+ // We should be able to get the scom states true/false, if not
+ // there is an issue please return.
+ continue;
+ }
+ // If core not scommable, simply skip entry for the same in the
+ // reserved space. Hostboot will be able to identify this basis PIR
+ if(isScomEn) //true
+ {
+ // Fetch the core state
+ uint8_t coreState = 0;
+ fapi2::buffer<uint64_t> ppm_ssh_buf = 0;
+ fapiRc = getscom_abs_wrap (&coreTgt, C_PPM_SSHSRC, &ppm_ssh_buf());
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC "Failed to read SSH");
+ continue;
+ }
+ ppm_ssh_buf.extractToRight<uint8_t>(coreState, 8, 4);
+
+ for(uint8_t thread = SMT4_THREAD0; thread < SMT4_THREAD_MAX; thread++)
+ {
+ RamCore ramCore( coreTgt, thread );
+ SBE_EXEC_HWP_NOARG(fapiRc, ramCore.ram_setup)
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_setup failed. threadNr:0x%2X "
+ "coreChipletId:0x%02X Proc:0x%02X",
+ thread, chipUnitNum, procChipId);
+ // Skip this thread since ram setup failed, try to get
+ // data for the Next Thread, but what about this fapiRc
+ continue;
+ }
+ // If setup passes, then go for get_reg()
+ Enum_RegType type = REG_SPR;
+ // Construct PIR for the thread
+ pir.procGrpId = procGrpId;
+ pir.procChipId = procChipId;
+ pir.chipUnitNum = chipUnitNum;
+ pir.thread = thread;
+
+ // Loop over the combined list of registers
+ for( uint32_t regIdx=0; regIdx<(sizeof(SPR_GPR_list)/sizeof(uint16_t)); regIdx++ )
+ {
+ // Switch to GPRs once SPRs are over in the list
+ if(regIdx >= SPR_LIST_SIZE)
+ {
+ type = REG_GPR;
+ }
+ // Start filling up the rest of data structure
+ dump.pir = pir;
+ dump.coreState = coreState;
+ dump.regNum = SPR_GPR_list[regIdx];
+
+ fapi2::buffer<uint64_t> data64;
+ SBE_EXEC_HWP(fapiRc, ramCore.get_reg, type,
+ SPR_GPR_list[regIdx], &data64, true)
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" get_reg failed. threadNr:0x%x "
+ "coreChipletId:0x%02x, regNr:%u regType:%u ",
+ thread, chipUnitNum, SPR_GPR_list[regIdx], type);
+ // If get_reg fails, we need to indicate hostboot
+ // that data fetch failed, use this signature
+ dump.regVal = 0xDEADBEEFDEADBEEFULL;
+ }
+ else
+ {
+ dump.regVal = data64;
+ }
+ // PBA it to the stash address
+ fapiRc = PBAInterface.accessWithBuffer(
+ &dump,
+ sizeof(dump),
+ false);
+ if(fapiRc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "failed in writing to hostboot");
+ break;
+ }
+ }
+ if(fapiRc)
+ {
+ break;
+ }
+ // HWP team does not care about cleanup for failure case.i
+ // So call cleaup only for success case.
+ // Clean up the ram core setup
+ SBE_EXEC_HWP_NOARG(fapiRc, ramCore.ram_cleanup)
+ if( fapiRc != FAPI2_RC_SUCCESS )
+ {
+ SBE_ERROR(SBE_FUNC" ram_cleanup failed. threadNr:0x%02X"
+ " coreChipletId:0x%02X", thread, chipUnitNum);
+ // Don't break, continue for the next thread
+ }
+ }
+ if(fapiRc)
+ {
+ break;
+ }
+ }
+ else
+ {
+ SBE_ERROR(SBE_FUNC "sbeDumpArchRegs - Core[%d] Not Scommable ",
+ chipUnitNum);
+ }
+ }
+ // Just see that we are pushing the last PBA Frame here so as to flush
+ // anything which is stuck before of a non-aligned frame.
+ sbeArchRegDumpFormat_t dump_dummy = {};
+ fapiRc = PBAInterface.accessWithBuffer(&dump_dummy, sizeof(dump_dummy), true);
+ if(fapiRc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ SBE_ERROR(SBE_FUNC "failed to write the last frame to hostboot");
+ break;
+ }
+ }while(0);
+
+ SBE_EXIT(SBE_FUNC);
+ return fapiRc;
+ #undef SBE_FUNC
+}
+
diff --git a/src/sbefw/app/power/sbearchregdump.H b/src/sbefw/app/power/sbearchregdump.H
new file mode 100644
index 00000000..d83eb738
--- /dev/null
+++ b/src/sbefw/app/power/sbearchregdump.H
@@ -0,0 +1,44 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/sbefw/app/power/sbearchregdump.H $ */
+/* */
+/* OpenPOWER sbe 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 __SBEFW_ARCHREGDUMP_H
+#define __SBEFW_ARCHREGDUMP_H
+
+#include <stdint.h>
+#include "fapi2.H"
+
+/**
+ * @brief This function dumps all the SPRs/GPRs associated with proc's core
+ * in a location provided by Hostboot's stash addr. Internally this method
+ * takes care if ramming is possible for a core-thread for spr/gpr read and
+ * dump the same in the format agreed via PBA
+ *
+ * @param[in] void
+ *
+ * @return FAPI2_RC_SUCCESS if success, else error code
+ */
+fapi2::ReturnCode sbeDumpArchRegs(void);
+
+#endif /* __SBEFW_ARCHREGDUMP_H */
diff --git a/src/sbefw/core/sbeHostMsg.H b/src/sbefw/core/sbeHostMsg.H
index 280dc693..4978417b 100644
--- a/src/sbefw/core/sbeHostMsg.H
+++ b/src/sbefw/core/sbeHostMsg.H
@@ -186,4 +186,25 @@ typedef struct
void init();
} sbeSbe2PsuRespHdr_t;
+/* @brief Format of PIR */
+typedef struct
+{
+ uint32_t procGrpId:21;
+ uint32_t procChipId:3;
+ uint32_t chipUnitNum:6;
+ uint32_t thread:2;
+} sbe_pir_t;
+
+/* @brief Format to dump out the architected register on the host memory
+ * Host may use this format to fetch all the register data/state
+ */
+typedef struct
+{
+ sbe_pir_t pir; // PIR value of thread corrsponding to the register
+ uint32_t coreState:8; // State of core in which this thread is present
+ uint32_t reserved:8; // Reserved
+ uint32_t regNum:16; // Register Number
+ uint64_t regVal; // Register Value
+} sbeArchRegDumpFormat_t;
+
#endif // __SBEFW_SBEHOST_MSG_H
diff --git a/src/sbefw/core/sbe_sp_intf.H b/src/sbefw/core/sbe_sp_intf.H
index f9ecd1aa..f238a80a 100644
--- a/src/sbefw/core/sbe_sp_intf.H
+++ b/src/sbefw/core/sbe_sp_intf.H
@@ -228,6 +228,7 @@ enum sbeSecondaryResponse
SBE_SEC_PERIODIC_IO_TOGGLE_FAILED = 0x27,
SBE_SEC_SPECIAL_WAKEUP_TIMEOUT = 0x28,
SBE_SEC_SPECIAL_WAKEUP_SCOM_FAILURE = 0x29,
+ SBE_SEC_S0_ARCH_REG_DUMP_FAILED = 0x2A,
};
/**
diff --git a/src/sbefw/core/sbes0handler.C b/src/sbefw/core/sbes0handler.C
index dd16e777..06507eb7 100644
--- a/src/sbefw/core/sbes0handler.C
+++ b/src/sbefw/core/sbes0handler.C
@@ -40,6 +40,7 @@
#include "sbecmdmpipl.H"
#include "sbeFFDC.H"
#include "sbes0handler.H"
+#include "sbearchregdump.H"
#include "fapi2.H"
#include "p9_perv_scom_addresses.H"
@@ -70,6 +71,15 @@ uint32_t sbeHandleS0(uint8_t *i_pArg)
break;
}
+ // Collect Architected Register Dump
+ fapiRc = sbeDumpArchRegs();
+ if(fapiRc != FAPI2_RC_SUCCESS)
+ {
+ rc = SBE_SEC_S0_ARCH_REG_DUMP_FAILED;
+ SBE_ERROR(SBE_FUNC "Failed to collect ArchRegDump S0 Interface");
+ break;
+ }
+
// TODO - RTC: 190585
//Core and Cache stop Clock
fapiRc = stopClockS0();
OpenPOWER on IntegriCloud