diff options
author | Andres Lugo-Reyes <aalugore@us.ibm.com> | 2017-03-13 13:00:54 -0500 |
---|---|---|
committer | William A. Bryan <wilbryan@us.ibm.com> | 2017-04-27 13:32:40 -0400 |
commit | c36fa46c1e2ab003f0b12c0e52ad7301b826ea38 (patch) | |
tree | 9214d75dacb0807e1ddcaf0651a201fbaa9b6837 /src/occ_405/wof | |
parent | f19200513b5c918bf9405616811280c4c8ae2c09 (diff) | |
download | talos-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.c | 116 | ||||
-rw-r--r-- | src/occ_405/wof/wof.h | 96 |
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 ); |