summaryrefslogtreecommitdiffstats
path: root/src/occ_405/wof
diff options
context:
space:
mode:
authorAndres Lugo-Reyes <aalugore@us.ibm.com>2017-03-13 13:00:54 -0500
committerWilliam A. Bryan <wilbryan@us.ibm.com>2017-04-27 13:32:40 -0400
commitc36fa46c1e2ab003f0b12c0e52ad7301b826ea38 (patch)
tree9214d75dacb0807e1ddcaf0651a201fbaa9b6837 /src/occ_405/wof
parentf19200513b5c918bf9405616811280c4c8ae2c09 (diff)
downloadtalos-occ-c36fa46c1e2ab003f0b12c0e52ad7301b826ea38.tar.gz
talos-occ-c36fa46c1e2ab003f0b12c0e52ad7301b826ea38.zip
WOF: WOF header and OPPB updates
Change-Id: Ib7cdc81fef49707e9f78acc40ecb7218407b44ff RTC: 169955 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/37859 Reviewed-by: William A. Bryan <wilbryan@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/occ_405/wof')
-rw-r--r--src/occ_405/wof/wof.c116
-rw-r--r--src/occ_405/wof/wof.h96
2 files changed, 154 insertions, 58 deletions
diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c
index 9380289..ecc5809 100644
--- a/src/occ_405/wof/wof.c
+++ b/src/occ_405/wof/wof.c
@@ -57,7 +57,6 @@ wof_header_data_t G_wof_header __attribute__ ((section (".global_data")));
// Quad state structs to temporarily hold the data from the doublewords to
// then populate in amec structure
-//TODO RTC: 169955 - Update quad state temp structs to reflect new imported code
quad_state0_t G_quad_state_0 = {0};
quad_state1_t G_quad_state_1 = {0};
@@ -381,9 +380,9 @@ void wof_main(void)
* Return: The calculated step for current Ceff_vdd/Ceff_vdn
*/
uint16_t calculate_step_from_start(uint16_t i_ceff_vdx_ratio,
- uint8_t i_step_size,
- uint8_t i_min_ceff,
- uint8_t i_max_step )
+ uint16_t i_step_size,
+ uint16_t i_min_ceff,
+ uint16_t i_max_step )
{
uint16_t l_current_step;
@@ -442,7 +441,7 @@ uint32_t calc_vfrt_mainstore_addr( void )
{
// Wof tables address calculation
// (Base_addr + (sizeof VFRT * (total active quads * ( (g_wof->vdn_step_from_start * vdd_size) + (g_wof->vdd_step_from_start) ) + (g_wof->quad_step_from_start))))
- uint32_t offset = G_wof_header.size_of_vfrt *
+ uint32_t offset = G_wof_header.vfrt_block_size *
(( G_wof_header.active_quads_size *
((g_wof->vdn_step_from_start * G_wof_header.vdd_size) +
g_wof->vdd_step_from_start) ) + g_wof->quad_step_from_start);
@@ -463,7 +462,6 @@ uint32_t calc_vfrt_mainstore_addr( void )
* Param[in]: i_parms - pointer to a struct that will hold data necessary to
* the calculation.
* -Pointer to vfrt table temp buffer
- * -Padding if the address needed to be 128-byte aligned
*/
void copy_vfrt_to_sram( copy_vfrt_to_sram_parms_t * i_parms)
{
@@ -496,8 +494,8 @@ void copy_vfrt_to_sram( copy_vfrt_to_sram_parms_t * i_parms)
// Copy the vfrt data into the buffer
memcpy( l_buffer_address,
- &(i_parms->vfrt_table->data[i_parms->pad]),
- G_wof_header.size_of_vfrt );
+ i_parms->vfrt_table->data,
+ G_wof_header.vfrt_block_size );
// Set the parameters for the GpeRequest
G_wof_vfrt_parms.vfrt_ptr = l_buffer_address;
@@ -599,8 +597,40 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr )
uint32_t l_reasonCode = 0;
uint32_t l_extReasonCode = 0;
+ errlHndl_t l_errl = NULL;
do
{
+ // First check if the address is 128-byte aligned. error if not.
+ if( i_vfrt_main_mem_addr % 128 )
+ {
+ g_wof->wof_disabled |= WOF_RC_VFRT_ALIGNMENT_ERROR;
+
+ /* @
+ * @errortype
+ * @moduleid SEND_VFRT_TO_PGPE
+ * @reasoncode WOF_VFRT_ALIGNMENT_ERROR
+ * @userdata1 The input vfrt address
+ * @userdata2 0
+ * @userdata4 OCC_NO_EXTENDED_RC
+ * @devdesc VFRT address is not 128-byte aligned
+ */
+ l_errl = createErrl(
+ SEND_VFRT_TO_PGPE, // modId
+ WOF_VFRT_ALIGNMENT_ERROR, // reasoncode
+ OCC_NO_EXTENDED_RC, // Extended reason code
+ ERRL_SEV_UNRECOVERABLE, // Severity
+ NULL, // Trace Buf
+ DEFAULT_TRACE_SIZE, // Trace Size
+ i_vfrt_main_mem_addr, // userdata1
+ 0 // userdata2
+ );
+
+ // Commit error log
+ commitErrl(&l_errl);
+
+ break;
+ }
+
if( (i_vfrt_main_mem_addr == g_wof->curr_vfrt_main_mem_addr ) &&
(g_wof->req_active_quad_update ==
g_wof->prev_req_active_quads) )
@@ -618,21 +648,15 @@ void send_vfrt_to_pgpe( uint32_t i_vfrt_main_mem_addr )
// 128-byte aligned temp buffer to hold data
temp_bce_request_buffer_t l_temp_bce_buff = {{0}};
- // TODO RTC 169955: No longer need padding as VFRT addresses
- // will already be 128-byte aligned and sized
- uint8_t l_pad = i_vfrt_main_mem_addr%128;
- uint32_t l_vfrt_addr_128_aligned = i_vfrt_main_mem_addr - l_pad;
-
// Create structure to hold parameters for callback function
copy_vfrt_to_sram_parms_t l_callback_parms;
l_callback_parms.vfrt_table = &l_temp_bce_buff;
- l_callback_parms.pad = l_pad;
// Create request
l_ssxrc = bce_request_create(
&l_vfrt_req, // block copy object
&G_pba_bcde_queue, // main to sram copy engine
- l_vfrt_addr_128_aligned, //mainstore address
+ i_vfrt_main_mem_addr, //mainstore address
(uint32_t) &l_temp_bce_buff, // SRAM start address
MIN_BCE_REQ_SIZE, // size of copy
SSX_WAIT_FOREVER, // no timeout
@@ -715,15 +739,22 @@ void read_shared_sram( void )
G_quad_state_0.value = in64(g_wof->quad_state_0_addr);
G_quad_state_1.value = in64(g_wof->quad_state_1_addr);
+ // Read f_clip, v_clip, f_ratio, and v_ratio
+ pgpe_wof_state_t l_wofstate;
+ l_wofstate.value = in64(g_wof->pgpe_wof_state_addr);
+ g_wof->f_clip = l_wofstate.fields.fclip_ps;
+ g_wof->v_clip = l_wofstate.fields.vclip_mv;
+ g_wof->f_ratio = l_wofstate.fields.fratio;
+ g_wof->v_ratio = l_wofstate.fields.vratio;
+
// Get the requested active quad update
read_req_active_quads();
- // merge the 16-bit power-on field from quad state 0 and the 16-bit power-on
- // field from quad state 1 and save it to amec.
- // TODO RTC:16955 - core_poweron_state not in new structure
- //g_wof->core_pwr_on =
- // (((uint32_t)G_quad_state_0.fields.core_poweron_state) << 16)
- // | ((uint32_t)G_quad_state_1.fields.core_poweron_state);
+ // merge the 16-bit active_cores field from quad state 0 and the 16-bit
+ // active_cores field from quad state 1 and save it to amec.
+ g_wof->core_pwr_on =
+ (((uint32_t)G_quad_state_0.fields.active_cores) << 16)
+ | ((uint32_t)G_quad_state_1.fields.active_cores);
// Clear out current quad pstates
memset(g_wof->quad_x_pstates, 0 , MAXIMUM_QUADS);
@@ -737,6 +768,8 @@ void read_shared_sram( void )
g_wof->quad_x_pstates[5] = (uint8_t)G_quad_state_1.fields.quad5_pstate;
// Save IVRM bit vector states to amec
+ // NOTE: the ivrm_state field in both quad state 0 and quad state 1
+ // double words should contain the same data.
g_wof->quad_ivrm_states =
(((uint8_t)G_quad_state_0.fields.ivrm_state) << 4)
| ((uint8_t)G_quad_state_1.fields.ivrm_state);
@@ -824,7 +857,7 @@ void calculate_core_leakage( void )
for(;l_chip_v_idx < CORE_IDDQ_MEASUREMENTS - 1; l_chip_v_idx++)
{
if( (l_v_chip >= G_iddq_voltages[l_chip_v_idx]) &&
- (l_v_chip <= G_iddq_voltages[l_chip_v_idx]) )
+ (l_v_chip <= G_iddq_voltages[l_chip_v_idx+1]) )
{
break;
}
@@ -1034,6 +1067,42 @@ void calculate_core_leakage( void )
*/
void calculate_nest_leakage( void )
{
+
+
+ // Get the VOLTVDN sensor to choose the appropriate nest voltage
+ // index
+ uint32_t l_v_nest = g_wof->voltvdn_sensor;
+ int l_nest_v_idx = 0;
+
+ if( l_v_nest <= G_iddq_voltages[0] )
+ {
+ // Voltage is <= first entry. Use first two entries.
+ l_nest_v_idx = 0;
+ }
+ else if( l_v_nest >= G_iddq_voltages[CORE_IDDQ_MEASUREMENTS-1] )
+ {
+ // Voltage is >= to last entry. use last two entries.
+ l_nest_v_idx = CORE_IDDQ_MEASUREMENTS - 2;
+ }
+ else
+ {
+ // Search for entries on either side of our voltage
+ for(; l_nest_v_idx < CORE_IDDQ_MEASUREMENTS - 1; l_nest_v_idx++)
+ {
+ if( (l_v_nest >= G_iddq_voltages[l_nest_v_idx]) &&
+ (l_v_nest <= G_iddq_voltages[l_nest_v_idx+1]) )
+ {
+ break;
+ }
+ }
+ }
+
+ uint32_t idc_nest = interpolate_linear((int32_t) l_v_nest,
+ (int32_t)G_iddq_voltages[l_nest_v_idx],
+ (int32_t)G_iddq_voltages[l_nest_v_idx+1],
+ (int32_t)G_oppb.iddq.ivdn[l_nest_v_idx],
+ (int32_t)G_oppb.iddq.ivdn[l_nest_v_idx+1]);
+
// Get the desired tvpd leak for nest calculation
// avgtemp in IDDQ table is 0.5C units. Divide by 2 to get 1C
g_wof->tvpd_leak_nest = G_oppb.iddq.avgtemp_vdn >> 1;
@@ -1045,8 +1114,7 @@ void calculate_nest_leakage( void )
uint32_t nest_mult = calculate_multiplier( nest_delta_temp );
// Save nest leakage to amec structure
- // TODO: ivdn is now an array and need to handle
- g_wof->idc_vdn = (G_oppb.iddq.ivdn[0]*nest_mult) >> 10;
+ g_wof->idc_vdn = (idc_nest*nest_mult) >> 10;
}
/**
diff --git a/src/occ_405/wof/wof.h b/src/occ_405/wof/wof.h
index e8e743a..e0715a3 100644
--- a/src/occ_405/wof/wof.h
+++ b/src/occ_405/wof/wof.h
@@ -32,7 +32,7 @@
//******************************************************************************
#define ACTIVE_QUAD_SZ_MIN 1
#define ACTIVE_QUAD_SZ_MAX 6
-#define MIN_BCE_REQ_SIZE 256
+#define MIN_BCE_REQ_SIZE 128
#define WOF_HEADER_SIZE 32
#define CORE_IDDQ_MEASUREMENTS 6
#define QUAD_POWERED_OFF 0xFF
@@ -60,7 +60,7 @@
#define WOF_RC_DIVIDE_BY_ZERO 0x0800
#define WOF_RC_VFRT_REQ_FAILURE 0x1000
#define WOF_RC_CONTROL_REQ_FAILURE 0x2000
-
+#define WOF_RC_VFRT_ALIGNMENT_ERROR 0x4000
// Reason codes which should NOT create an error log should be added here
#define ERRL_RETURN_CODES ~(WOF_RC_MODE_CHANGE | \
@@ -85,39 +85,70 @@ enum wof_init_states
// Structure to hold relevant data from the WOF header in Mainstore
typedef struct __attribute__ ((packed))
{
- uint32_t magic_number;
- uint8_t reserved[3];
- uint8_t version;
- uint8_t size_of_vfrt;
- uint8_t vfrt_data_size;
- uint8_t active_quads_start;
- uint8_t active_quads_size;
- uint8_t vdn_start;
- uint8_t vdn_step;
- uint8_t vdn_size;
- uint8_t vdd_start;
- uint8_t vdd_step;
- uint8_t vdd_size;
+ uint32_t magic_number; //4
+ uint8_t reserved_1[7]; //11
+ uint8_t version; //12
+ uint16_t vfrt_block_size; //14
+ uint16_t vfrt_blck_hdr_sz; //16
+ uint16_t vfrt_data_size; //18
+ uint8_t active_quads_size; //19
+ uint8_t core_count; //20
+ uint16_t vdn_start; //22
+ uint16_t vdn_step; //24
+ uint16_t vdn_size; //26
+ uint16_t vdd_start; //28
+ uint16_t vdd_step; //30
+ uint16_t vdd_size; //32
+ uint16_t vratio_start; //34
+ uint16_t vratio_step; //36
+ uint16_t vratio_size; //38
+ uint16_t fratio_start; //40
+ uint16_t fratio_step; //42
+ uint16_t fratio_size; //44
+ uint16_t vdn_percent[8]; //60
+ uint16_t socket_power_w; //62
+ uint16_t nest_freq_mhz; //64
+ uint16_t nom_freq_mhz; //66
+ uint16_t rdp_capacity; //68
+ uint64_t wof_tbls_src_tag; //76
+ uint64_t package_name_hi; //84
+ uint64_t package_name_lo; //88
+ uint8_t reserved_2[40]; //128
} wof_header_data_t;
-
// Structure used in g_amec
typedef struct
{
// Bit vector where each bit signifies a different failure case
uint16_t wof_disabled;
// Data from wof header for debug
- uint8_t size_of_vfrt;
- uint8_t vfrt_data_size;
- uint8_t active_quads_start;
- uint8_t active_quads_size;
- uint8_t vdn_start;
- uint8_t vdn_step;
- uint8_t vdn_size;
- uint8_t vdd_start;
- uint8_t vdd_step;
- uint8_t vdd_size;
+ uint8_t version; //12
+ uint16_t vfrt_block_size; //14
+ uint16_t vfrt_blck_hdr_sz; //16
+ uint16_t vfrt_data_size; //18
+ uint8_t active_quads_size; //19
+ uint8_t core_count; //20
+ uint16_t vdn_start; //22
+ uint16_t vdn_step; //24
+ uint16_t vdn_size; //26
+ uint16_t vdd_start; //28
+ uint16_t vdd_step; //30
+ uint16_t vdd_size; //32
+ uint16_t vratio_start; //34
+ uint16_t vratio_step; //36
+ uint16_t vratio_size; //38
+ uint16_t fratio_start; //40
+ uint16_t fratio_step; //42
+ uint16_t fratio_size; //44
+ uint16_t vdn_percent[8]; //60
+ uint16_t socket_power_w; //62
+ uint16_t nest_freq_mhz; //64
+ uint16_t nom_freq_mhz; //66
+ uint16_t rdp_capacity; //68
+ uint64_t wof_tbls_src_tag; //76
+ uint64_t package_name_hi; //84
+ uint64_t package_name_lo; //88
// Calculated step from start for VDD
uint16_t vdd_step_from_start;
// Calculated step from start for VDN
@@ -244,16 +275,14 @@ typedef struct
uint32_t quad_state_0_addr;
// The address in shared OCC-PGPE SRAM of Quad State 1
uint32_t quad_state_1_addr;
+ // The address in shared OCC-PGPE SRAM of the PGPE WOF state
+ uint32_t pgpe_wof_state_addr;
// The address in shared OCC-PGPE SRAM of the Requested Active quads
uint32_t req_active_quads_addr;
} amec_wof_t;
typedef struct
{
- // There is no guarantee that we can fit everything into the min BceRequest
- // size of 128 given that there may be a need to padding in the event the
- // Main Memory address is not 128-byte aligned. The data here is 256 to
- // ensure we have enough room for any and all padding that may be needed.
uint8_t data[MIN_BCE_REQ_SIZE];
} temp_bce_request_buffer_t __attribute ((aligned(128)));
@@ -263,7 +292,6 @@ typedef struct
typedef struct
{
temp_bce_request_buffer_t * vfrt_table;
- uint8_t pad;
} copy_vfrt_to_sram_parms_t;
//******************************************************************************
@@ -275,9 +303,9 @@ void call_wof_main( void );
void wof_main( void );
uint16_t calculate_step_from_start( uint16_t i_ceff_vdx,
- uint8_t i_step_size,
- uint8_t i_min_step,
- uint8_t i_max_step );
+ uint16_t i_step_size,
+ uint16_t i_min_step,
+ uint16_t i_max_step );
uint8_t calc_quad_step_from_start( void );
OpenPOWER on IntegriCloud