/* * Function Specification * * Name: workaround_HW258436 * * Description: Sets up the PBA so that there is no overlap in use of buffers between * GPE engines and other engines. This came from Bishop Brock. * It should be pulled out after the procedure that sets up the PBA * has been fixed. Without this workaround we see an invalid instruction * failure on the GPE. * * End Function Specification */ void workaround_HW258436() { uint64_t l_scom_data = 0; int l_rc = 0; do { //scom errors will be committed internally -- gm033 l_rc = getscom_ffdc(0x64004, &l_scom_data, NULL); if(l_rc) break; l_scom_data &= 0xfffff1ffffffffffull; l_scom_data |= 0x0000080000000000ull; l_rc = putscom_ffdc(0x64004, l_scom_data, NULL); if(l_rc) break; l_rc = getscom_ffdc(0x64005, &l_scom_data, NULL); if(l_rc) break; l_scom_data &= 0xfffff1ffffffffffull; l_scom_data |= 0x0000040000000000ull; l_rc = putscom_ffdc(0x64005, l_scom_data, NULL); if(l_rc) break; l_rc = getscom_ffdc(0x64006, &l_scom_data, NULL); if(l_rc) break; l_scom_data &= 0xfffff1ffffffffffull; l_scom_data |= 0x0000040000000000ull; l_rc = putscom_ffdc(0x64006, l_scom_data, NULL); if(l_rc) break; l_rc = getscom_ffdc(0x64007, &l_scom_data, NULL); if(l_rc) break; l_scom_data &= 0xfffff1ffffffffffull; l_scom_data |= 0x0000040000000000ull; l_rc = putscom_ffdc(0x64007, l_scom_data, NULL); if(l_rc) break; }while(0); if(l_rc) { TRAC_ERR("workaround_HW258436: scom failure. rc=0x%08x", l_rc); } }
// Function Specification // // Name: proc_pstate_kvm_setup // // Description: Get everything set up for KVM mode // // End Function Specification void proc_pstate_kvm_setup() { int l_core; int l_rc = 0; uint32_t l_configured_cores; pcbs_pcbspm_mode_reg_t l_ppmr; pcbs_pmgp1_reg_t l_pmgp1; pcbs_power_management_bounds_reg_t l_pmbr; errlHndl_t l_errlHndl; do { //only run this in KVM mode if(!G_sysConfigData.system_type.kvm) { break; } l_configured_cores = ~in32(PMC_CORE_DECONFIGURATION_REG); // Do per-core configuration for(l_core = 0; l_core < PGP_NCORES; l_core++, l_configured_cores <<= 1) { if(!(l_configured_cores & 0x80000000)) continue; //do read-modify-write to allow pmax clip to also clip voltage (not just frequency) l_rc = getscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core), &(l_ppmr.value), NULL); //commit errors internally if(l_rc) { TRAC_ERR("proc_pstate_kvm_setup: getscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d", l_rc, l_core); break; } l_ppmr.fields.enable_clipping_of_global_pstate_req = 1; l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core), l_ppmr.value, NULL); //commit errors internally if(l_rc) { TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d", l_rc, l_core); break; } //per Vaidy Srinivasan, clear bit 11 in the Power Management GP1 register l_pmgp1.value = 0; l_pmgp1.fields.pm_spr_override_en = 1; l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PMGP1_REG_AND, l_core), ~l_pmgp1.value, NULL); //commit errors internally if(l_rc) { TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PMGB1_REG_OR) failed. rc=0x%08x, hw_core=%d", l_rc, l_core); break; } //set pmax/pmin clip initial settings l_pmbr.value = 0; l_pmbr.fields.pmin_clip = gpst_pmin(&G_global_pstate_table)+1; //Per David Du, we must use pmin+1 to avoid gpsa hang l_pmbr.fields.pmax_clip = gpst_pmax(&G_global_pstate_table); l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_POWER_MANAGEMENT_BOUNDS_REG, l_core), l_pmbr.value, NULL); //commit errors internally if(l_rc) { TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_POWER_MANAGEMENT_BOUNDS_REG) failed. rc=0x%08x, hw_core=%d", l_rc, l_core); break; } }// end of per-core config if(l_rc) { break; } // Set the voltage clipping register to match the pmax/pmin clip values set above. pmc_rail_bounds_register_t prbr; prbr.value = in32(PMC_RAIL_BOUNDS_REGISTER); prbr.fields.pmin_rail = gpst_pmin(&G_global_pstate_table); prbr.fields.pmax_rail = gpst_pmax(&G_global_pstate_table); TRAC_IMP("pmin clip pstate = %d, pmax clip pstate = %d", prbr.fields.pmin_rail, prbr.fields.pmax_rail); out32(PMC_RAIL_BOUNDS_REGISTER, prbr.value); // Initialize the sapphire table in SRAM (sets valid bit) populate_pstate_to_sapphire_tbl(); // copy sram image into mainstore HOMER populate_sapphire_tbl_to_mem(); TRAC_IMP("proc_pstate_kvm_setup: RUNNING IN KVM MODE"); }while(0); if(l_rc) { // Create Error Log and request reset /* @ * @errortype * @moduleid PROC_PSTATE_KVM_SETUP_MOD * @reasoncode PROC_SCOM_ERROR * @userdata1 l_configured_cores * @userdata2 Return Code of call that failed * @userdata4 OCC_NO_EXTENDED_RC * @devdesc OCC failed to scom a core register */ l_errlHndl = createErrl( PROC_PSTATE_KVM_SETUP_MOD, //modId PROC_SCOM_ERROR, //reasoncode OCC_NO_EXTENDED_RC, //Extended reason code ERRL_SEV_PREDICTIVE, //Severity NULL, //Trace Buf DEFAULT_TRACE_SIZE, //Trace Size l_configured_cores, //userdata1 l_rc //userdata2 ); addCalloutToErrl(l_errlHndl, ERRL_CALLOUT_TYPE_HUID, G_sysConfigData.proc_huid, ERRL_CALLOUT_PRIORITY_HIGH); addCalloutToErrl(l_errlHndl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_FIRMWARE, ERRL_CALLOUT_PRIORITY_MED); REQUEST_RESET(l_errlHndl); } }