summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/occ/occ_common.C
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hwpf/hwp/occ/occ_common.C')
-rw-r--r--src/usr/hwpf/hwp/occ/occ_common.C258
1 files changed, 237 insertions, 21 deletions
diff --git a/src/usr/hwpf/hwp/occ/occ_common.C b/src/usr/hwpf/hwp/occ/occ_common.C
index 983d84ea3..96ef4d7f3 100644
--- a/src/usr/hwpf/hwp/occ/occ_common.C
+++ b/src/usr/hwpf/hwp/occ/occ_common.C
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <occ/occ_common.H>
+#include <occ/occAccess.H>
#include <initservice/taskargs.H>
#include <errl/errlentry.H>
@@ -121,8 +122,101 @@ namespace HBOCC
return l_errl;
}
+#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
+ errlHndl_t loadOCCImageDuringIpl( TARGETING::Target* i_target,
+ void* i_occVirtAddr)
+ {
+ TRACUCOMP( g_fapiTd,
+ ENTER_MRK"loadOCCImageDuringIpl(%p)",
+ i_occVirtAddr);
+
+ errlHndl_t l_errl = NULL;
+ size_t lidSize = 0;
+ do {
+ UtilLidMgr lidMgr(HBOCC::OCC_LIDID);
+
+ l_errl = lidMgr.getLidSize(lidSize);
+ if(l_errl)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadOCCImageDuringIpl: Error getting lid size. lidId=0x%.8x",
+ OCC_LIDID);
+ break;
+ }
+
+ // get the full OCC LID and then copy them.
+ l_errl = lidMgr.getLid(i_occVirtAddr, lidSize);
+ if(l_errl)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadOCCImageDuringIpl: Error getting lid. lidId=0x%.8x",
+ OCC_LIDID);
+ break;
+ }
+
+ // OCC Boot Image is now at the start of that L3 region.
+ size_t l_length = 0; // length of this section
+ size_t l_startOffset = 0; // offset to start of the section
+ size_t l_offsetToLength = 0x48; // offset to length of the section
+
+ char *l_tmpStart = reinterpret_cast<char *>(i_occVirtAddr) +
+ l_startOffset;
+ uint32_t *ptrToLength = (uint32_t *)(l_tmpStart + l_offsetToLength);
+ l_length = *ptrToLength;
+
+ // OCC Main Application
+ l_startOffset = l_length; // after the Boot image
+ l_tmpStart = reinterpret_cast<char *>(i_occVirtAddr) +
+ l_startOffset;
+ ptrToLength = (uint32_t *)(l_tmpStart + l_offsetToLength);
+ l_length = *ptrToLength;
+
+ // write the IPL flag and the nest FREQ for OCC.
+ // IPL_FLAG is a two byte field. OR a 1 into these two bytes.
+ // FREQ is the 4 byte nest frequency value that goes into
+ // the same field in the HOMER.
+ TARGETING::TargetService & tS = TARGETING::targetService();
+ TARGETING::Target * sysTarget = NULL;
+ tS.getTopLevelTarget( sysTarget );
+ assert( sysTarget != NULL );
+
+ uint16_t *ptrToIplFlag =
+ (uint16_t *)((char *)l_tmpStart + OCC_OFFSET_IPL_FLAG);
+ uint32_t *ptrToFreq =
+ (uint32_t *)((char *)l_tmpStart + OCC_OFFSET_FREQ);
+ *ptrToIplFlag |= 0x0001;
+ *ptrToFreq = sysTarget->getAttr<ATTR_FREQ_PB>();
+
+ ecmdDataBufferBase l_occAppData(l_length * 8 /* bits */);
+ uint32_t rc = l_occAppData.insert((uint32_t *)l_tmpStart, 0,
+ l_length * 8 /* bits */);
+ if (rc)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadOCCImageDuringIpl: Error %d doing insert",
+ rc);
+ // create l_errl
+ break;
+ }
+ const uint32_t l_SramAddrApp = OCC_SRAM_ADDRESS;
+ l_errl = HBOCC::writeSRAM(i_target, l_SramAddrApp, l_occAppData);
+ if(l_errl)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadOCCImageDuringIpl: Error in writeSRAM of app");
+ break;
+ }
+
+ }while(0);
+
+ TRACUCOMP( g_fapiTd,
+ EXIT_MRK"loadOCCImageDuringIpl");
+ return l_errl;
+ }
+#endif
+
/**
- * @brief Sets up OCC Host data
+ * @brief Sets up OCC Host data in Homer
*/
errlHndl_t loadHostDataToHomer( TARGETING::Target* i_proc,
void* i_occHostDataVirtAddr)
@@ -192,27 +286,124 @@ namespace HBOCC
EXIT_MRK"loadHostDataToHomer");
return l_errl;
- }
+ } // loadHostDataToHomer
+
+#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
+#ifndef __HOSTBOOT_RUNTIME
+ /**
+ * @brief Sets up OCC Host data in SRAM
+ */
+ errlHndl_t loadHostDataToSRAM( TARGETING::Target* i_proc,
+ const PRDF::HwInitialized_t i_curHw)
+ {
+ TRACUCOMP( g_fapiTd,
+ ENTER_MRK"loadHostDataToSRAM i_curHw=%d",i_curHw);
+
+ errlHndl_t l_errl = NULL;
+
+ //Treat virtual address as starting pointer
+ //for config struct
+ HBOCC::occHostConfigDataArea_t * config_data =
+ new HBOCC::occHostConfigDataArea_t();
+
+ // Get top level system target
+ TARGETING::TargetService & tS = TARGETING::targetService();
+ TARGETING::Target * sysTarget = NULL;
+ tS.getTopLevelTarget( sysTarget );
+ assert( sysTarget != NULL );
+
+ uint32_t nestFreq = sysTarget->getAttr<ATTR_FREQ_PB>();
+
+ config_data->version = HBOCC::OccHostDataVersion;
+ config_data->nestFrequency = nestFreq;
+
+ // Figure out the interrupt type
+ if( INITSERVICE::spBaseServicesEnabled() )
+ {
+ config_data->interruptType = USE_FSI2HOST_MAILBOX;
+ }
+ else
+ {
+ config_data->interruptType = USE_PSIHB_COMPLEX;
+ }
+
+ config_data->firMaster = IS_FIR_MASTER;
+ l_errl = PRDF::writeHomerFirData( config_data->firdataConfig,
+ sizeof(config_data->firdataConfig),
+ i_curHw);
+ if (l_errl)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadHostDataToSRAM: Error in writeHomerFirData");
+ }
+ else
+ {
+ const uint32_t l_SramAddrFir = OCC_SRAM_FIR_DATA;
+ ecmdDataBufferBase l_occFirData(OCC_SRAM_FIR_LENGTH * 8 /* bits */);
+ /// copy config_data in here
+ uint32_t rc = l_occFirData.insert((uint32_t *)config_data, 0,
+ sizeof(*config_data) * 8 /* bits */);
+ if (rc)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadHostDataToSRAM: Error %d doing insert",
+ rc);
+ /*@
+ * @errortype
+ * @moduleid fapi::MOD_OCC_LOAD_HOST_DATA_TO_SRAM
+ * @reasoncode fapi::RC_ECMD_INSERT_FAILED
+ * @userdata1 Return Code
+ * @userdata2 0
+ * @devdesc ecmd insert failed for l_occFirData
+ * @custdesc A problem occurred during the IPL
+ * of the system.
+ */
+ l_errl = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ fapi::MOD_OCC_LOAD_HOST_DATA_TO_SRAM,
+ fapi::RC_ECMD_INSERT_FAILED,
+ rc, 0);
+ }
+ else
+ {
+ l_errl = HBOCC::writeSRAM(i_proc, l_SramAddrFir, l_occFirData);
+ if(l_errl)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadHostDataToSRAM: Error in writeSRAM");
+ }
+ }
+ }
+
+ TRACUCOMP( g_fapiTd,
+ EXIT_MRK"loadHostDataToSRAM");
+
+ return l_errl;
+ } // loadHostDataToSRAM
+#endif
+#endif
errlHndl_t loadOCC(TARGETING::Target* i_target,
uint64_t i_occImgPaddr,
- uint64_t i_occImgVaddr,
- uint64_t i_commonPhysAddr)
+ uint64_t i_occImgVaddr, // dest
+ uint64_t i_commonPhysAddr,
+ bool i_useSRAM)
{
errlHndl_t l_errl = NULL;
+
TRACFCOMP( g_fapiTd,
- ENTER_MRK"loadOCC" );
+ ENTER_MRK"loadOCC(0x%08X, 0x%08X, 0x%08X, %d)",
+ i_occImgPaddr, i_occImgVaddr, i_commonPhysAddr,
+ i_useSRAM);
do{
// Remember where we put things
- if( i_target )
- {
- // Subtract HOMER_OFFSET_TO_OCC_IMG to be technically
- // correct though HOMER_OFFSET_TO_OCC_IMG happens to be zero
- i_target->setAttr<ATTR_HOMER_PHYS_ADDR>
- (i_occImgPaddr - HOMER_OFFSET_TO_OCC_IMG);
- i_target->setAttr<ATTR_HOMER_VIRT_ADDR>
- (i_occImgVaddr - HOMER_OFFSET_TO_OCC_IMG);
- }
+ // Subtract HOMER_OFFSET_TO_OCC_IMG to be technically
+ // correct though HOMER_OFFSET_TO_OCC_IMG happens to be zero
+ i_target->setAttr<ATTR_HOMER_PHYS_ADDR>
+ (i_occImgPaddr - HOMER_OFFSET_TO_OCC_IMG);
+ i_target->setAttr<ATTR_HOMER_VIRT_ADDR>
+ (i_occImgVaddr - HOMER_OFFSET_TO_OCC_IMG);
+
// cast OUR type of target to a FAPI type of target.
const fapi::Target l_fapiTarg(fapi::TARGET_TYPE_PROC_CHIP,
(const_cast<Target*>(i_target)));
@@ -242,7 +433,6 @@ namespace HBOCC
ERR_MRK"loadOCC: Bar0 config failed!" );
l_errl->collectTrace(FAPI_TRACE_NAME,256);
l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256);
-
break;
}
@@ -264,7 +454,6 @@ namespace HBOCC
ERR_MRK"loadOCC: Bar1 config failed!" );
l_errl->collectTrace(FAPI_TRACE_NAME,256);
l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256);
-
break;
}
@@ -286,34 +475,60 @@ namespace HBOCC
VMM_OCC_COMMON_SIZE_IN_MB,
PBA_CMD_SCOPE_NODAL );
- if ( l_errl != NULL )
+ if ( l_errl )
{
TRACFCOMP( g_fapiImpTd,
ERR_MRK"loadOCC: Bar3 config failed!" );
l_errl->collectTrace(FAPI_TRACE_NAME,256);
l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256);
-
break;
}
+#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
+ if (i_useSRAM)
+ {
+ void* occVirt = reinterpret_cast<void *>(i_occImgVaddr);
+ l_errl = loadOCCImageDuringIpl( i_target, occVirt );
+ if( l_errl )
+ {
+ TRACFCOMP(g_fapiImpTd,
+ ERR_MRK"loadOCC: loadOCCImageDuringIpl failed!");
+ break;
+ }
+ }
+ else
+#endif
+ {
//==============================
//Load the OCC HOMER image
//==============================
+
+#ifdef CONFIG_ENABLE_CHECKSTOP_ANALYSIS
+ // clear (up to and including) the IPL Flag
+ const uint32_t l_SramAddrApp = OCC_SRAM_ADDRESS;
+ ecmdDataBufferBase l_occAppData((OCC_OFFSET_IPL_FLAG + 6) * 8 /* bits */);
+ l_errl = HBOCC::writeSRAM(i_target, l_SramAddrApp, l_occAppData);
+ if(l_errl)
+ {
+ TRACFCOMP( g_fapiImpTd,
+ ERR_MRK"loadOCC: Error in writeSRAM of 0");
+ break;
+ }
+#endif
void* occVirt = reinterpret_cast<void *>(i_occImgVaddr);
l_errl = loadOCCImageToHomer( occVirt );
- if( l_errl != NULL )
+ if( l_errl )
{
TRACFCOMP(g_fapiImpTd,
ERR_MRK"loadOCC: loadOCCImageToHomer failed!");
break;
}
+ }
}while(0);
TRACFCOMP( g_fapiTd,
EXIT_MRK"loadOCC");
-
return l_errl;
-
}
/**
@@ -434,6 +649,7 @@ namespace HBOCC
EXIT_MRK"startOCC");
return l_errl;
}
+
/**
* @brief Stop OCC for specified DCM pair of processors.
* If 2nd input is NULL, OCC will be setup on just
OpenPOWER on IntegriCloud