diff options
author | Stephan Broyles <sbroyles@us.ibm.com> | 2014-11-05 19:09:37 -0600 |
---|---|---|
committer | Stephan Broyles <sbroyles@us.ibm.com> | 2014-11-05 19:22:32 -0600 |
commit | 9976c207cdb20871880bd2f4cf123cf4cb6a8b0f (patch) | |
tree | 1cf9ed8f23085e6fe3e0e6046fc30dcb7e02ccf2 /src/occ/cmdh/cmdh_mnfg_intf.c | |
parent | 2f8ce357b89d361b5091d88aea91416011b73ccb (diff) | |
download | talos-occ-9976c207cdb20871880bd2f4cf123cf4cb6a8b0f.tar.gz talos-occ-9976c207cdb20871880bd2f4cf123cf4cb6a8b0f.zip |
Added remaining occ files.
Change-Id: I91a748d3dcf3161a6a3eedcb376fcaf1e4dfe655
Diffstat (limited to 'src/occ/cmdh/cmdh_mnfg_intf.c')
-rwxr-xr-x | src/occ/cmdh/cmdh_mnfg_intf.c | 814 |
1 files changed, 814 insertions, 0 deletions
diff --git a/src/occ/cmdh/cmdh_mnfg_intf.c b/src/occ/cmdh/cmdh_mnfg_intf.c new file mode 100755 index 0000000..d475f4e --- /dev/null +++ b/src/occ/cmdh/cmdh_mnfg_intf.c @@ -0,0 +1,814 @@ +/****************************************************************************** +// @file cmdh_mnfg_intf.c +// @brief Command Handling for Manufacturing Interface. +*/ +/****************************************************************************** + * + * @page ChangeLogs Change Logs + * @section _cmdh_mnfg_intf_c cmdh_mnfg_intf.c + * @verbatim + * + * Flag Def/Fea Userid Date Description + * ------- ---------- -------- ---------- ---------------------------------- + * @gs004 gjsilva 05/15/2013 Created + * @gs005 883829 gjsilva 05/22/2013 Fix compilation issues + * @gm002 885429 milesg 05/30/2013 support for list/get sensors + * @gs006 884384 gjsilva 05/30/2013 Support for mnfg auto-slewing function + * @th040 887069 thallet 06/11/2013 Support Nom & FFO Freq Setting for Mnfg + * @th042 thallet 07/22/2013 Fix a bug where sensor name was corrupted + * @gm004 892961 milesg 07/25/2013 Support memory auto slewing + * @gm012 905097 milesg 10/31/2013 Fix centaur enablement + * @gm013 907548 milesg 11/22/2013 Memory therm monitoring support + * @gm016 909061 milesg 12/10/2013 Support memory throttling due to temperature + * @gm017 909636 milesg 12/17/2013 changes from mem throttle review + * + * @endverbatim + * + *///*************************************************************************/ + +//************************************************************************* +// Includes +//************************************************************************* +#include "cmdh_mnfg_intf.h" +#include "cmdh_service_codes.h" +#include "cmdh_fsp_cmds.h" +#include "dcom.h" +#include "amec_oversub.h" +#include "amec_sys.h" +#include "sensorQueryList.h" +#include "amec_smh.h" +#include "amec_master_smh.h" +#include "centaur_data.h" //gm004 +#include "centaur_control.h" //gm004 +//************************************************************************* +// Externs +//************************************************************************* +extern task_t G_task_table[TASK_END]; //gm004 +extern centaur_throttle_t G_centaurThrottleLimits[MAX_NUM_CENTAURS][NUM_MBAS_PER_CENTAUR]; +//************************************************************************* +// Defines/Enums +//************************************************************************* + +//************************************************************************* +// Globals +//************************************************************************* + +//************************************************************************* +// Function Declarations +//************************************************************************* + +//************************************************************************* +// Functions +//************************************************************************* + +// Function Specification +// +// Name: cmdh_mnfg_run_stop_slew +// +// Description: This function handles the manufacturing command to start +// or stop frequency autoslewing. +// +// +// Flow: xx/xx/xx FN= +// +// End Function Specification +uint8_t cmdh_mnfg_run_stop_slew(const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint8_t l_rc = ERRL_RC_SUCCESS; + uint16_t l_fmin = 0; + uint16_t l_fmax = 0; + uint16_t l_step_size = 0; + uint16_t l_step_delay = 0; + uint32_t l_temp = 0; + mnfg_run_stop_slew_cmd_t *l_cmd_ptr = (mnfg_run_stop_slew_cmd_t*) i_cmd_ptr; + mnfg_run_stop_slew_rsp_t *l_rsp_ptr = (mnfg_run_stop_slew_rsp_t*) o_rsp_ptr; + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + do + { + // This command is only supported on Master OCC + if (G_occ_role == OCC_SLAVE) + { + TRAC_ERR("cmdh_mnfg_run_stop_slew: Mnfg command not supported on Slave OCCs!"); + break; + } + + // Do some basic input verification + if ((l_cmd_ptr->action > MNFG_INTF_SLEW_STOP) || + (l_cmd_ptr->step_mode > MNFG_INTF_FULL_SLEW)) + { + // Invalid values were passed by the user! + TRAC_ERR("cmdh_mnfg_run_stop_slew: Invalid values were detected! action[0x%02x] step_mode[0x%02x]", + l_cmd_ptr->action, + l_cmd_ptr->step_mode); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // Are we stopping the auto-slew function? + if (l_cmd_ptr->action == MNFG_INTF_SLEW_STOP) + { + // Collect the slew count + l_rsp_ptr->slew_count = AMEC_MST_CUR_SLEW_COUNT(); + + // Collect the frequency range used for the auto-slew + l_rsp_ptr->fstart = AMEC_MST_CUR_MNFG_FMIN(); + l_rsp_ptr->fstop = AMEC_MST_CUR_MNFG_FMAX(); + + TRAC_INFO("cmdh_mnfg_run_stop_slew: Auto-slewing has been stopped. Count[%u] fstart[%u] fstop[%u]", + AMEC_MST_CUR_SLEW_COUNT(), + AMEC_MST_CUR_MNFG_FMIN(), + AMEC_MST_CUR_MNFG_FMAX()); + + // Send a signal to RTL to stop auto-slewing + AMEC_MST_STOP_AUTO_SLEW(); + + // We are done + break; + } + + // If we made it here, that means we are starting up a slew run + // First, determine the Fmax and Fmin for the slew run + if (l_cmd_ptr->bottom_mode == OCC_MODE_PWRSAVE) + { + // If bottom mode is Static Power Save, use the min frequency + // available + l_fmin = G_sysConfigData.sys_mode_freq.table[OCC_MODE_MIN_FREQUENCY]; + } + else + { + l_fmin = G_sysConfigData.sys_mode_freq.table[l_cmd_ptr->bottom_mode]; + } + l_fmax = G_sysConfigData.sys_mode_freq.table[l_cmd_ptr->high_mode]; + + // Add the percentages to compute the min/max frequencies + l_fmin = l_fmin + (l_fmin * l_cmd_ptr->bottom_percent)/100; + l_fmax = l_fmax + (l_fmax * l_cmd_ptr->high_percent)/100; + + TRAC_INFO("cmdh_mnfg_run_stop_slew: We are about to start auto-slewing function"); + TRAC_INFO("cmdh_mnfg_run_stop_slew: bottom_mode[0x%.2X] freq[%u] high_mode[0x%.2X] freq[%u]", + l_cmd_ptr->bottom_mode, + l_fmin, + l_cmd_ptr->high_mode, + l_fmax); + + // Determine the frequency step size and the step delay + if (l_cmd_ptr->step_mode == MNFG_INTF_FULL_SLEW) + { + l_step_size = l_fmax - l_fmin; + + // Disable step delays if full slew mode has been selected + l_step_delay = 0; + + TRAC_INFO("cmdh_mnfg_run_stop_slew: Enabling full-slew mode with step_size[%u] step_delay[%u]", + l_step_size, + l_step_delay); + } + else + { + l_step_size = 20; //TODO: Need to find out the step size from Pstate table + + // Translate the step delay to internal OCC ticks + l_temp = (l_cmd_ptr->step_delay * 1000) / AMEC_US_PER_TICK; + l_step_delay = (uint16_t) l_temp; + + TRAC_INFO("cmdh_mnfg_run_stop_slew: Enabling single-step mode with step_size[%u] step_delay[%u]", + l_step_size, + l_step_delay); + } + + // Now, load the values for RTL consumption + AMEC_MST_SET_MNFG_FMIN(l_fmin); + AMEC_MST_SET_MNFG_FMAX(l_fmax); + AMEC_MST_SET_MNFG_FSTEP(l_step_size); + AMEC_MST_SET_MNFG_DELAY(l_step_delay); + + // Reset the slew-counter before we start auto-slewing + AMEC_MST_CUR_SLEW_COUNT() = 0; + + // Wait a little bit for RTL to process above parameters + ssx_sleep(SSX_MILLISECONDS(5)); + + // Send a signal to RTL to start auto-slewing + AMEC_MST_START_AUTO_SLEW(); + + // We are auto-slewing now, populate the response packet + l_rsp_ptr->slew_count = 0; + l_rsp_ptr->fstart = l_fmin; + l_rsp_ptr->fstop = l_fmax; + + }while(0); + + // Populate the response data packet + l_rsp_ptr->rc = l_rc; + l_rsp_ptr->data_length[0] = 0; + l_rsp_ptr->data_length[1] = MNFG_INTF_RUN_STOP_SLEW_RSP_SIZE; + + return l_rc; +} + +// Function Specification +// +// Name: cmdh_mnfg_mem_slew +// +// Description: This function handles the manufacturing command to start +// or stop memory autoslewing. +// +// +// Flow: xx/xx/xx FN= +// +// End Function Specification +uint8_t cmdh_mnfg_mem_slew(const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint8_t l_rc = ERRL_RC_SUCCESS; + mnfg_mem_slew_cmd_t *l_cmd_ptr = (mnfg_mem_slew_cmd_t*) i_cmd_ptr; + mnfg_mem_slew_rsp_t *l_rsp_ptr = (mnfg_mem_slew_rsp_t*) o_rsp_ptr; + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + do + { + + // Do some basic input verification + if (l_cmd_ptr->action > MNFG_INTF_SLEW_STOP) + { + // Invalid values were passed by the user! + TRAC_ERR("cmdh_mnfg_mem_slew: Invalid value was detected! action[0x%02x]", + l_cmd_ptr->action); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // Are we stopping the auto-slew function? + if (l_cmd_ptr->action == MNFG_INTF_SLEW_STOP) + { + // Send a signal to RTL to stop auto-slewing + g_amec->mnfg_parms.mem_autoslew = FALSE; + + // Collect the slew count + if(g_amec->mnfg_parms.mem_slew_counter > 0x0000FFFF) + { + l_rsp_ptr->slew_count = 0xFFFF; + } + else + { + l_rsp_ptr->slew_count = g_amec->mnfg_parms.mem_slew_counter; + } + + // zero out the slew count; + g_amec->mnfg_parms.mem_slew_counter = 0; + + TRAC_INFO("cmdh_mnfg_mem_slew: Auto-slewing has been stopped. Count[%u]", + l_rsp_ptr->slew_count); + + // We are done + break; + } + + // If we made it here, that means we are starting up a slew run + TRAC_INFO("cmdh_mnfg_mem_slew: We are about to start auto-slewing function"); + + // force activation of memory monitoring and control + if(!rtl_task_is_runnable(TASK_ID_CENTAUR_CONTROL)) + { + uint32_t l_cent, l_mba; + + //only run initialization on an active OCC + if(!IS_OCC_STATE_ACTIVE()) + { + TRAC_ERR("cmdh_mnfg_mem_slew: OCC must be active to start mem slewing"); + l_rc = ERRL_RC_INVALID_STATE; + break; + } + + //Force all MBA's to be present + G_configured_mbas = -1; + + TRAC_INFO("cmdh_mnfg_mem_slew: calling centaur_init()"); + centaur_init(); //no rc, handles errors internally + + //check if centaur_init resulted in a reset + //since we don't have a return code from centaur_init. + if(isSafeStateRequested()) + { + TRAC_ERR("cmdh_mnfg_mem_slew: OCC is being reset"); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + + for(l_cent = 0; l_cent < MAX_NUM_CENTAURS; l_cent++) + { + if(!CENTAUR_PRESENT(l_cent)) + { + continue; + } + + for(l_mba = 0; l_mba < NUM_MBAS_PER_CENTAUR; l_mba++) + { + mem_throt_config_data_t * l_throt_ptr = + &G_sysConfigData.mem_throt_limits[l_cent][l_mba]; + + //Uses values seen on tuleta as defaults -- gm017 + l_throt_ptr->min_ot_n_per_mba = 13; + l_throt_ptr->nom_n_per_mba = 72; + l_throt_ptr->nom_n_per_chip = 72; + l_throt_ptr->turbo_n_per_mba = 72; + l_throt_ptr->turbo_n_per_chip = 72; + l_throt_ptr->ovs_n_per_mba = 72; + l_throt_ptr->ovs_n_per_chip = 72; + } + + } + + + //initialization was successful. + //Set task flags to allow centaur control task to run and + //also to prevent us from doing initialization again. + G_task_table[TASK_ID_CENTAUR_DATA].flags = CENTAUR_DATA_RTL_FLAGS; + G_task_table[TASK_ID_CENTAUR_CONTROL].flags = CENTAUR_CONTROL_RTL_FLAGS; + } + + // zero out the slew count + g_amec->mnfg_parms.mem_slew_counter = 0; + + // Send a signal to RTL to start memory auto-slewing + g_amec->mnfg_parms.mem_autoslew = TRUE; + + // We are auto-slewing now, populate the response packet + l_rsp_ptr->slew_count = 0; + + TRAC_INFO("cmdh_mnfg_mem_slew: memory slewing started."); + + }while(0); + + // Populate the response data packet + l_rsp_ptr->rc = l_rc; + l_rsp_ptr->data_length[0] = 0; + l_rsp_ptr->data_length[1] = MNFG_INTF_MEM_SLEW_RSP_SIZE; + + return l_rc; +} + + +// Function Specification +// +// Name: cmdh_mnfg_emulate_oversub +// +// Description: This function handles the manufacturing command to emulate +// oversubscription. +// +// +// Flow: xx/xx/xx FN= +// +// End Function Specification +uint8_t cmdh_mnfg_emulate_oversub(const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint8_t l_rc = 0; + mnfg_emul_oversub_cmd_t *l_cmd_ptr = (mnfg_emul_oversub_cmd_t*) i_cmd_ptr; + mnfg_emul_oversub_rsp_t *l_rsp_ptr = (mnfg_emul_oversub_rsp_t*) o_rsp_ptr; + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + do + { + // This command is only supported on Master OCC + if (G_occ_role == OCC_SLAVE) + { + TRAC_ERR("cmdh_mnfg_emulate_oversub: Mnfg command not supported on Slave OCCs!"); + break; + } + + switch (l_cmd_ptr->action) + { + case 0x00: + TRAC_INFO("cmdh_mnfg_emulate_oversub: Disable oversubscription emulation"); + AMEC_INTF_GET_OVERSUBSCRIPTION_EMULATION() = 0; + l_rsp_ptr->state = l_cmd_ptr->action; + break; + + case 0x01: + TRAC_INFO("cmdh_mnfg_emulate_oversub: Enable oversubscription emulation"); + AMEC_INTF_GET_OVERSUBSCRIPTION_EMULATION() = 1; + l_rsp_ptr->state = l_cmd_ptr->action; + break; + + case 0xFF: + TRAC_INFO("cmdh_mnfg_emulate_oversub: Query oversubscription emulation"); + l_rsp_ptr->state = AMEC_INTF_GET_OVERSUBSCRIPTION_EMULATION(); + break; + + default: + TRAC_INFO("cmdh_mnfg_emulate_oversub: Invalid oversubscription emulation action"); + l_rsp_ptr->state = AMEC_INTF_GET_OVERSUBSCRIPTION_EMULATION(); + break; + } + + }while(0); + + // Populate the response data packet + l_rsp_ptr->rc = ERRL_RC_SUCCESS; + l_rsp_ptr->data_length[0] = 0; + l_rsp_ptr->data_length[1] = 1; + + return l_rc; +} + +// Function Specification +// +// Name: cmdh_mnfg_list_sensors +// +// Description: Returns a list of selected sensors +// +// +// Flow: xx/xx/xx FN= +// +// End Function Specification +uint8_t cmdh_mnfg_list_sensors(const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint8_t l_rc = ERRL_RC_SUCCESS; + uint16_t l_type = 0; + uint16_t l_location = 0; + uint16_t l_start_gsid; + uint16_t i = 0; + uint16_t l_resp_data_length = 0; + uint16_t l_datalength; + uint16_t l_num_of_sensors = MFG_MAX_NUM_SENSORS + 1; + cmdh_mfg_list_sensors_query_t *l_cmd_ptr = + (cmdh_mfg_list_sensors_query_t*) i_cmd_ptr; + cmdh_mfg_list_sensors_resp_t *l_resp_ptr = + (cmdh_mfg_list_sensors_resp_t*) o_rsp_ptr; + sensorQueryList_t l_sensor_list[MFG_MAX_NUM_SENSORS + 1]; + errlHndl_t l_err = NULL; + OCC_APLT_STATUS_CODES l_status = 0; + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + do + { + // Do sanity check on the function inputs + if ((NULL == i_cmd_ptr) || (NULL == o_rsp_ptr)) + { + TRAC_ERR("cmdh_mnfg_list_sensors: invalid pointers. cmd[0x%08x] rsp[0x%08x]", + i_cmd_ptr, o_rsp_ptr); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + + // Check packet data length + l_datalength = CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr); + if(l_datalength < (sizeof(cmdh_mfg_list_sensors_query_t) - + sizeof(cmdh_fsp_cmd_header_t))) + { + TRAC_ERR("cmdh_mnfg_list_sensors: incorrect data length. exp[%d] act[%d]", + (sizeof(cmdh_mfg_list_sensors_query_t) - + sizeof(cmdh_fsp_cmd_header_t)), + l_datalength); + l_rc = ERRL_RC_INVALID_CMD_LEN; + break; + } + + // Check version + if(l_cmd_ptr->version != MFG_LIST_SENSOR_VERSION) + { + TRAC_ERR("cmdh_mnfg_list_sensors: incorrect version. exp[%d] act[%d]", + MFG_LIST_SENSOR_VERSION, + l_cmd_ptr->version); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // Capture user inputs + l_type = l_cmd_ptr->type; + l_location = l_cmd_ptr->location; + l_start_gsid = l_cmd_ptr->start_gsid; + + TRAC_INFO("cmdh_mnfg_list_sensors: Type[0x%04x] Location[0x%04x]", + l_type, + l_location); + + // Initialize the Applet arguments + querySensorListAppletArg_t l_applet_arg = + { + l_start_gsid, // i_startGsid - passed by the caller + l_cmd_ptr->present, // i_present - passed by the caller + l_type, // i_type - passed by the caller + l_location, // i_loc - passed by the caller + &l_num_of_sensors, // io_numOfSensors + l_sensor_list, // o_sensors + NULL // o_sensorInfoPtr - not needed + }; + + // Call the sensor query list applet + runApplet(OCC_APLT_SNSR_QUERY, + &l_applet_arg, + TRUE, + NULL, + &l_err, + &l_status); + + if (NULL != l_err) + { + // Query failure + TRAC_ERR("cmdh_mnfg_list_sensors: Failed to run OCC_APLT_SNSR_QUERY applet. Error status is: 0x%x", + l_status); + + // Commit error log + commitErrl(&l_err); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + else + { + TRAC_INFO("cmdh_mnfg_list_sensors: Numbers of sensors found[%u]", + l_num_of_sensors); + + if (l_num_of_sensors > MFG_MAX_NUM_SENSORS) + { + // Got too many sensors back, need to truncate the list + TRAC_INFO("cmdh_mnfg_list_sensors: Got too many sensors back[%u]. Truncating number of sensors to %u", + l_num_of_sensors, + MFG_MAX_NUM_SENSORS); + + l_num_of_sensors = MFG_MAX_NUM_SENSORS; + l_resp_ptr->truncated = 1; + } + else + { + l_resp_ptr->truncated = 0; + } + + // Clear out the sensor fields - @th042 + memset((void*) &(l_resp_ptr->sensor[0]), 0, (sizeof(cmdh_dbug_sensor_list_t)*l_num_of_sensors) ); + + // Populate the response data packet + l_resp_ptr->num_sensors = l_num_of_sensors; + for (i=0; i<l_num_of_sensors; i++) + { + l_resp_ptr->sensor[i].gsid = l_sensor_list[i].gsid; + l_resp_ptr->sensor[i].sample = l_sensor_list[i].sample; + strcpy(l_resp_ptr->sensor[i].name, l_sensor_list[i].name); + } + } + + }while(0); + + // Populate the response data header + l_resp_data_length = 2 + l_num_of_sensors * sizeof(cmdh_mfg_sensor_rec_t); + o_rsp_ptr->rc = l_rc; + o_rsp_ptr->data_length[0] = ((uint8_t *)&l_resp_data_length)[0]; + o_rsp_ptr->data_length[1] = ((uint8_t *)&l_resp_data_length)[1]; + + return l_rc; +} + + +// Function Specification +// +// Name: cmdh_mnfg_get_sensor +// +// Description: Returns a list of selected sensors +// +// +// Flow: xx/xx/xx FN= +// +// End Function Specification +uint8_t cmdh_mnfg_get_sensor(const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint8_t l_rc = ERRL_RC_SUCCESS; + uint16_t l_gsid; + uint16_t l_resp_data_length = 0; + uint16_t l_datalength; + uint16_t l_num_of_sensors = 1; + cmdh_mfg_get_sensor_query_t *l_cmd_ptr = + (cmdh_mfg_get_sensor_query_t*) i_cmd_ptr; + cmdh_mfg_get_sensor_resp_t *l_resp_ptr = + (cmdh_mfg_get_sensor_resp_t*) o_rsp_ptr; + sensor_info_t l_sensor_info; + errlHndl_t l_err = NULL; + OCC_APLT_STATUS_CODES l_status = 0; + sensor_t* l_sensor_ptr; + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + do + { + // Do sanity check on the function inputs + if ((NULL == i_cmd_ptr) || (NULL == o_rsp_ptr)) + { + TRAC_ERR("cmdh_mnfg_get_sensor: invalid pointers. cmd[0x%08x] rsp[0x%08x]", + i_cmd_ptr, o_rsp_ptr); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + + // Check packet data length + l_datalength = CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr); + if(l_datalength < (sizeof(cmdh_mfg_get_sensor_query_t) - + sizeof(cmdh_fsp_cmd_header_t))) + { + TRAC_ERR("cmdh_mnfg_get_sensor: incorrect data length. exp[%d] act[%d]", + (sizeof(cmdh_mfg_get_sensor_query_t) - + sizeof(cmdh_fsp_cmd_header_t)), + l_datalength); + l_rc = ERRL_RC_INVALID_CMD_LEN; + break; + } + + // Check version + if(l_cmd_ptr->version != MFG_LIST_SENSOR_VERSION) + { + TRAC_ERR("cmdh_mnfg_get_sensor: incorrect version. exp[%d] act[%d]", + MFG_GET_SENSOR_VERSION, + l_cmd_ptr->version); + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // Capture user inputs + l_gsid = l_cmd_ptr->gsid; + + TRAC_INFO("cmdh_mnfg_get_sensor: gsid[0x%04x]", l_gsid); + + // Initialize the Applet arguments + querySensorListAppletArg_t l_applet_arg = + { + l_gsid, // i_startGsid - passed by the caller + 0, // i_present - passed by the caller + AMEC_SENSOR_TYPE_ALL, // i_type + AMEC_SENSOR_LOC_ALL, // i_loc + &l_num_of_sensors, // io_numOfSensors + NULL, // o_sensors - not needed + &l_sensor_info // o_sensorInfoPtr + }; + + // Call the sensor query list applet + runApplet(OCC_APLT_SNSR_QUERY, + &l_applet_arg, + TRUE, + NULL, + &l_err, + &l_status); + + if (NULL != l_err) + { + // Query failure + TRAC_ERR("cmdh_mnfg_get_sensor: Failed to run OCC_APLT_SNSR_QUERY applet. Error status is: 0x%x", + l_status); + + // Commit error log + commitErrl(&l_err); + l_rc = ERRL_RC_INTERNAL_FAIL; + break; + } + else + { + l_resp_ptr->gsid = l_gsid; + + // some of the response comes from the sensor + l_sensor_ptr = getSensorByGsid(l_gsid); + if (l_sensor_ptr == NULL) + { + TRAC_INFO("cmdh_mnfg_get_sensor: Didn't find sensor with gsid[0x%.4X]. Min/Max values won't be accurate.", + l_gsid); + l_resp_ptr->sample = 0; + l_resp_ptr->min = 0xFFFF; + l_resp_ptr->max = 0; + l_resp_ptr->accumulator = 0; + l_resp_ptr->status = 0; + } + else + { + l_resp_ptr->sample = l_sensor_ptr->sample; + l_resp_ptr->min = l_sensor_ptr->sample_min; + l_resp_ptr->max = l_sensor_ptr->sample_max; + l_resp_ptr->accumulator = l_sensor_ptr->accumulator; + l_resp_ptr->status = *(uint8_t*)(&l_sensor_ptr->status); + } + + //the rest of the response comes from the sensor info + memcpy(l_resp_ptr->name, l_sensor_info.name, sizeof(l_resp_ptr->name)); + memcpy(l_resp_ptr->units, l_sensor_info.sensor.units, sizeof(l_resp_ptr->units)); + l_resp_ptr->freq = l_sensor_info.sensor.freq; + l_resp_ptr->scalefactor = l_sensor_info.sensor.scalefactor; + l_resp_ptr->location = l_sensor_info.sensor.location; + l_resp_ptr->type = l_sensor_info.sensor.type; + } + + }while(0); + + // Populate the response data header + l_resp_data_length = sizeof(cmdh_mfg_get_sensor_resp_t) - + sizeof(cmdh_fsp_rsp_header_t); + o_rsp_ptr->rc = l_rc; + o_rsp_ptr->data_length[0] = ((uint8_t *)&l_resp_data_length)[0]; + o_rsp_ptr->data_length[1] = ((uint8_t *)&l_resp_data_length)[1]; + + return l_rc; +} + +// Function Specification +// +// Name: cmdh_mnfg_test_parse +// +// Description: This function parses the manufacturing commands sent via TMGT. +// +// +// +// Flow: xx/xx/xx FN= +// +// End Function Specification +void cmdh_mnfg_test_parse (const cmdh_fsp_cmd_t * i_cmd_ptr, + cmdh_fsp_rsp_t * o_rsp_ptr) +{ + /*------------------------------------------------------------------------*/ + /* Local Variables */ + /*------------------------------------------------------------------------*/ + uint8_t l_rc = 0; + uint8_t l_sub_cmd = 0; + errlHndl_t l_errl = NULL; + + /*------------------------------------------------------------------------*/ + /* Code */ + /*------------------------------------------------------------------------*/ + + // Sub-command is always first byte of data + l_sub_cmd = i_cmd_ptr->data[0]; + + TRAC_INFO("cmdh_mnfg_test_parse: Mnfg sub-command [0x%02x]", l_sub_cmd); + + switch (l_sub_cmd) + { + case MNFG_RUN_STOP_SLEW: + l_rc = cmdh_mnfg_run_stop_slew(i_cmd_ptr, o_rsp_ptr); + break; + + case MNFG_OVERSUB_EMULATION: + l_rc = cmdh_mnfg_emulate_oversub(i_cmd_ptr, o_rsp_ptr); + break; + + case MNFG_LIST_SENSORS: + l_rc = cmdh_mnfg_list_sensors(i_cmd_ptr, o_rsp_ptr); + break; + + case MNFG_GET_SENSOR: + l_rc = cmdh_mnfg_get_sensor(i_cmd_ptr, o_rsp_ptr); + break; + + case MNFG_MEMORY_SLEW: + l_rc = cmdh_mnfg_mem_slew(i_cmd_ptr, o_rsp_ptr); + break; + + case MNFG_RETRIEVE_EAR: + case MNFG_SET_FMINMAX: + case MNFG_FAILSAFE_EMULATION: + case MNFG_CPM_STRESS_CALI: + case MNFG_UV_CONTROL: + case MNFG_FCHECK_CONTROL: + default: + // Should never get here... + l_rc = ERRL_RC_INVALID_DATA; + break; + } + + // All errors in MNFG logged internally + if (l_rc) + { + TRAC_ERR("Mfg command 0x%02x failed with rc = %d", l_sub_cmd, l_rc); + // Build Error Response packet + cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, l_rc, &l_errl); + } + + return; +} + |