diff options
Diffstat (limited to 'src/occ_405/cmdh/cmdh_fsp_cmds.c')
-rwxr-xr-x | src/occ_405/cmdh/cmdh_fsp_cmds.c | 342 |
1 files changed, 311 insertions, 31 deletions
diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds.c b/src/occ_405/cmdh/cmdh_fsp_cmds.c index c047d15..0933372 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds.c @@ -50,6 +50,7 @@ #include <avsbus.h> #include "cmdh_dbug_cmd.h" #include "wof.h" +#include "sensor_main_memory.h" extern dimm_sensor_flags_t G_dimm_temp_expired_bitmap; extern bool G_vrm_thermal_monitoring; @@ -1824,74 +1825,101 @@ errlHndl_t cmdh_tmgt_get_field_debug_data(const cmdh_fsp_cmd_t * i_cmd_ptr, // Function Specification // -// Name: cmdh_set_user_pcap +// Name: cmdh_set_user_pcap_common // -// Description: Implements the Set Use Power Cap command. +// Description: Implements the common part of Set Use Power Cap cmd from inband or out of band // // End Function Specification -errlHndl_t cmdh_set_user_pcap(const cmdh_fsp_cmd_t * i_cmd_ptr, - cmdh_fsp_rsp_t * o_rsp_ptr) +uint8_t cmdh_set_user_pcap_common(uint16_t i_pcap, + uint8_t i_source) { - errlHndl_t l_err = NULL; - ERRL_RC l_rc = ERRL_RC_SUCCESS; - - - G_rsp_status = ERRL_RC_SUCCESS; - o_rsp_ptr->data_length[0] = 0; - o_rsp_ptr->data_length[1] = 0; + uint8_t l_rc = ERRL_RC_SUCCESS; do { // Can't send this command to a slave if (OCC_SLAVE == G_occ_role) { + TRAC_ERR("From source %d User PCAP %d must be sent to master OCC", + i_source, i_pcap); l_rc = ERRL_RC_INVALID_CMD; break; } - if (CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr) != CMDH_SET_USER_PCAP_DATALEN) - { - l_rc = ERRL_RC_INVALID_CMD_LEN; - break; - } - - uint16_t l_pcap = CONVERT_UINT8_ARRAY_UINT16(i_cmd_ptr->data[0], - i_cmd_ptr->data[1]); - //A value of 0 means this pcap has been deactivated, otherwise //make sure it's within the min & max. - if ((l_pcap != 0) && (l_pcap < G_master_pcap_data.soft_min_pcap)) + if ((i_pcap != 0) && (i_pcap < G_master_pcap_data.soft_min_pcap)) { - TRAC_ERR("User PCAP %d is below the minimum allowed (%d)", - l_pcap, G_master_pcap_data.soft_min_pcap); + TRAC_ERR("From source %d User PCAP %d is below the minimum allowed (%d)", + i_source, i_pcap, G_master_pcap_data.soft_min_pcap); l_rc = ERRL_RC_INVALID_DATA; break; } - else if ((l_pcap > G_master_pcap_data.system_pcap) && + else if ((i_pcap > G_master_pcap_data.system_pcap) && (G_master_pcap_data.system_pcap != 0)) { - TRAC_ERR("User PCAP %d is above the maximum allowed (%d)", - l_pcap, G_master_pcap_data.system_pcap); + TRAC_ERR("From source %d User PCAP %d is above the maximum allowed (%d)", + i_source, i_pcap, G_master_pcap_data.system_pcap); l_rc = ERRL_RC_INVALID_DATA; break; } else { - G_master_pcap_data.current_pcap = l_pcap; + G_master_pcap_data.current_pcap = i_pcap; //Indicate there is new PCAP data available G_master_pcap_data.pcap_data_count++; - - G_master_pcap_data.source = OUT_OF_BAND; // BMC/(H)TMGT + // if user pcap was just disabled set source to 0 (no user pcap) + if(i_pcap == 0) + { + G_master_pcap_data.source = 0; + } + else + { + G_master_pcap_data.source = i_source; + } } - TRAC_INFO("User selected power limit = %d", - G_master_pcap_data.current_pcap); + TRAC_INFO("User selected power limit = %d set from source %d", + G_master_pcap_data.current_pcap, i_source); } while (0); + return l_rc; +} + +// Function Specification +// +// Name: cmdh_set_user_pcap +// +// Description: Implements the Set Use Power Cap command from out of band interface +// +// End Function Specification +errlHndl_t cmdh_set_user_pcap(const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + errlHndl_t l_err = NULL; + ERRL_RC l_rc = ERRL_RC_SUCCESS; + + + G_rsp_status = ERRL_RC_SUCCESS; + o_rsp_ptr->data_length[0] = 0; + o_rsp_ptr->data_length[1] = 0; + + if (CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr) != CMDH_SET_USER_PCAP_DATALEN) + { + TRAC_ERR("cmdh_set_user_pcap: Invalid command length %u, expected %u ", + CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr), CMDH_SET_USER_PCAP_DATALEN); + l_rc = ERRL_RC_INVALID_CMD_LEN; + } + else + { + uint16_t l_pcap = CONVERT_UINT8_ARRAY_UINT16(i_cmd_ptr->data[0], + i_cmd_ptr->data[1]); + l_rc = cmdh_set_user_pcap_common(l_pcap, OUT_OF_BAND); + } if (ERRL_RC_SUCCESS != l_rc) { @@ -1901,3 +1929,255 @@ errlHndl_t cmdh_set_user_pcap(const cmdh_fsp_cmd_t * i_cmd_ptr, return l_err; } + +// Function Specification +// +// Name: cmdh_clear_sensor_data +// +// Description: Implements the Clear sensor data command +// +// End Function Specification +uint8_t cmdh_clear_sensor_data(const uint16_t i_cmd_data_length, + const uint8_t* i_cmd_data_ptr, + const uint16_t i_max_rsp_data_length, + uint16_t* o_rsp_data_length, + uint8_t* o_rsp_data_ptr) +{ + uint8_t l_rc = ERRL_RC_SUCCESS; + cmdh_clear_sensor_cmd_data_t *l_cmd_ptr = (cmdh_clear_sensor_cmd_data_t *) i_cmd_data_ptr; + cmdh_clear_sensor_rsp_data_t *l_rsp_ptr = (cmdh_clear_sensor_rsp_data_t*) o_rsp_data_ptr; + *o_rsp_data_length = 0; + + do + { + // Command Length Check + if( i_cmd_data_length != sizeof(cmdh_clear_sensor_cmd_data_t) ) + { + TRAC_ERR("cmdh_clear_sensor_data: Invalid command length %u, expected %u ", + i_cmd_data_length, sizeof(cmdh_clear_sensor_cmd_data_t)); + l_rc = ERRL_RC_INVALID_CMD_LEN; + break; + } + // Make sure there is enough room in response buffer + if( sizeof(cmdh_clear_sensor_rsp_data_t) > i_max_rsp_data_length ) + { + TRAC_ERR("cmdh_clear_sensor_data: Response size %u is larger than buffer size %u ", + sizeof(cmdh_clear_sensor_rsp_data_t), i_max_rsp_data_length); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + // Check that the owner(s) to clear sensors for are valid + if( (l_cmd_ptr->sensor_owner_id & ~(VALID_CLEAR_SENSOR_OWNER_MASK) ) || + (l_cmd_ptr->sensor_owner_id == 0) ) + { + TRAC_ERR("cmdh_clear_sensor_data: Invalid sensor owners = 0x%02X", + l_cmd_ptr->sensor_owner_id); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // clear min/max fields of all sensors for the given owner(s) + sensor_t *l_sensor_ptr = NULL; + uint16_t i = 0; + for( i = 0;i < G_amec_sensor_count; i++) + { + l_sensor_ptr = getSensorByGsid(i); + sensor_clear_minmax(l_sensor_ptr, l_cmd_ptr->sensor_owner_id); + } + + // copy the owner_id to the response buffer and set the rsp length + l_rsp_ptr->sensor_owner_id = l_cmd_ptr->sensor_owner_id; + *o_rsp_data_length = (uint16_t) sizeof(cmdh_clear_sensor_rsp_data_t); + TRAC_INFO("cmdh_clear_sensor_data: Sensor min/max cleared for owners = 0x%02X", + l_rsp_ptr->sensor_owner_id); + } while (0); + + return l_rc; +} + +// Function Specification +// +// Name: cmdh_set_pcap_inband +// +// Description: Implements setting a power cap from the inband interface +// +// End Function Specification +uint8_t cmdh_set_pcap_inband(const uint16_t i_cmd_data_length, + const uint8_t* i_cmd_data_ptr, + const uint16_t i_max_rsp_data_length, + uint16_t* o_rsp_data_length, + uint8_t* o_rsp_data_ptr) +{ + uint8_t l_rc = ERRL_RC_SUCCESS; + cmdh_set_inband_pcap_cmd_data_t *l_cmd_ptr = (cmdh_set_inband_pcap_cmd_data_t *) i_cmd_data_ptr; + cmdh_set_inband_pcap_rsp_data_t *l_rsp_ptr = (cmdh_set_inband_pcap_rsp_data_t*) o_rsp_data_ptr; + *o_rsp_data_length = 0; + + do + { + // Command Length Check + if( i_cmd_data_length != sizeof(cmdh_set_inband_pcap_cmd_data_t) ) + { + TRAC_ERR("cmdh_set_pcap_inband: Invalid command length %u, expected %u ", + i_cmd_data_length, sizeof(cmdh_set_inband_pcap_cmd_data_t)); + l_rc = ERRL_RC_INVALID_CMD_LEN; + break; + } + + // Make sure there is enough room in response buffer + if( sizeof(cmdh_set_inband_pcap_rsp_data_t) > i_max_rsp_data_length ) + { + TRAC_ERR("cmdh_set_pcap_inband: Response size %u is larger than buffer size %u ", + sizeof(cmdh_set_inband_pcap_rsp_data_t), i_max_rsp_data_length); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + + uint16_t l_pcap = CONVERT_UINT8_ARRAY_UINT16(l_cmd_ptr->power_cap[0], + l_cmd_ptr->power_cap[1]); + l_rc = cmdh_set_user_pcap_common(l_pcap, IN_BAND); + + // if successful copy the power cap to the response buffer and set the rsp length + if(l_rc == ERRL_RC_SUCCESS) + { + l_rsp_ptr->power_cap[0] = l_cmd_ptr->power_cap[0]; + l_rsp_ptr->power_cap[1] = l_cmd_ptr->power_cap[1]; + *o_rsp_data_length = (uint16_t) sizeof(cmdh_set_inband_pcap_rsp_data_t); + } + } while (0); + + return l_rc; +} + +// Function Specification +// +// Name: cmdh_write_psr +// +// Description: Implements the Write Power Shifting Ratio command +// +// End Function Specification +uint8_t cmdh_write_psr(const uint16_t i_cmd_data_length, + const uint8_t* i_cmd_data_ptr, + const uint16_t i_max_rsp_data_length, + uint16_t* o_rsp_data_length, + uint8_t* o_rsp_data_ptr) +{ + uint8_t l_rc = ERRL_RC_SUCCESS; + cmdh_write_psr_cmd_data_t *l_cmd_ptr = (cmdh_write_psr_cmd_data_t *) i_cmd_data_ptr; + cmdh_write_psr_rsp_data_t *l_rsp_ptr = (cmdh_write_psr_rsp_data_t*) o_rsp_data_ptr; + *o_rsp_data_length = 0; + + do + { + // Command Length Check + if( i_cmd_data_length != sizeof(cmdh_write_psr_cmd_data_t) ) + { + TRAC_ERR("cmdh_write_psr: Invalid command length %u, expected %u ", + i_cmd_data_length, sizeof(cmdh_write_psr_cmd_data_t)); + l_rc = ERRL_RC_INVALID_CMD_LEN; + break; + } + // Make sure there is enough room in response buffer + if( sizeof(cmdh_write_psr_rsp_data_t) > i_max_rsp_data_length ) + { + TRAC_ERR("cmdh_write_psr: Response size %u is larger than buffer size %u ", + sizeof(cmdh_write_psr_rsp_data_t), i_max_rsp_data_length); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + // Verify PSR is within range 0-100% + if(l_cmd_ptr->psr > 100) + { + TRAC_ERR("cmdh_write_psr: Invalid PSR %u", + l_cmd_ptr->psr); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // PSR is valid + TRAC_INFO("cmdh_write_psr: PSR changed from %u to %u", G_sysConfigData.psr, l_cmd_ptr->psr); + G_sysConfigData.psr = l_cmd_ptr->psr; + + // copy the PSR to the response buffer and set the rsp length + l_rsp_ptr->psr = l_cmd_ptr->psr; + *o_rsp_data_length = (uint16_t) sizeof(cmdh_write_psr_rsp_data_t); + } while (0); + + return l_rc; +} + +// Function Specification +// +// Name: cmdh_select_sensor_groups +// +// Description: Implements the Select sensor Groups command to select +// sensor types that will be copied to main memory +// +// End Function Specification +uint8_t cmdh_select_sensor_groups(const uint16_t i_cmd_data_length, + const uint8_t* i_cmd_data_ptr, + const uint16_t i_max_rsp_data_length, + uint16_t* o_rsp_data_length, + uint8_t* o_rsp_data_ptr) +{ + uint8_t l_rc = ERRL_RC_SUCCESS; + uint16_t l_sensor_groups = 0; + cmdh_select_sensor_groups_cmd_data_t *l_cmd_ptr = (cmdh_select_sensor_groups_cmd_data_t *) i_cmd_data_ptr; + cmdh_select_sensor_groups_rsp_data_t *l_rsp_ptr = (cmdh_select_sensor_groups_rsp_data_t*) o_rsp_data_ptr; + *o_rsp_data_length = 0; + do + { + // Command Length Check + if( i_cmd_data_length != sizeof(cmdh_select_sensor_groups_cmd_data_t) ) + { + TRAC_ERR("cmdh_select_sensor_groups: Invalid command length %u, expected %u ", + i_cmd_data_length, sizeof(cmdh_select_sensor_groups_cmd_data_t)); + l_rc = ERRL_RC_INVALID_CMD_LEN; + break; + } + // Make sure there is enough room in response buffer + if( sizeof(cmdh_select_sensor_groups_rsp_data_t) > i_max_rsp_data_length ) + { + TRAC_ERR("cmdh_select_sensor_groups: Response size %u is larger than buffer size %u ", + sizeof(cmdh_select_sensor_groups_rsp_data_t), i_max_rsp_data_length); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + // Check that the sensor group(s) to select are valid + // 0 is valid and means not to copy any sensors to main memory + l_sensor_groups = CONVERT_UINT8_ARRAY_UINT16(l_cmd_ptr->sensor_groups[0], + l_cmd_ptr->sensor_groups[1]); + if(l_sensor_groups & ~(VALID_SET_SENSOR_GROUPS_MASK)) + { + TRAC_ERR("cmdh_select_sensor_groups: Invalid sensor groups = 0x%04X", + l_sensor_groups); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // Loop thru 16 bits to check all possible sensor types + uint8_t l_bit = 0; + uint16_t l_sensor_type = 0; + bool l_enabled = false; + for(l_bit = 0; l_bit < 16; l_bit++) + { + l_sensor_type = 0x0001 << l_bit; + // only set eanbled for sensor types that are valid + if( l_sensor_type & (VALID_SET_SENSOR_GROUPS_MASK) ) + { + // type is valid now set enabled based on sensor groups selected + l_enabled = (l_sensor_groups & l_sensor_type) ? true : false; + main_mem_sensors_set_enabled(l_sensor_type, l_enabled); + } + } + + // copy the sensor groups to the response buffer and set the rsp length + l_rsp_ptr->sensor_groups[0] = l_cmd_ptr->sensor_groups[0]; + l_rsp_ptr->sensor_groups[1] = l_cmd_ptr->sensor_groups[1]; + *o_rsp_data_length = (uint16_t) sizeof(cmdh_select_sensor_groups_rsp_data_t); + TRAC_INFO("cmdh_select_sensor_groups: Sensor groups 0x%04X selected", + l_sensor_groups); + } while (0); + + return l_rc; +} |