diff options
Diffstat (limited to 'src/occ/amec/amec_init.c')
-rwxr-xr-x | src/occ/amec/amec_init.c | 426 |
1 files changed, 426 insertions, 0 deletions
diff --git a/src/occ/amec/amec_init.c b/src/occ/amec/amec_init.c new file mode 100755 index 0000000..7031eb0 --- /dev/null +++ b/src/occ/amec/amec_init.c @@ -0,0 +1,426 @@ +/****************************************************************************** +// @file amec_init.c +// @brief OCC AMEC Initialization +*/ +/****************************************************************************** + * + * @page ChangeLogs Change Logs + * @section amec_init.c AMEC_INIT.C + * @verbatim + * + * Flag Def/Fea Userid Date Description + * ------- ---------- -------- ---------- ---------------------------------- + * @th005 thallet 11/18/2011 Added this file + * @th00a thallet 02/03/2012 Worst case FW timings in AMEC Sensors + * @th00b thallet 02/28/2012 Added functions to init vector sensors + * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments + * @pb00E pbavari 03/11/2012 Added correct include file + * @nh001 neilhsu 05/23/2012 Add missing error log tags + * @gs001 gsilva 08/03/2012 Added g_amec init function + * @ly001 853751 lychen 09/17/2012 Support DPS algorithm + * @ry002 822116 ronda 11/26/2012 Support thermal controller for processor + * @ry003 870734 ronda 02/20/2013 Thermal controller for memory + * @fk001 879727 fmkassem 04/16/2013 PCAP support. + * @cl001 lefurgy 07/24/2013 Fix thermal control loop + * @gm006 SW224414 milesg 09/16/2013 Reset and FFDC improvements + * @gm008 SW226989 milesg 09/30/2013 Sapphire initial support + * @gs023 912003 gjsilva 01/16/2014 Generate VRHOT signal and control loop + * @mw641 918066 mware 02/23/2014 g44_avg changed to 32 bits. Altered zeroing out of array at init. + * + * @endverbatim + * + *///*************************************************************************/ + +//************************************************************************* +// Includes +//************************************************************************* +//@pb00Ec - changed from common.h to occ_common.h for ODE support +#include <occ_common.h> +#include <amec_sys.h> +#include <ssx.h> +#include <errl.h> // Error logging +#include <rtls.h> +#include <occ_sys_config.h> +#include <occ_service_codes.h> // for SSX_GENERIC_FAILURE +#include <trac.h> +#include "state.h" +#include "amec_service_codes.h" +#include <amec_sys.h> +#include <proc_data.h> +#include <sensor.h> + +//************************************************************************* +// Externs +//************************************************************************* + +//************************************************************************* +// Macros +//************************************************************************* + +//************************************************************************* +// Defines/Enums +//************************************************************************* + +//************************************************************************* +// Structures +//************************************************************************* + +//************************************************************************* +// Globals +//************************************************************************* +// We can initialize amec system structure to all zeros +amec_sys_t g_amec_sys = {0}; //@gm008 + +// Initialize g_amec to point to g_amec_sys +// We use this pointer to keep the amec code as similar to TPMD +amec_sys_t * g_amec = &g_amec_sys; + +// GPE Request Structure that is used to measure the worst case GPE timings +PoreFlex G_gpe_nop_request[NUM_GPE_ENGINES]; // @th00a + +extern PoreEntryPoint GPE_pore_nop; // @th00a +extern void amec_slv_update_gpe_sensors(uint8_t i_gpe_engine); // @th00a +extern void amec_slv_update_gpe_sensors(uint8_t i_gpe_engine); // @th00a + +//************************************************************************* +// Function Prototypes +//************************************************************************* + +//************************************************************************* +// Functions +//************************************************************************* +void amec_vectorize_core_sensor(sensor_t * l_sensor, + vectorSensor_t * l_vector, + const VECTOR_SENSOR_OP l_op, + uint16_t l_sensor_elem_array_gsid) +{ +#define VECTOR_CREATE_FAILURE 1 +#define VECTOR_ADD_ELEM_FAILURE 2 + + int l_idx = 0; // Used to index the for loops for vector create + int l_rc = 0; // Indicates failure to add a sensor to vector + uint16_t l_gsid = 0xFFFF; + errlHndl_t l_err = NULL; + + do + { + // Grab GSID for errl in case of failure + l_gsid = l_sensor->gsid; + + // Vectorize the sensor + sensor_vectorize(l_sensor, + l_vector, + l_op); + + // If vectorize worked, add elements to the vector sensor + if(NULL != l_sensor->vector) + { + // Loop through cores + for(l_idx=0; l_idx<MAX_NUM_CORES; l_idx++) + { + // Add elements to the vector sensor + sensor_vector_elem_add(l_sensor->vector, + l_idx, + AMECSENSOR_ARRAY_PTR(l_sensor_elem_array_gsid,l_idx)); + // If core is not present, disable this vector element + if(!CORE_PRESENT(l_idx)) + { + sensor_vector_elem_enable(l_sensor->vector, + l_idx, + 0 /* Disable */); + } + } + + // Sanity check, we should have MAX_NUM_CORES entries in + // vector sensor + if(l_sensor->vector->size != MAX_NUM_CORES) + { + // Set l_rc and break out so that we can create an errl + l_rc = VECTOR_ADD_ELEM_FAILURE; + break; + } + } + else + { + // Set l_rc and break out so that we can create an errl + l_rc = VECTOR_CREATE_FAILURE; + break; + } + }while(0); + + if(l_rc) + { + //If fail to create pore flex object then there is a problem. + TRAC_ERR("Failed to vectorize sensor[0x%x, 0x%x]", l_gsid, l_rc ); + + /* @ + * @errortype + * @moduleid AMEC_VECTORIZE_FW_SENSORS + * @reasoncode SSX_GENERIC_FAILURE + * @userdata1 return code + * @userdata2 gsid of failed sensor + * @userdata4 OCC_NO_EXTENDED_RC + * @devdesc Firmware failure in call to vectorize sensor + */ + l_err = createErrl( + AMEC_VECTORIZE_FW_SENSORS, //modId + SSX_GENERIC_FAILURE, //reasoncode + OCC_NO_EXTENDED_RC, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL,//TODO: create trace //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + l_rc, //userdata1 + l_gsid //userdata2 + ); + + REQUEST_RESET(l_err); //gm06 + } +} + +void amec_init_vector_sensors(void) +{ + +#define VECTOR_CREATE_FAILURE 1 +#define VECTOR_ADD_ELEM_FAILURE 2 + + //----------------------------------------------------- + // TEMP2MSP0 Vector Sensor + //----------------------------------------------------- + amec_vectorize_core_sensor(AMECSENSOR_PTR(TEMP2MSP0), + &g_amec_sys.proc[0].temp2ms_vector, + VECTOR_OP_AVG, + TEMP2MSP0C0); + + //----------------------------------------------------- + // FREQA2MSP0 Vector Sensor + //----------------------------------------------------- + amec_vectorize_core_sensor(AMECSENSOR_PTR(FREQA2MSP0), // @mw626 + &g_amec_sys.proc[0].freqa2ms_vector, + VECTOR_OP_AVG, + FREQA2MSP0C0); + + //----------------------------------------------------- + // IPS2MSP0 Vector Sensor + //----------------------------------------------------- + amec_vectorize_core_sensor(AMECSENSOR_PTR(IPS2MSP0), + &g_amec_sys.proc[0].ips2ms_vector, + VECTOR_OP_AVG, + IPS2MSP0C0); + + //----------------------------------------------------- + // TEMP2MSP0PEAK Vector Sensor + //----------------------------------------------------- + amec_vectorize_core_sensor(AMECSENSOR_PTR(TEMP2MSP0PEAK), + &g_amec_sys.proc[0].temp2mspeak_vector, + VECTOR_OP_MAX, + TEMP2MSP0C0); + + //----------------------------------------------------- + // UTIL2MSP0 Vector Sensor + //----------------------------------------------------- + amec_vectorize_core_sensor(AMECSENSOR_PTR(UTIL2MSP0), + &g_amec_sys.proc[0].util2ms_vector, + VECTOR_OP_AVG, + UTIL2MSP0C0); + +#if 0 //TODO: Re-enable with error checking when centaur support is added + int l_rc = 0, l_idx = 0, l_idx2 = 0; // Used to index the for loops for vector create + //----------------------------------------------------- + // MEMSP2MSP0 Vector Sensor + //----------------------------------------------------- + sensor_vectorize(AMECSENSOR_PTR(MEMSP2MSP0), + &g_amec_sys.proc[0].memsp2ms_vector, + VECTOR_OP_MIN); + + for(l_idx=0; l_idx<MAX_NUM_MEM_CONTROLLERS; l_idx++) + { + for(l_idx2=0; l_idx2<NUM_PORT_PAIRS_PER_CENTAUR; l_idx2++) + { + sensor_vector_elem_add(AMECSENSOR_PTR(MEMSP2MSP0)->vector, + l_idx, + AMECSENSOR_2D_ARRAY_PTR(MEMSP2MSPM0C0P0,l_idx, l_idx2)); + } + } +#endif +} + +// Function Specification +// +// Name: amec_init_gamec_struct +// +// Description: Perform initialization of g_amec structure +// +// Flow: --/--/-- FN=a +// +// End Function Specification +void amec_init_gamec_struct(void) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint16_t l_idx = 0; // @ly001a + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + // Defaul the frequency range to something safe + g_amec->sys.fmin = 2000; + g_amec->sys.fmax = 2000; + g_amec->sys.max_speed = 1000; // @ly001a + + g_amec->sys.min_speed = 400; + g_amec->sys.speed_step = 10; + g_amec->sys.speed_step_limit = (uint16_t)((65535/4)/(g_amec->sys.speed_step)); + + // Initialize thermal controller for processor + g_amec->thermalproc.setpoint = 850; // @cl001 change to 850 = 85.0 C + g_amec->thermalproc.Pgain = 1000; + g_amec->thermalproc.speed_request = 1000; + g_amec->thermalproc.freq_request = -1; //unconstrained frequency vote + g_amec->thermalproc.total_res = 0; + + // Initialize thermal controller based on DIMM temperatures + g_amec->thermaldimm.setpoint = 850; //In 0.1 degrees C @cl001 change to 850 = 85.0 C + g_amec->thermaldimm.Pgain = 30000; + g_amec->thermaldimm.speed_request = AMEC_MEMORY_MAX_STEP; + + // Initialize thermal controller based on Centaur temperatures + g_amec->thermalcent.setpoint = 850; //In 0.1 degrees C @cl001 change to 850 = 85.0 C + g_amec->thermalcent.Pgain = 30000; + g_amec->thermalcent.speed_request = AMEC_MEMORY_MAX_STEP; + + // Initialize controler based on VRHOT signal from processor regulator + g_amec->vrhotproc.setpoint = 100; + g_amec->vrhotproc.freq_request = -1; + g_amec->vrhotproc.speed_request = 1000; + + // @ly001a - start + // Initialize partition information + amec_part_init(); + + // Initialize performace counter + for (l_idx=0; l_idx<MAX_NUM_CORES; l_idx++) + { + amec_core_perf_counter_ctor(&g_amec->proc[0].core[l_idx].core_perf, 0, l_idx); + } + // @ly001a - end + + //Initialize processor fields + g_amec->proc[0].core_max_freq = G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]; + + //Initialize processor power votes + g_amec->proc[0].pwr_votes.pmax_clip_freq = G_sysConfigData.sys_mode_freq.table[OCC_MODE_TURBO]; + + //Initialize stream buffer recording parameters + g_amec->recordflag=0; // Never enable recording until requested via Amester API call + g_amec->r_cnt=0; // Reset counter of 250us ticks + g_amec->ptr_stream_buffer = &g_amec->stream_buffer[0]; + g_amec->stream_vector_mode=0; // No recording yet + g_amec->stream_vector_delay=0; // Delay in msec before recording can begin + g_amec->stream_vector_rate=0xff; // Invalid setting: requires IPMI command to select initial rate + + //Initialize analytics parameters + g_amec->analytics_group=44; // Default to analytics Group 44 $mw431 + g_amec->analytics_chip=0; // Default to which chip to perform analytics on $mw417 + g_amec->analytics_bad_output_count=0; // Number of frames to discard before recording analytics output @mw587 + g_amec->analytics_total_chips=MAX_NUM_CHIP_MODULES; // Default to do all chips in the system $mw418 + g_amec->analytics_threadmode=1; // Default is average of all N threads $mw470 (may be altered with IPMI command) + g_amec->analytics_threadcountmax=4; // Default is 4 threads per core $mw459 (may be altered with IPMI command) + g_amec->analytics_total_chips=4; // For Tuleta force to only 2 DCM sockets, 4 chips + g_amec->analytics_option=1; // =0 means cycle through all chips, =1 means only work with analytics_chip + g_amec->analytics_thermal_offset=0; // Reset offset to 0 for thermal output group + g_amec->analytics_slot=4; // Time slot associated with when the amec_analytics function is called (out of 8 slots) @mw586 + // Set entire averaging buffer to zero $mw417 + memset (&g_amec->g44_avg, 0, 4*(MAX_SENSORS_ANALYTICS*MAX_NUM_CHIP_MODULES)); // @mw641 +} + +// Function Specification +// +// Name: amec_slave_init +// +// Description: Perform initialization of any/all AMEC Slave Functions +// +// Flow: 2/01/12 FN=amec_slave_init +// +// End Function Specification + +void amec_slave_init() +{ + errlHndl_t l_err = NULL; // Error handler + int rc = 0; // Return code + int rc2 = 0; // Return code + + // Set the GPE Request Pointers to NULL in case the create fails. + G_fw_timing.gpe0_timing_request = NULL; + G_fw_timing.gpe1_timing_request = NULL; + + // Initializes the GPE routine that will be used to measure the worst case + // timings for GPE0 + rc = pore_flex_create( &G_gpe_nop_request[0], //gpe_req for the task + &G_pore_gpe0_queue, //queue + (void *) GPE_pore_nop, //entry point + (uint32_t) NULL, //parm for the task + SSX_WAIT_FOREVER, //no timeout + (AsyncRequestCallback) amec_slv_update_gpe_sensors, //callback + (void *) GPE_ENGINE_0, //callback argument + ASYNC_CALLBACK_IMMEDIATE ); //options + + // Initializes the GPE routine that will be used to measure the worst case + // timings for GPE1 + rc2 = pore_flex_create( &G_gpe_nop_request[1], //gpe_req for the task + &G_pore_gpe1_queue, //queue + (void *)GPE_pore_nop, //entry point + (uint32_t) NULL, //parm for the task + SSX_WAIT_FOREVER, //no timeout + (AsyncRequestCallback) amec_slv_update_gpe_sensors, //callback + (void *) GPE_ENGINE_1, //callback argument + ASYNC_CALLBACK_IMMEDIATE ); //options + + // If we couldn't create the poreFlex objects, there must be a major problem + // so we will log an error and halt OCC. + if( rc || rc2 ) + { + //If fail to create pore flex object then there is a problem. + TRAC_ERR("Failed to create GPE duration poreFlex object[0x%x, 0x%x]", rc, rc2 ); + + /* @ + * @errortype + * @moduleid AMEC_INITIALIZE_FW_SENSORS + * @reasoncode SSX_GENERIC_FAILURE + * @userdata1 return code - gpe0 + * @userdata2 return code - gpe1 + * @userdata4 OCC_NO_EXTENDED_RC + * @devdesc Failure to create PORE-GPE poreFlex object for FW timing + * analysis. + * + */ + l_err = createErrl( + AMEC_INITIALIZE_FW_SENSORS, //modId + SSX_GENERIC_FAILURE, //reasoncode + OCC_NO_EXTENDED_RC, //Extended reason code + ERRL_SEV_PREDICTIVE, //Severity + NULL, //TODO: create trace //Trace Buf + DEFAULT_TRACE_SIZE, //Trace Size + rc, //userdata1 + rc2 //userdata2 + ); + + REQUEST_RESET(l_err); //gm06 + + } + else + { + // Everything was successful, so set FW timing pointers to these + // GPE Request objects + G_fw_timing.gpe0_timing_request = &G_gpe_nop_request[0]; + G_fw_timing.gpe1_timing_request = &G_gpe_nop_request[1]; + } + + // Initialize Vector Sensors for AMEC use + amec_init_vector_sensors(); // @th00b + + // Initialize AMEC internal parameters + amec_init_gamec_struct(); +} + |