/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/occ_405/mode.c $ */ /* */ /* OpenPOWER OnChipController Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2011,2017 */ /* [+] 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 #include #include "ssx_io.h" #include "trac.h" #include "rtls.h" #include "state.h" #include "occ_service_codes.h" #include "amec_freq.h" #include "amec_part.h" #include "amec_data.h" #include "amec_sys.h" errlHndl_t SMGR_mode_transition_to_nominal(); errlHndl_t SMGR_mode_transition_to_powersave(); errlHndl_t SMGR_mode_transition_to_dynpowersave(); errlHndl_t SMGR_mode_transition_to_dynpowersave_fp(); errlHndl_t SMGR_mode_transition_to_turbo(); errlHndl_t SMGR_mode_transition_to_ffo(); errlHndl_t SMGR_mode_transition_to_fmf(); errlHndl_t SMGR_mode_transition_to_nom_perf(); errlHndl_t SMGR_mode_transition_to_max_perf(); // Mode that OCC is currently in OCC_MODE G_occ_internal_mode = OCC_MODE_NOCHANGE; // Mode that OCC is requesting that TMGT put OCC into OCC_MODE G_occ_internal_req_mode = OCC_MODE_NOCHANGE; // Mode that TMGT is requesting OCC go to OCC_MODE G_occ_external_req_mode = OCC_MODE_NOCHANGE; // Mode that TMGT is requesting OCC go to in KVM OCC_MODE G_occ_external_req_mode_kvm = OCC_MODE_NOCHANGE; // Indicates if we are currently in a mode transition bool G_mode_transition_occuring = FALSE; // Mode that OCC Master is in OCC_MODE G_occ_master_mode = OCC_MODE_NOCHANGE; // Semaphore to allow mode change to be called from multiple threads SsxSemaphore G_smgrModeChangeSem; // Table that indicates which functions should be run for a given mode // transition. const smgr_state_trans_t G_smgr_mode_trans[] = { /* Current Mode New Mode Transition Function */ {OCC_MODE_ALL, OCC_MODE_NOMINAL, &SMGR_mode_transition_to_nominal}, {OCC_MODE_ALL, OCC_MODE_PWRSAVE, &SMGR_mode_transition_to_powersave}, {OCC_MODE_ALL, OCC_MODE_DYN_POWER_SAVE, &SMGR_mode_transition_to_dynpowersave}, {OCC_MODE_ALL, OCC_MODE_DYN_POWER_SAVE_FP, &SMGR_mode_transition_to_dynpowersave_fp}, {OCC_MODE_ALL, OCC_MODE_TURBO, &SMGR_mode_transition_to_turbo}, {OCC_MODE_ALL, OCC_MODE_FFO, &SMGR_mode_transition_to_ffo}, {OCC_MODE_ALL, OCC_MODE_FMF, &SMGR_mode_transition_to_fmf}, {OCC_MODE_ALL, OCC_MODE_NOM_PERFORMANCE, &SMGR_mode_transition_to_nom_perf}, {OCC_MODE_ALL, OCC_MODE_MAX_PERFORMANCE, &SMGR_mode_transition_to_max_perf}, }; const uint8_t G_smgr_mode_trans_count = sizeof(G_smgr_mode_trans)/sizeof(smgr_state_trans_t); // Function Specification // // Name: SMGR_is_mode_transitioning // // Description: // // End Function Specification inline bool SMGR_is_mode_transitioning(void) { return G_mode_transition_occuring; } // Function Specification // // Name: SMGR_get_mode // // Description: // // End Function Specification inline OCC_MODE SMGR_get_mode(void) { return G_occ_internal_mode; } // Function Specification // // Name: SMGR_set_mode // // Description: // // End Function Specification errlHndl_t SMGR_set_mode( const OCC_MODE i_mode ) { errlHndl_t l_errlHndl = NULL; int jj=0; OCC_MODE l_mode = i_mode; do { // Get lock for critical section if(ssx_semaphore_pend(&G_smgrModeChangeSem,SSX_WAIT_FOREVER)) { /* @ * @errortype * @moduleid MAIN_MODE_TRANSITION_MID * @reasoncode SSX_GENERIC_FAILURE * @userdata1 none * @userdata4 ERC_RUNNING_SEM_PENDING_FAILURE * @devdesc SSX semaphore related failure */ l_errlHndl = createErrl(MAIN_MODE_TRANSITION_MID, //modId SSX_GENERIC_FAILURE, //reasoncode ERC_RUNNING_SEM_PENDING_FAILURE,//Extended reason code ERRL_SEV_UNRECOVERABLE, //Severity NULL, //Trace Buf DEFAULT_TRACE_SIZE, //Trace Size 0, //userdata1 0); //userdata2 // Callout firmware addCalloutToErrl(l_errlHndl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_FIRMWARE, ERRL_CALLOUT_PRIORITY_HIGH); break; } //Check to see if we need to make a change if(l_mode == OCC_MODE_NOCHANGE) { break; } // OPAL only accepts DPS-FE mode. In case OCC gets other modes, it should accept the request // and keep reporting back that it is in that mode. However, internally we should not // initiate any mode transition, i.e., OCC should remain internally in DPS-FE mode. if(G_sysConfigData.system_type.kvm) { G_occ_external_req_mode_kvm = l_mode; if (l_mode != OCC_MODE_DYN_POWER_SAVE) { TRAC_ERR("OPAL only accepts DPS-FE mode(6) but requested mode is : %d", l_mode); l_mode = OCC_MODE_DYN_POWER_SAVE; } } // Change Mode via Transition Function do { // Loop through mode transition table, and find the state // transition function that matches the transition we need to do. for(jj=0; jj