Skip to content

Commit

Permalink
[SBE-ARCH2] Format register dump and SBE Capturing the Data
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Raja Das authored and sgupta2m committed Aug 14, 2018
1 parent 3163363 commit 4a2a88f
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/sbefw/app/power/apppowerfiles.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
270 changes: 270 additions & 0 deletions src/sbefw/app/power/sbearchregdump.C
Original file line number Diff line number Diff line change
@@ -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
}

44 changes: 44 additions & 0 deletions src/sbefw/app/power/sbearchregdump.H
Original file line number Diff line number Diff line change
@@ -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 */
21 changes: 21 additions & 0 deletions src/sbefw/core/sbeHostMsg.H
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions src/sbefw/core/sbe_sp_intf.H
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};

/**
Expand Down
10 changes: 10 additions & 0 deletions src/sbefw/core/sbes0handler.C
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 4a2a88f

Please sign in to comment.