1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
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();
}
|