/* * @file: ppe/sbe/sbefw/sbecmdiplcontrol.C * * @brief This file contains the SBE istep chipOps * */ #include "sbecmdiplcontrol.H" #include "sbefifo.H" #include "sbetrace.H" #include "sbe_sp_intf.H" #include "sbeFifoMsgUtils.H" #include "assert.h" #include "fapi2.H" // Pervasive HWP Header Files ( istep 2) #include #include #include #include #include #include #include #include #include #include #include // Pervasive HWP Header Files ( istep 3) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Cache HWP header file #include "p9_hcd_cache.H" // Core HWP header file #include "p9_hcd_core.H" // Forward declaration using namespace fapi2; ReturnCode sbeExecuteIstep (uint8_t i_major, uint8_t i_minor); bool validateIstep (uint8_t i_major, uint8_t i_minor); //typedefs typedef ReturnCode (*sbeIstepHwp_t) (const Target & i_target); // Wrapper function for HWP IPl functions typedef ReturnCode (*sbeIstep_t)( sbeIstepHwp_t ); // Wrapper function which will call HWP with Proc target. ReturnCode istepWithProc( sbeIstepHwp_t i_hwp ); ReturnCode istepNoOp( sbeIstepHwp_t i_hwp ); ReturnCode istepWithEx( sbeIstepHwp_t i_hwp); ReturnCode istepWithEq( sbeIstepHwp_t i_hwp); ReturnCode istepWithCore( sbeIstepHwp_t i_hwp); //structure for mapping SBE wrapper and HWP functions typedef struct { sbeIstep_t istepWrapper; sbeIstepHwp_t istepHwp; }istepMap_t; // Major isteps which are supported typedef enum { SBE_ISTEP2 = 2, SBE_ISTEP3 = 3, SBE_ISTEP4 = 4, SBE_ISTEP5 = 5, }sbe_supported_steps_t; // constants // TODO via RTC 135345 // Check with Dean. In IPL flow doc ( version 0.63 ), // after istep 2.9, next istep is 2.11. istep 2.10 is not present. // So in IPL flow doc, total minor isteps for step 2 are 16. const uint32_t ISTEP2_MAX_SUBSTEPS = 15; const uint32_t ISTEP3_MAX_SUBSTEPS = 20; const uint32_t ISTEP4_MAX_SUBSTEPS = 31; const uint32_t ISTEP5_MAX_SUBSTEPS = 2; // File static data static istepMap_t g_istep2PtrTbl[ ISTEP2_MAX_SUBSTEPS ] = { { NULL, NULL }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_attr_setup }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_chiplet_init1 }, { &istepNoOp, NULL }, // DFT only { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_npll_initf }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_npll_setup }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_switch_gears }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_chiplet_reset }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_gptr_time_repr_initf }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_chiplet_init2 }, { &istepNoOp, NULL }, // DFT only { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_arrayinit }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_initf }, { &istepNoOp, NULL }, // DFT only { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_chiplet_init3}, }; static istepMap_t g_istep3PtrTbl[ ISTEP3_MAX_SUBSTEPS ] = { { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_chiplet_reset }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_chiplet_pll_initf }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_chiplet_pll_setup }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_gptr_time_repr_initf }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_chiplet_init }, { &istepNoOp, NULL }, // DFT only { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_arrayinit }, { &istepNoOp, NULL }, // DFT only { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_tp_enable_ridi }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_setup_evid }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_nest_initf }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_nest_startclocks }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_nest_enable_ridi }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_startclock_chiplets }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_scominit }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_lpc_init }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_fabricinit }, { &istepNoOp, NULL }, // TODO via RTC 120752 // FW proc_sbe_check_master { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_mcs_setup }, { &istepWithProc, (sbeIstepHwp_t)&p9_sbe_select_ex }, }; static istepMap_t g_istep4PtrTbl[ ISTEP4_MAX_SUBSTEPS ] = { { &istepWithEq, (sbeIstepHwp_t )&p9_hcd_cache_poweron }, { &istepWithEq, (sbeIstepHwp_t )&p9_hcd_cache_chiplet_reset }, { &istepWithEq, (sbeIstepHwp_t )&p9_hcd_cache_gptr_time_initf }, { &istepWithEq, (sbeIstepHwp_t )&p9_hcd_cache_dpll_setup }, { &istepWithEq, (sbeIstepHwp_t )&p9_hcd_cache_chiplet_init }, { &istepWithEx, (sbeIstepHwp_t )&p9_hcd_cache_repair_initf }, { &istepWithEx, (sbeIstepHwp_t )&p9_hcd_cache_arrayinit }, { &istepNoOp, NULL }, // DFT Only { &istepNoOp, NULL }, // DFT Only { &istepWithEx, (sbeIstepHwp_t )&p9_hcd_cache_initf }, { &istepWithEx, (sbeIstepHwp_t )&p9_hcd_cache_startclocks }, { &istepWithEx, (sbeIstepHwp_t )&p9_hcd_cache_scominit }, { &istepWithEx, (sbeIstepHwp_t )&p9_hcd_cache_scomcust }, { &istepNoOp, NULL }, // Runtime only { &istepNoOp, NULL }, // Runtime only { &istepNoOp, NULL }, // stub for SBE // TODO via RTC 135345 // As per IPL flow doc, p9_hcd_core_pcb_arb is no-op on SBE // But this HWP is present in SBE code bas and is No-OP. // If we do not require this HWP for future use cases, we // can make it istepNoOp as it will save space in SBE. { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_pcb_arb }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_poweron }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_chiplet_reset }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_gptr_time_initf }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_chiplet_init }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_repair_initf }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_arrayinit }, { &istepNoOp, NULL }, // DFT Only { &istepNoOp, NULL }, // DFT Only { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_initf }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_startclocks }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_scominit }, { &istepWithCore, (sbeIstepHwp_t )&p9_hcd_core_scomcust }, { &istepNoOp, NULL }, { &istepNoOp, NULL }, }; // TODO via RTC 135345 // Add the support for istep 5 HWP static istepMap_t g_istep5PtrTbl[ ISTEP5_MAX_SUBSTEPS ] { { &istepNoOp, NULL }, { &istepNoOp, NULL }, }; // Functions //---------------------------------------------------------------------------- uint32_t sbeHandleIstep (uint8_t *i_pArg) { #define SBE_FUNC "sbeHandleIstep " SBE_DEBUG(SBE_FUNC); uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; ReturnCode fapiRc = FAPI2_RC_SUCCESS; uint32_t len = 0; sbeIstepReqMsg_t req; sbeResponseGenericHeader_t respHdr; respHdr.init(); sbeResponseFfdc_t ffdc; // NOTE: In this function we will have two loops // First loop will deque data and prepare the response // Second response will enque the data on DS FIFO //loop 1 do { len = sizeof( req )/sizeof(uint32_t); rc = sbeUpFifoDeq_mult ( len, (uint32_t *)&req); if (rc != SBE_SEC_OPERATION_SUCCESSFUL) //FIFO access issue { SBE_ERROR(SBE_FUNC"FIFO dequeue failed, rc[0x%X]", rc); break; } SBE_DEBUG(SBE_FUNC"Major number:0x%08x minor number:0x%08x", req.major, req.minor ); if( false == validateIstep( req.major, req.minor ) ) { SBE_ERROR(SBE_FUNC" Invalid Istep. major:0x%08x" " minor:0x%08x", req.major, req.minor); // @TODO via RTC 132295. // Need to change code asper better error handling. respHdr.setStatus( SBE_PRI_INVALID_DATA, SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); break; } fapiRc = sbeExecuteIstep( req.major, req.minor ); if( fapiRc != FAPI2_RC_SUCCESS ) { SBE_ERROR(SBE_FUNC" sbeExecuteIstep() Failed. major:0x%08x" " minor:0x%08x", req.major, req.minor); respHdr.setStatus( SBE_PRI_GENERIC_EXECUTION_FAILURE, SBE_SEC_GENERIC_FAILURE_IN_EXECUTION); ffdc.setRc(fapiRc); } }while(0); //loop 2 do { // FIFO error if ( rc ) { break; } uint32_t distance = 1; //initialise by 1 for entry count itself. len = sizeof(respHdr)/sizeof(uint32_t); // sbeDownFifoEnq_mult. rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &respHdr); if (rc) { break; } distance += len; // If no ffdc , exit; if( ffdc.getRc() ) { len = sizeof(ffdc)/sizeof(uint32_t); rc = sbeDownFifoEnq_mult ( len, ( uint32_t *) &ffdc); if (rc) { break; } distance += len; } len = sizeof(distance)/sizeof(uint32_t); //@TODO via RTC 129076. //Need to add FFDC data as well. rc = sbeDownFifoEnq_mult ( len, &distance); if (rc) { break; } }while(0); if( rc ) { SBE_ERROR( SBE_FUNC"Failed. rc[0x%X]", rc); } return rc; #undef SBE_FUNC } //---------------------------------------------------------------------------- // @note This is the responsibilty of caller to verify major/minor // number before calling this function // @TODO via RTC 129077. // This function should check for system checkstop as well. ReturnCode sbeExecuteIstep (const uint8_t i_major, const uint8_t i_minor) { #define SBE_FUNC "sbeExecuteIstep " SBE_DEBUG(SBE_FUNC"Major number:0x%x minor number:0x%x", i_major, i_minor ); ReturnCode rc = FAPI2_RC_SUCCESS; switch( i_major ) { case SBE_ISTEP2: rc = (g_istep2PtrTbl[i_minor-1].istepWrapper)( g_istep2PtrTbl[i_minor-1].istepHwp); break; case SBE_ISTEP3: rc = (g_istep3PtrTbl[i_minor-1].istepWrapper)( g_istep3PtrTbl[i_minor-1].istepHwp); break; case SBE_ISTEP4: rc = (g_istep4PtrTbl[i_minor-1].istepWrapper)( g_istep4PtrTbl[i_minor-1].istepHwp); break; case SBE_ISTEP5: rc = (g_istep5PtrTbl[i_minor-1].istepWrapper)( g_istep5PtrTbl[i_minor-1].istepHwp); break; // We should never reach here as before calling this validation has // been done. default: assert(0); break; } return rc; #undef SBE_FUNC } //---------------------------------------------------------------------------- bool validateIstep (const uint8_t i_major, const uint8_t i_minor) { bool valid = true; do { if( 0 == i_minor ) { valid = false; break; } switch( i_major ) { case SBE_ISTEP2: // istep 2.1 loads image to PIBMEM // So SBE control loop can not execute istep 2.1. if(( i_minor > ISTEP2_MAX_SUBSTEPS ) || ( i_minor == 1) ) { valid = false; } break; case SBE_ISTEP3: if( i_minor > ISTEP3_MAX_SUBSTEPS ) { valid = false; } ; break; case SBE_ISTEP4: if( i_minor > ISTEP4_MAX_SUBSTEPS ) { valid = false; } break; case SBE_ISTEP5: if( i_minor > ISTEP5_MAX_SUBSTEPS ) { valid = false; } break; default: valid= false; break; } } while(0); return valid; } //---------------------------------------------------------------------------- ReturnCode istepWithProc( sbeIstepHwp_t i_hwp) { SBE_DEBUG("istepWithProc"); Target proc = plat_getChipTarget(); ReturnCode rc = FAPI2_RC_SUCCESS; if( i_hwp ) { rc = i_hwp(proc); } SBE_DEBUG("istepWithProc"); return rc; } //---------------------------------------------------------------------------- ReturnCode istepWithEx( sbeIstepHwp_t i_hwp) { fapi2::Target ex10_target((uint64_t)10); SBE_DEBUG("istepWithEx"); ReturnCode rc = FAPI2_RC_SUCCESS; if( i_hwp ) { rc = i_hwp(ex10_target); } return rc; } //---------------------------------------------------------------------------- ReturnCode istepWithEq( sbeIstepHwp_t i_hwp) { // TODO via RTC 135345 // Curently we are passing Hard code eq target. Finally it is // going to be a multicast target. Once multicast support is // present, use the right target. fapi2::Target eq10_target((uint64_t)10); SBE_DEBUG("istepWithEq"); ReturnCode rc = FAPI2_RC_SUCCESS; if( i_hwp ) { rc = i_hwp( eq10_target ); } return rc; } //---------------------------------------------------------------------------- ReturnCode istepWithCore( sbeIstepHwp_t i_hwp) { // TODO via RTC 135345 // Curently we are passing Hard code core target. Finally it is // going to be a multicast target. Once multicast support is // present, use the right target. fapi2::Target core_target((uint64_t)10); SBE_DEBUG("istepWithCore"); ReturnCode rc = FAPI2_RC_SUCCESS; if( i_hwp ) { rc = i_hwp( core_target ); } return rc; } //---------------------------------------------------------------------------- ReturnCode istepNoOp( sbeIstepHwp_t i_hwp) { SBE_DEBUG("istepNoOp"); return FAPI2_RC_SUCCESS ; } //---------------------------------------------------------------------------- uint32_t sbeWaitForSbeIplDone (uint8_t *i_pArg) { uint32_t rc = SBE_SEC_OPERATION_SUCCESSFUL; SBE_TRACE("sbeWaitForSbeIplDone"); return rc; }