diff options
author | Chris Cain <cjcain@us.ibm.com> | 2015-11-19 12:27:03 -0600 |
---|---|---|
committer | William A. Bryan <wilbryan@us.ibm.com> | 2016-01-27 16:27:07 -0600 |
commit | 1cdc7f74cf7303b2d2e7e172b0e269928def09de (patch) | |
tree | bc88add88943f8389626a04c5219d0efc3d08f17 /src/occ_405 | |
parent | 476a284b52f50c1d0f5a8fc637cc28a22c714185 (diff) | |
download | talos-occ-1cdc7f74cf7303b2d2e7e172b0e269928def09de.tar.gz talos-occ-1cdc7f74cf7303b2d2e7e172b0e269928def09de.zip |
Implement code to read DIMM temperatures
Change-Id: I98fc83ab1c78bd40241fe6e47a9ddeae24f78c38
RTC: 140093
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/22770
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Tested-by: FSP CI Jenkins
Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Reviewed-by: Christopher Cain <cjcain@us.ibm.com>
Diffstat (limited to 'src/occ_405')
-rwxr-xr-x | src/occ_405/Makefile | 1 | ||||
-rwxr-xr-x | src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c | 48 | ||||
-rwxr-xr-x | src/occ_405/cmdh/cmdh_mnfg_intf.c | 3 | ||||
-rwxr-xr-x | src/occ_405/dimm/dimm.c | 749 | ||||
-rw-r--r-- | src/occ_405/dimm/dimm.h | 69 | ||||
-rwxr-xr-x | src/occ_405/dimm/dimm_service_codes.h | 40 | ||||
-rw-r--r-- | src/occ_405/img_defs.mk | 11 | ||||
-rwxr-xr-x | src/occ_405/incl/comp_ids.h | 4 | ||||
-rwxr-xr-x | src/occ_405/main.c | 1 | ||||
-rw-r--r-- | src/occ_405/occLinkInputFile | 1 | ||||
-rw-r--r-- | src/occ_405/occ_service_codes.h | 7 | ||||
-rwxr-xr-x | src/occ_405/occ_sys_config.c | 7 | ||||
-rwxr-xr-x | src/occ_405/occ_sys_config.h | 7 | ||||
-rwxr-xr-x | src/occ_405/rtls/rtls.h | 14 | ||||
-rwxr-xr-x | src/occ_405/rtls/rtls_tables.c | 27 | ||||
-rwxr-xr-x | src/occ_405/state.c | 32 | ||||
-rw-r--r-- | src/occ_405/topfiles.mk | 1 | ||||
-rwxr-xr-x | src/occ_405/trac/trac.h | 12 |
18 files changed, 960 insertions, 74 deletions
diff --git a/src/occ_405/Makefile b/src/occ_405/Makefile index 633b9d1..caae6f7 100755 --- a/src/occ_405/Makefile +++ b/src/occ_405/Makefile @@ -54,6 +54,7 @@ LIB_DIRS = -L$(OBJDIR) \ -L$(OBJDIR)/ppc405lib \ -L$(OBJDIR)/cmdh \ -L$(OBJDIR)/dcom \ + -L$(OBJDIR)/dimm \ -L$(OBJDIR)/errl \ -L$(OBJDIR)/pss \ -L$(OBJDIR)/rtls \ diff --git a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c index 2abebc0..b2ac116 100755 --- a/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c +++ b/src/occ_405/cmdh/cmdh_fsp_cmds_datacnfg.c @@ -957,7 +957,7 @@ errlHndl_t data_store_apss_config(const cmdh_fsp_cmd_t * i_cmd_ptr, * @userdata4 OCC_NO_EXTENDED_RC * @devdesc OCC recieved an invalid data packet from the FSP */ - cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); + cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); } else // Version 0x20 { @@ -1483,7 +1483,6 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, uint8_t l_i2c_port; uint8_t l_i2c_addr = 0; uint8_t l_dimm_num = 0; - uint8_t l_centaur_num = 0; int i; do @@ -1511,7 +1510,7 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, // Store the memory type. Memory must all be the same type, save from first and verify remaining G_sysConfigData.mem_type = l_cmd_ptr->data_set[0].memory_type; - if(G_sysConfigData.mem_type == 0xFF) // TODO change to MEM_TYPE_NIMBUS + if(G_sysConfigData.mem_type == MEM_TYPE_NIMBUS) { // Nimbus type -- dimm_info1 is I2C engine which must be the same // save from first entry and verify remaining @@ -1519,8 +1518,28 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, } else { - // Must be cumulus type - G_sysConfigData.mem_type = 0; // TODO change to MEM_TYPE_CUMULUS + // TODO - CUMULUS not supported yet + //G_sysConfigData.mem_type = MEM_TYPE_CUMULUS; + + CMDH_TRAC_ERR("data_store_mem_cfg: Invalid mem type 0x%02X in config data packet version[0x%02X] num_data_sets[%u]", + l_cmd_ptr->data_set[0].memory_type, + l_cmd_ptr->header.version, + l_cmd_ptr->header.num_data_sets); + + cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); + break; + } + + // Clear all sensor IDs (hw and temperature) + memset(G_sysConfigData.dimm_huids, 0, sizeof(G_sysConfigData.dimm_huids)); + int memctl, dimm; + for(memctl=0; memctl < MAX_NUM_MEM_CONTROLLERS; ++memctl) + { + g_amec->proc[0].memctl[memctl].centaur.temp_sid = 0; + for(dimm=0; dimm < NUM_DIMMS_PER_CENTAUR; ++dimm) + { + g_amec->proc[0].memctl[memctl].centaur.dimm_temps[dimm].temp_sid = 0; + } } // Store the hardware sensor ID and the temperature sensor ID @@ -1531,7 +1550,7 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, // Verify matching memory type and process based on memory type if( (l_data_set->memory_type == G_sysConfigData.mem_type) && - (l_data_set->memory_type == 0xFF) ) // TODO change to MEM_TYPE_NIMBUS + (l_data_set->memory_type == MEM_TYPE_NIMBUS) ) { // Nimbus type: dimm info is I2C Engine, I2C Port, I2C Address l_i2c_engine = l_data_set->dimm_info1; @@ -1577,7 +1596,7 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, // The location of the HW sensor ID in the 2D dimm_huids array is used to know i2c port // and i2c address for reading the DIMM. "centaur num" index is port "dimm num" is // translated from i2c address, we already verified the i2c addr is 0x3z above - l_dimm_num = (l_i2c_addr & 0x0F) >> 1; + l_dimm_num = (l_i2c_addr & 0x0F) >> 1; // Store the hardware sensor ID G_sysConfigData.dimm_huids[l_i2c_port][l_dimm_num] = l_data_set->hw_sensor_id; @@ -1591,8 +1610,16 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, } else // must be cumulus and the "memory type" byte is the centaur# { + CMDH_TRAC_ERR("data_store_mem_cfg: Invalid mem type 0x%02X in config data packet entry %d (entry 0 type: 0x%02X)", + l_data_set->memory_type, i, G_sysConfigData.mem_type); + + cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, ERRL_RC_INVALID_DATA, &l_err); + break; + +#if 0 + // TODO - CUMULUS not supported yet // per spec for cumulus memory type is the centaur# and dimm info1 is DIMM# - l_centaur_num = l_data_set->memory_type; + uint8_t l_centaur_num = l_data_set->memory_type; l_dimm_num = l_data_set->dimm_info1; // Validate the centaur and dimm #'s for this data set @@ -1629,6 +1656,7 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, l_num_dimms++; } +#endif } // Cumulus } // for each data set } // version 0x20 @@ -1645,8 +1673,8 @@ errlHndl_t data_store_mem_cfg(const cmdh_fsp_cmd_t * i_cmd_ptr, { // If there were no errors, indicate that we got this data G_data_cnfg->data_mask |= DATA_MASK_MEM_CFG; - CMDH_TRAC_IMP("data_store_mem_cfg: Got valid mem cfg packet. cent#=%d, dimm#=%d", - l_num_centaurs, l_num_dimms); + CMDH_TRAC_IMP("data_store_mem_cfg: Got valid mem cfg packet. type=0x%02X, #cent=%d, #dimm=%d", + G_sysConfigData.mem_type, l_num_centaurs, l_num_dimms); // No errors so we can enable memory monitoring if the data indicates it should be enabled if(l_cmd_ptr->header.num_data_sets == 0) // num data sets of 0 indicates memory monitoring disabled diff --git a/src/occ_405/cmdh/cmdh_mnfg_intf.c b/src/occ_405/cmdh/cmdh_mnfg_intf.c index a952f1b..8fd8feb 100755 --- a/src/occ_405/cmdh/cmdh_mnfg_intf.c +++ b/src/occ_405/cmdh/cmdh_mnfg_intf.c @@ -238,7 +238,8 @@ uint8_t cmdh_mnfg_mem_slew(const cmdh_fsp_cmd_t * i_cmd_ptr, // 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"); -// TEMP -- NOT SUPPORTED YET IN PHASE1 +// TEMP -- NOT SUPPORTED YET IN PHASE1 +// when implementing see dimm/dimm.c - memory_init() /* // Force activation of memory monitoring and control if(!rtl_task_is_runnable(TASK_ID_CENTAUR_CONTROL)) diff --git a/src/occ_405/dimm/dimm.c b/src/occ_405/dimm/dimm.c new file mode 100755 index 0000000..3008979 --- /dev/null +++ b/src/occ_405/dimm/dimm.c @@ -0,0 +1,749 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/occ_405/dimm/dimm.c $ */ +/* */ +/* OpenPOWER OnChipController Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +//#define DIMM_DEBUG + +#include <ssx.h> +#include <occhw_async.h> +#include <gpe_export.h> + +#include <trac_interface.h> +#include <trac.h> +#include <occ_common.h> +#include <comp_ids.h> +#include <occ_service_codes.h> +#include <dimm.h> +#include <dimm_service_codes.h> +#include <state.h> +#include <occ_sys_config.h> +#include "sensor.h" +#include "amec_sys.h" + + +extern bool G_mem_monitoring_allowed; +extern task_t G_task_table[TASK_END]; + +uint8_t G_dimm_state = DIMM_STATE_INIT; // Curret state of DIMM state machine +uint8_t G_maxDimmPorts = NUM_DIMM_PORTS; + +bool G_dimm_i2c_reset_required = false; +uint32_t G_dimm_i2c_reset_cause = 0; + +#define MAX_CONSECUTIVE_DIMM_RESETS 1 +typedef struct { + bool disabled; + uint8_t errorCount; + uint64_t lastReading; +} dimmData_t; +dimmData_t G_dimm[NUM_DIMM_PORTS][NUM_DIMMS_PER_CENTAUR] = {{{false,0}}}; + +#define DIMM_TICK (CURRENT_TICK % MAX_NUM_TICKS) + +// If still no i2c interrupt after MAX_TICK_COUNT_WAIT, then try next operation anyway +#define MAX_TICK_COUNT_WAIT 2 + +#define DIMM_AND_PORT ((G_dimm_sm_args.i2cPort<<8) | G_dimm_sm_args.dimm) +// GPE Requests +GpeRequest G_dimm_sm_request; +// GPE arguments +GPE_BUFFER(dimm_sm_args_t G_dimm_sm_args); + + +// Read OCC_MISC register to see if an I2C interrupt was generated for +// the specified engine. +bool check_for_i2c_interrupt(const uint8_t i_engine) +{ + bool l_interruptTriggered = false; + ocb_occmisc_t occmisc; + occmisc.value = in32(OCB_OCCMISC); + + // I2CM_INTR_STATUS has a one bit status for each engine: C, D, and E + if (PIB_I2C_ENGINE_E == i_engine) + { + // Engine E + l_interruptTriggered = occmisc.fields.i2cm_intr_status & 0x01; + } + else if (PIB_I2C_ENGINE_D == i_engine) + { + // Engine D + l_interruptTriggered = occmisc.fields.i2cm_intr_status & 0x02; + } + else if (PIB_I2C_ENGINE_C == i_engine) + { + // Engine C + l_interruptTriggered = occmisc.fields.i2cm_intr_status & 0x04; + } + else + { + // Invalid engine + DIMM_DBG("check_for_i2c_interrupt: invalid engine 0x%02X", i_engine); + } + + if (!l_interruptTriggered) + { + DIMM_DBG("check_for_i2c_interrupt: no interrupt for engine 0x%02X", i_engine); + } + + return l_interruptTriggered; + +} // end check_for_i2c_interrupt() + + +// Determine the I2C address for specified DIMM +uint8_t get_dimm_addr(uint8_t i_dimm) +{ + //if (MEMORY_TYPE_NIMBUS == G_sysConfigData.mem_type) + return 0x30 | (i_dimm<<1); +} + + +// Initialize the memory task data +void memory_init() +{ + if(G_mem_monitoring_allowed) + { + // Check if memory task is running (default task is for NIMBUS) + const task_id_t mem_task = TASK_ID_DIMM_SM; + if(!rtl_task_is_runnable(mem_task)) + { + if (MEM_TYPE_NIMBUS == G_sysConfigData.mem_type) + { + // Init DIMM state manager IPC request + memory_nimbus_init(); + } + else + { + // TODO CUMULUS NOT SUPPORTED YET IN PHASE1 +#if 0 + TRAC_INFO("memory_init: calling centaur_init()"); + centaur_init(); //no rc, handles errors internally +#endif + TRAC_ERR("memory_init: invalid memory type 0x%02X", G_sysConfigData.mem_type); + /* + * @errortype + * @moduleid DIMM_MID_MEMORY_INIT + * @reasoncode MEMORY_INIT_FAILED + * @userdata1 memory type + * @userdata2 0 + * @devdesc Invalid memory type detected + */ + errlHndl_t err = createErrl(DIMM_MID_MEMORY_INIT, + MEMORY_INIT_FAILED, + OCC_NO_EXTENDED_RC, + ERRL_SEV_PREDICTIVE, + NULL, + DEFAULT_TRACE_SIZE, + G_sysConfigData.mem_type, + 0); + REQUEST_RESET(err); + } + + // check if the init resulted in a reset + if(isSafeStateRequested()) + { + TRAC_ERR("memory_init: OCC is being reset, memory init failed (type=0x%02X)", + G_sysConfigData.mem_type); + } + else + { + // Initialization was successful. Set task flags to allow memory + // tasks to run and also prevent from doing initialization again. + G_task_table[mem_task].flags = MEMORY_DATA_RTL_FLAGS; + //G_task_table[TASK_ID_CENTAUR_CONTROL].flags = MEMORY_CONTROL_RTL_FLAGS; + } + } + } + +} // end memory_init() + + +// Create DIMM state machine IPC request +void memory_nimbus_init() +{ + DIMM_DBG("memory_nimbus_init: Creating request GPE1 DIMM request objects"); + gpe_request_create(&G_dimm_sm_request, + &G_async_gpe_queue1, // queue + IPC_ST_DIMM_SM_FUNCID, // entry_point + &G_dimm_sm_args, // entry_point arg + SSX_WAIT_FOREVER, // no timeout + NULL, // callback + NULL, // callback arg + ASYNC_CALLBACK_IMMEDIATE); // options +} + + +// Scan all of the DIMM temps and keep track of the hottest +void update_hottest_dimm() +{ + // Find/save the hottest DIMM temperature for the last set of readings + uint8_t hottest = 0, hottest_loc = 0; + int pIndex, dIndex; + for (pIndex = 0; pIndex < G_maxDimmPorts; ++pIndex) + { + for (dIndex = 0; dIndex < NUM_DIMMS_PER_CENTAUR; ++dIndex) + { + if (g_amec->proc[0].memctl[pIndex].centaur.dimm_temps[dIndex].cur_temp > hottest) + { + hottest = g_amec->proc[0].memctl[pIndex].centaur.dimm_temps[dIndex].cur_temp; + hottest_loc = (pIndex*8) + dIndex; + } + } + } + + DIMM_DBG("update_hottest_dimm: hottest DIMM temp for this sample: %dC (loc=%d)", hottest, hottest_loc); + if(hottest > g_amec->proc[0].memctl[0].centaur.tempdimmax.sample_max) + { + // Save hottest DIMM location ever sampled + DIMM_DBG("update_hottest_dimm: Hottest DIMM ever sampled was DIMM%d %dC (prior %dC)", + hottest_loc, hottest, g_amec->proc[0].memctl[0].centaur.tempdimmax.sample_max); + sensor_update(&g_amec->proc[0].memctl[0].centaur.locdimmax, hottest_loc); + } + // Nimbus has no Centaurs, but store hottest temp in memctl[0] + sensor_update(&g_amec->proc[0].memctl[0].centaur.tempdimmax, hottest); +} + + +// Update current I2C port/DIMM index to next potential DIMM +void use_next_dimm(uint8_t * i_port, uint8_t * i_dimm) +{ + if (++*i_dimm == NUM_DIMMS_PER_CENTAUR) + { + // Finished all DIMMs for current port, switch to new port + *i_port = 1 - *i_port; + *i_dimm = 0; + } + + // Check if we are starting a new set of readings and if so, update hottest DIMM + if ((*i_port == 0) && (*i_dimm == 0)) + { + update_hottest_dimm(); + } +} + + +// Called after a failure to read a DIMM temperature. The error will +// be counted and if threshold is reached, and error will be created with +// the DIMM as a callout and then set flag to trigger I2C reset +void mark_dimm_failed() +{ + const uint8_t port = G_dimm_sm_args.i2cPort; + const uint8_t dimm = G_dimm_sm_args.dimm; + INTR_TRAC_ERR("mark_dimm_failed: DIMM%04X failed in state %d with rc=0x%02X " + "(ffdc 0x%08X%08X, err_count=%d, completion_state 0x%02X)", + DIMM_AND_PORT, G_dimm_sm_args.state, + G_dimm_sm_args.error.rc, + WORD_HIGH(G_dimm_sm_args.error.ffdc), + WORD_LOW(G_dimm_sm_args.error.ffdc), + G_dimm[port][dimm].errorCount, + G_dimm_sm_request.request.completion_state); + + if (++G_dimm[port][dimm].errorCount > MAX_CONSECUTIVE_DIMM_RESETS) + { + // Disable collection on this DIMM, collect FFDC and log error + G_dimm[port][dimm].disabled = true; + INTR_TRAC_ERR("mark_dimm_failed: disabling DIMM%04X due to %d consecutive errors (state=%d)", + DIMM_AND_PORT, G_dimm[port][dimm].errorCount, G_dimm_sm_args.state); + errlHndl_t l_err = NULL; + /* + * @errortype + * @moduleid DIMM_MID_MARK_DIMM_FAILED + * @reasoncode DIMM_GPE_FAILURE + * @userdata1 GPE returned rc code + * @userdata4 ERC_DIMM_COMPLETE_FAILURE + * @devdesc Failure writing dimm i2c mode register + */ + l_err = createErrl(DIMM_MID_MARK_DIMM_FAILED, + DIMM_GPE_FAILURE, + ERC_DIMM_COMPLETE_FAILURE, + ERRL_SEV_INFORMATIONAL, + NULL, + DEFAULT_TRACE_SIZE, + G_dimm_sm_args.error.rc, + 0); + addUsrDtlsToErrl(l_err, + (uint8_t*)&G_dimm_sm_request.ffdc, + sizeof(G_dimm_sm_request.ffdc), + ERRL_STRUCT_VERSION_1, + ERRL_USR_DTL_BINARY_DATA); + addCalloutToErrl(l_err, + ERRL_CALLOUT_TYPE_HUID, + G_sysConfigData.dimm_huids[port][dimm], + ERRL_CALLOUT_PRIORITY_HIGH); + commitErrl(&l_err); + } + + // Reset DIMM I2C engine + G_dimm_i2c_reset_required = true; + G_dimm_i2c_reset_cause = port<<24 | dimm<<16 | (G_dimm_sm_args.error.rc & 0xFFFF); + G_dimm_state = DIMM_STATE_RESET_MASTER; + +} // end mark_dimm_failed() + + +// Schedule a GPE request for the specified DIMM state +bool schedule_dimm_req(uint8_t i_state) +{ + bool l_scheduled = false; + bool scheduleRequest = true; + + DIMM_DBG("dimm_sm called with state 0x%02X (tick=%d)", i_state, DIMM_TICK); + + if (!async_request_is_idle(&G_dimm_sm_request.request)) + { + INTR_TRAC_ERR("dimm_sm: request is not idle."); + } + else + { + switch(i_state) + { + // Init + case DIMM_STATE_INIT: + break; + + // Read DIMM temp + case DIMM_STATE_WRITE_MODE: + case DIMM_STATE_WRITE_ADDR: + case DIMM_STATE_INITIATE_READ: + case DIMM_STATE_READ_TEMP: + break; + + // I2C reset + case DIMM_STATE_RESET_MASTER: + case DIMM_STATE_RESET_SLAVE_P0: + case DIMM_STATE_RESET_SLAVE_P0_COMPLETE: + case DIMM_STATE_RESET_SLAVE_P1: + case DIMM_STATE_RESET_SLAVE_P1_COMPLETE: + break; + + default: + INTR_TRAC_ERR("dimm_sm: Invalid state (0x%02X)", i_state); + errlHndl_t err = NULL; + /* + * @errortype + * @moduleid DIMM_MID_DIMM_SM + * @reasoncode DIMM_INVALID_STATE + * @userdata1 DIMM state + * @userdata2 0 + * @devdesc Invalid DIMM I2C state requested + */ + err = createErrl(DIMM_MID_DIMM_SM, + DIMM_INVALID_STATE, + OCC_NO_EXTENDED_RC, + ERRL_SEV_PREDICTIVE, + NULL, + DEFAULT_TRACE_SIZE, + i_state, + 0); + // Request reset since this should never happen. + REQUEST_RESET(err); + scheduleRequest = false; + break; + } + + if (scheduleRequest) + { + // Clear errors and init common arguments for GPE + G_dimm_sm_args.error.error = 0; + G_dimm_sm_args.state = i_state; + + DIMM_DBG("dimm_sm: Scheduling GPE1 DIMM I2C state 0x%02X (tick %d)", i_state, DIMM_TICK); + int l_rc = gpe_request_schedule(&G_dimm_sm_request); + if (0 == l_rc) + { + l_scheduled = true; + } + else + { + errlHndl_t l_err = NULL; + INTR_TRAC_ERR("dimm_sm: schedule failed w/rc=0x%08X (%d us)", + l_rc, (int) ((ssx_timebase_get())/(SSX_TIMEBASE_FREQUENCY_HZ/1000000))); + /* + * @errortype + * @moduleid DIMM_MID_DIMM_SM + * @reasoncode SSX_GENERIC_FAILURE + * @userdata1 GPE shedule returned rc code + * @userdata2 state + * @devdesc dimm_sm schedule failed + */ + l_err = createErrl(DIMM_MID_DIMM_SM, + SSX_GENERIC_FAILURE, + ERC_DIMM_SCHEDULE_FAILURE, + ERRL_SEV_PREDICTIVE, + NULL, + DEFAULT_TRACE_SIZE, + l_rc, + i_state); + // Request reset since this should never happen. + REQUEST_RESET(l_err); + } + } + } + + return l_scheduled; + +} // end schedule_dimm_req() + + +// Check if the last I2C operation completed, and force failure if not +bool check_for_i2c_failure() +{ + bool failed = false; + + if (false == G_dimm_i2c_reset_required) + { + // Check if I2C operation is complete + if (ASYNC_REQUEST_STATE_COMPLETE == G_dimm_sm_request.request.completion_state) + { + // Check if I2C operation failed + if ((GPE_RC_SUCCESS != G_dimm_sm_args.error.rc) && + (GPE_RC_NOT_COMPLETE != G_dimm_sm_args.error.rc)) + { + mark_dimm_failed(); + failed = true; + } + } + } + return failed; +} + + +// Handle the DIMM reset states +uint8_t dimm_reset_sm() +{ + uint8_t nextState = G_dimm_state; + + switch (G_dimm_state) + { + case DIMM_STATE_RESET_MASTER: + if (DIMM_TICK == 0) + { + G_dimm_sm_args.i2cEngine = G_sysConfigData.dimm_i2c_engine; + if (schedule_dimm_req(DIMM_STATE_RESET_MASTER)) + { + nextState = DIMM_STATE_RESET_SLAVE_P0; + } + } + // else wait for tick 0 + break; + + case DIMM_STATE_RESET_SLAVE_P0: + G_dimm_sm_args.i2cPort = 0; + if (schedule_dimm_req(DIMM_STATE_RESET_SLAVE_P0)) + { + nextState = DIMM_STATE_RESET_SLAVE_P0_WAIT; + } + break; + + case DIMM_STATE_RESET_SLAVE_P0_WAIT: + // Delay to allow reset to complete + DIMM_DBG("dimm_reset_sm: waiting during slave port 0 reset"); + nextState = DIMM_STATE_RESET_SLAVE_P0_COMPLETE; + break; + + case DIMM_STATE_RESET_SLAVE_P0_COMPLETE: + if (schedule_dimm_req(DIMM_STATE_RESET_SLAVE_P0_COMPLETE)) + { + if (G_maxDimmPorts > 1) + { + nextState = DIMM_STATE_RESET_SLAVE_P1; + } + else + { + // If there is only one port, skip slave port 1 + nextState = DIMM_STATE_INIT; + G_dimm_i2c_reset_required = false; + TRAC_INFO("dimm_reset_sm: I2C reset completed (1 port)"); + } + } + break; + + case DIMM_STATE_RESET_SLAVE_P1: + G_dimm_sm_args.i2cPort = 1; + if (schedule_dimm_req(DIMM_STATE_RESET_SLAVE_P1)) + { + nextState = DIMM_STATE_RESET_SLAVE_P1_WAIT; + } + break; + + case DIMM_STATE_RESET_SLAVE_P1_WAIT: + // Delay to allow reset to complete + nextState = DIMM_STATE_RESET_SLAVE_P1_COMPLETE; + break; + + case DIMM_STATE_RESET_SLAVE_P1_COMPLETE: + if (schedule_dimm_req(DIMM_STATE_RESET_SLAVE_P1_COMPLETE)) + { + nextState = DIMM_STATE_INIT; + G_dimm_i2c_reset_required = false; + TRAC_INFO("dimm_reset_sm: I2C reset completed"); + } + break; + + default: + INTR_TRAC_ERR("dimm_reset_sm: INVALID STATE: 0x%02X when reset is required", G_dimm_state); + nextState = DIMM_STATE_RESET_MASTER; + break; + } + + return nextState; + +} // end dimm_reset_sm() + + +// Function Specification +// +// Name: task_dimm_sm +// +// Description: DIMM State Machine - Called every other tick to collect all of +// the DIMM temperatures. +// +// Task Flags: RTL_FLAG_ACTIVE +// +// End Function Specification +void task_dimm_sm(struct task *i_self) +{ + static uint8_t L_dimmIndex = 0x00; + static uint8_t L_dimmPort = 0x00; + static uint8_t L_notReadyCount = 0; +#define MAX_READ_ATTEMPT 3 + static uint8_t L_readAttempt = 0; + static bool L_readIssued = false; + + if (G_mem_monitoring_allowed) + { + //DIMM_DBG("task_dimm_sm: request state=0x%02X, completion_state=0x%02X, abort_state=0x%02X", + // G_dimm_sm_request.request.state, G_dimm_sm_request.request.completion_state, G_dimm_sm_request.request.abort_state); + + if (check_for_i2c_failure()) + { + // After reset, move on to next DIMM + use_next_dimm(&L_dimmPort, &L_dimmIndex); + } + + uint8_t nextState = G_dimm_state; + + if (G_dimm_i2c_reset_required) + { + nextState = dimm_reset_sm(); + } + else if (G_dimm_state == DIMM_STATE_INIT) + { + // Setup I2C Interrupt Mask Register + DIMM_DBG("DIMM_STATE_INIT: (I2C Engine 0x%02X, Memory Type 0x%02X)", + G_sysConfigData.dimm_i2c_engine, G_sysConfigData.mem_type); + G_dimm_sm_args.i2cEngine = G_sysConfigData.dimm_i2c_engine; + if (schedule_dimm_req(DIMM_STATE_INIT)) + { + nextState = DIMM_STATE_WRITE_MODE; + } + } + else + { + bool intTriggered = check_for_i2c_interrupt(G_sysConfigData.dimm_i2c_engine); + if (intTriggered == false) + { + ++L_notReadyCount; + } + + // Check if prior command completed (or timed out waiting for it) + if (intTriggered || (L_notReadyCount > MAX_TICK_COUNT_WAIT)) + { + if (ASYNC_REQUEST_STATE_COMPLETE == G_dimm_sm_request.request.completion_state) + { + // IPC request completed, now check return code + if (GPE_RC_SUCCESS == G_dimm_sm_args.error.rc) + { + // last request completed without error + switch (G_dimm_sm_args.state) + { + case DIMM_STATE_INIT: + // Save max I2C ports + if (G_maxDimmPorts != G_dimm_sm_args.maxPorts) + { + G_maxDimmPorts = G_dimm_sm_args.maxPorts; + DIMM_DBG("task_dimm_sm: updating DIMM Max I2C Ports to %d", G_maxDimmPorts); + } + break; + + case DIMM_STATE_READ_TEMP: + if (L_readIssued) + { + const uint8_t port = G_dimm_sm_args.i2cPort; + const uint8_t dimm = G_dimm_sm_args.dimm; + + // Last DIMM read completed, update sensor and clear error count + DIMM_DBG("task_dimm_sm: Successfully read DIMM%04X temperature: %dC, tick %d", + DIMM_AND_PORT, G_dimm_sm_args.temp, DIMM_TICK); + g_amec->proc[0].memctl[port].centaur.dimm_temps[dimm].cur_temp = G_dimm_sm_args.temp; + G_dimm[port][dimm].lastReading = ((ssx_timebase_get())/(SSX_TIMEBASE_FREQUENCY_HZ/1000000)); + G_dimm[port][dimm].errorCount = 0; + + // Move on to next DIMM + use_next_dimm(&L_dimmPort, &L_dimmIndex); + L_readIssued = false; + } + break; + + default: + // Nothing to do + break; + } + } + else + { + // last request did not return success + switch (G_dimm_sm_args.state) + { + case DIMM_STATE_INITIATE_READ: + if (++L_readAttempt < MAX_READ_ATTEMPT) + { + // The initiate_read didnt complete, retry + DIMM_DBG("task_dimm_sm: initiate read didn't start (%d attempts)", L_readAttempt); + // Force the read again + G_dimm_state = DIMM_STATE_INITIATE_READ; + nextState = G_dimm_state; + } + else + { + INTR_TRAC_ERR("task_dimm_sm: initiate read didn't start after %d attempts... forcing reset", L_readAttempt); + mark_dimm_failed(); + } + break; + + case DIMM_STATE_READ_TEMP: + if (L_readIssued) + { + if (++L_readAttempt < MAX_READ_ATTEMPT) + { + DIMM_DBG("task_dimm_sm: read didn't complete (%d attempts)", L_readAttempt); + // Force the read again + G_dimm_state = DIMM_STATE_READ_TEMP; + nextState = G_dimm_state; + } + else + { + INTR_TRAC_ERR("task_dimm_sm: read did not complete after %d attempts... forcing reset", L_readAttempt); + mark_dimm_failed(); + } + } + break; + + default: + // Nothing to do + break; + } + } + } + } + + if (false == G_dimm_i2c_reset_required) + { + // Handle new DIMM state + switch (G_dimm_state) + { + case DIMM_STATE_WRITE_MODE: + // Only start a DIMM read on tick 0 or 8 + if ((DIMM_TICK == 0) || (DIMM_TICK == 8)) + { + // If DIMM has huid/sensor then it should be present + if ((0 != G_sysConfigData.dimm_huids[L_dimmPort][L_dimmIndex]) && + (G_dimm[L_dimmPort][L_dimmIndex].disabled == false)) + { + G_dimm_sm_args.i2cPort = L_dimmPort; + G_dimm_sm_args.dimm = L_dimmIndex; + DIMM_DBG("task_dimm_sm: Starting collection for DIMM%04X at tick %d", + DIMM_AND_PORT, DIMM_TICK); + if (schedule_dimm_req(DIMM_STATE_WRITE_MODE)) + { + nextState = DIMM_STATE_WRITE_ADDR; + } + } + else + { + // Skip current DIMM and move on to next one + use_next_dimm(&L_dimmPort, &L_dimmIndex); + } + } + break; + + case DIMM_STATE_WRITE_ADDR: + if (intTriggered || (L_notReadyCount > MAX_TICK_COUNT_WAIT)) + { + G_dimm_sm_args.dimm = L_dimmIndex; + G_dimm_sm_args.i2cAddr = get_dimm_addr(L_dimmIndex); + if (schedule_dimm_req(DIMM_STATE_WRITE_ADDR)) + { + nextState = DIMM_STATE_INITIATE_READ; + L_readAttempt = 0; + L_readIssued = false; + } + } + break; + + case DIMM_STATE_INITIATE_READ: + if (intTriggered || (L_notReadyCount > MAX_TICK_COUNT_WAIT)) + { + G_dimm_sm_args.dimm = L_dimmIndex; + if (schedule_dimm_req(DIMM_STATE_INITIATE_READ)) + { + nextState = DIMM_STATE_READ_TEMP; + } + } + break; + + case DIMM_STATE_READ_TEMP: + if (intTriggered || (L_notReadyCount > MAX_TICK_COUNT_WAIT)) + { + if (schedule_dimm_req(DIMM_STATE_READ_TEMP)) + { + L_readIssued = true; + nextState = DIMM_STATE_WRITE_MODE; + } + } + break; + + default: + INTR_TRAC_ERR("task_dimm_sm: INVALID STATE: 0x%02X", G_dimm_state); + break; + } + } + else + { + // Previous op triggered reset + nextState = dimm_reset_sm(); + } + } + + if (nextState != G_dimm_state) + { + DIMM_DBG("task_dimm_sm: Updating state to 0x%02X (DIMM%04X) end of tick %d", nextState, (L_dimmPort<<8)|L_dimmIndex, DIMM_TICK); + G_dimm_state = nextState; + L_notReadyCount = 0; + } + } + +} // end task_dimm_sm() + + diff --git a/src/occ_405/dimm/dimm.h b/src/occ_405/dimm/dimm.h new file mode 100644 index 0000000..cfbb898 --- /dev/null +++ b/src/occ_405/dimm/dimm.h @@ -0,0 +1,69 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/occ_405/dimm/dimm.h $ */ +/* */ +/* OpenPOWER OnChipController Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef _DIMM_H +#define _DIMM_H + +#include <occ_common.h> +#include <trac_interface.h> +#include <errl.h> +#include <rtls.h> + +#define WORD_HIGH(data) ((uint32_t)(((uint64_t)data)>>32)) +#define WORD_LOW(data) ((uint32_t)(((uint64_t)data)&0xFFFFFFFF)) + +#define NUM_DIMM_PORTS 2 + +typedef enum +{ + DIMM_READ_SUCCESS = 0x00, + DIMM_READ_IN_PROGRESS = 0x01, + DIMM_READ_SCHEDULE_FAILED = 0xFA, + DIMM_READ_NOT_COMPLETE = 0xFF, +} readStatus_e; + +typedef enum +{ + PIB_I2C_ENGINE_C = 0x01, + PIB_I2C_ENGINE_D = 0x02, + PIB_I2C_ENGINE_E = 0x03, +} PIB_I2C_ENGINE; + +typedef enum +{ + MEM_TYPE_CUMULUS = 0x00, + MEM_TYPE_NIMBUS = 0xFF +} MEMORY_TYPE; + +// Generic memory initialization to handle init for all memory types +void memory_init(); + +// Nimbus specific init +void memory_nimbus_init(); + +// DIMM I2C state machine (for NIMBUS) +void task_dimm_sm(struct task *i_self); + +#endif //_DIMM_H diff --git a/src/occ_405/dimm/dimm_service_codes.h b/src/occ_405/dimm/dimm_service_codes.h new file mode 100755 index 0000000..9261d04 --- /dev/null +++ b/src/occ_405/dimm/dimm_service_codes.h @@ -0,0 +1,40 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/occ_405/dimm/dimm_service_codes.h $ */ +/* */ +/* OpenPOWER OnChipController Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef _DIMM_SERVICE_CODES_H_ +#define _DIMM_SERVICE_CODES_H_ + +#include <comp_ids.h> + +enum dimmModuleId +{ + DIMM_MID_STATE_MACHINE = DIMM_COMP_ID | 0x00, + DIMM_MID_MEMORY_INIT = DIMM_COMP_ID | 0x01, + DIMM_MID_NIMBUS_INIT = DIMM_COMP_ID | 0x02, + DIMM_MID_DIMM_SM = DIMM_COMP_ID | 0x03, + DIMM_MID_MARK_DIMM_FAILED = DIMM_COMP_ID | 0x04, +}; + +#endif /* #ifndef _DIMM_SERVICE_CODES_H_ */ diff --git a/src/occ_405/img_defs.mk b/src/occ_405/img_defs.mk index e3fec37..a2f6d50 100644 --- a/src/occ_405/img_defs.mk +++ b/src/occ_405/img_defs.mk @@ -35,10 +35,10 @@ # # SSX_SRCDIR : Default ..; The path to the SSX source code. # The default is set for building the SSX -# subdirectories. +# subdirectories. # # SSX_THREAD_SUPPORT : (0/1, default 1); Compile SSX thread and -# semaphore suppprt +# semaphore suppprt # # SSX_TIMER_SUPPORT : (0/1, default 1); Compile SSX timer suppprt # @@ -58,7 +58,7 @@ # make GCC-O-LEVEL="-Os -fno-branch-count-reg" # # GCC-TOOL-PREFIX : The full path (including executable file prefixes) to -# the GCC cross-development tools to use. The default is +# the GCC cross-development tools to use. The default is # "ppcnf-mcp5-" # # CTEPATH : This variable defaults to the afs/awd CTE tool @@ -186,8 +186,8 @@ GCC-DEFS += -DSTRAIGHT_TO_OBS_HACK=1 endif GCC-DEFS += -DIMAGE_NAME=$(IMAGE_NAME) -GCC-DEFS += -DSSX_TIMER_SUPPORT=$(SSX_TIMER_SUPPORT) -GCC-DEFS += -DSSX_THREAD_SUPPORT=$(SSX_THREAD_SUPPORT) +GCC-DEFS += -DSSX_TIMER_SUPPORT=$(SSX_TIMER_SUPPORT) +GCC-DEFS += -DSSX_THREAD_SUPPORT=$(SSX_THREAD_SUPPORT) GCC-DEFS += -DPPC405_MMU_SUPPORT=$(PPC405_MMU_SUPPORT) GCC-DEFS += -DSSX_TRACE_SUPPORT=$(SSX_TRACE_SUPPORT) GCC-DEFS += -DSSX_TRACE_HASH_PREFIX=$(SSX_TRACE_HASH_PREFIX) @@ -212,6 +212,7 @@ APP_INCLUDES = -I$(IMAGE_SRCDIR)/rtls \ -I$(IMAGE_SRCDIR)/amec \ -I$(IMAGE_SRCDIR)/cent \ -I$(IMAGE_SRCDIR)/firdata \ + -I$(IMAGE_SRCDIR)/dimm \ -I$(IMAGE_SRCDIR)/../occ_gpe0 \ INCLUDES += $(IMG_INCLUDES) $(GLOBAL_INCLUDES) $(APP_INCLUDES) \ diff --git a/src/occ_405/incl/comp_ids.h b/src/occ_405/incl/comp_ids.h index fb6f5d5..e6ff8b6 100755 --- a/src/occ_405/incl/comp_ids.h +++ b/src/occ_405/incl/comp_ids.h @@ -80,5 +80,9 @@ #define CMDH_COMP_ID 0x0E00 #define CMDH_COMP_NAME "CMDH" +// DIMM State Manager +#define DIMM_COMP_ID 0x0F00 +#define DIMM_COMP_NAME "DIMM" + #endif diff --git a/src/occ_405/main.c b/src/occ_405/main.c index 2d0c37b..8e77fcf 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -56,6 +56,7 @@ #include "scom.h" //#include <fir_data_collect.h> #include <pss_service_codes.h> +#include <dimm.h> extern uint32_t __ssx_boot; // Function address is 32 bits extern uint32_t G_occ_phantom_critical_count; diff --git a/src/occ_405/occLinkInputFile b/src/occ_405/occLinkInputFile index 98bec10..adc8403 100644 --- a/src/occ_405/occLinkInputFile +++ b/src/occ_405/occLinkInputFile @@ -20,6 +20,7 @@ INPUT ( amec_data.o dcomMasterRx.o dcomSlaveRx.o dcomSlaveTx.o + dimm.o errl.o ffdc.o fir_data_collect.o diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h index 65ccde4..e355f28 100644 --- a/src/occ_405/occ_service_codes.h +++ b/src/occ_405/occ_service_codes.h @@ -102,6 +102,10 @@ enum occReasonCode APSS_HARD_FAILURE = 0xC5, /// Request to read redundant APSS data failed REDUNDANT_APSS_GPE_FAILURE = 0xCB, + /// Request to read DIMM data failed. + DIMM_GPE_FAILURE = 0xD0, + MEMORY_INIT_FAILED = 0xD1, + DIMM_INVALID_STATE = 0xD2, /// Success! OCC_SUCCESS_REASON_CODE = 0xFF, }; @@ -193,6 +197,9 @@ enum occExtReasonCode ERC_BCE_REQ_SCHED_INPROG_FAILURE = 0x00000073, ERC_BCE_REQ_CREATE_WRITE_FAILURE = 0x00000074, ERC_BCE_REQ_SCHED_WRITE_FAILURE = 0x00000075, + + ERC_DIMM_SCHEDULE_FAILURE = 0x00000080, + ERC_DIMM_COMPLETE_FAILURE = 0x00000081, }; // Error log Module Ids diff --git a/src/occ_405/occ_sys_config.c b/src/occ_405/occ_sys_config.c index f052fe0..808fce0 100755 --- a/src/occ_405/occ_sys_config.c +++ b/src/occ_405/occ_sys_config.c @@ -26,6 +26,7 @@ #include <occ_common.h> #include <common_types.h> #include <occ_sys_config.h> +#include <dimm.h> // SysConfig Section Defines #define SYSCFG_DEFAULT_VERSION 0xff @@ -183,10 +184,12 @@ occSysConfigData_t G_sysConfigData = .master_ppb_fmax = 0xFFFF, // ----------------------------------------------------------- - // Centaur/Dimm HUID initializations + // Centaur/DIMM Initialization // ----------------------------------------------------------- .centaur_huids = {0}, - .dimm_huids = {{0},{0},{0},{0},{0},{0},{0},{0}}, + .dimm_huids = {{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}}, + .mem_type = MEM_TYPE_NIMBUS, + .dimm_i2c_engine = PIB_I2C_ENGINE_E, // ----------------------------------------------------------- // Memory Throttle Limits diff --git a/src/occ_405/occ_sys_config.h b/src/occ_405/occ_sys_config.h index 91a6369..4d238ee 100755 --- a/src/occ_405/occ_sys_config.h +++ b/src/occ_405/occ_sys_config.h @@ -34,6 +34,7 @@ #endif #include <state.h> #include <apss.h> +#include <dimm.h> #define MAX_NUM_OCC 8 #define MAX_NUM_NODES 4 @@ -332,14 +333,10 @@ typedef struct uint32_t master_ppb_fmax; // -------------------------------------- - // Hardware Sensor ID's for centaurs and dimms + // Memory Configuration Data // -------------------------------------- uint32_t centaur_huids[MAX_NUM_CENTAURS]; uint32_t dimm_huids[MAX_NUM_CENTAURS][NUM_DIMMS_PER_CENTAUR]; - - // -------------------------------------- - // Memory type and dimm i2c engine for nimbus - // -------------------------------------- uint8_t mem_type; uint8_t dimm_i2c_engine; diff --git a/src/occ_405/rtls/rtls.h b/src/occ_405/rtls/rtls.h index 7db2e90..5b95791 100755 --- a/src/occ_405/rtls/rtls.h +++ b/src/occ_405/rtls/rtls.h @@ -57,7 +57,7 @@ typedef enum { // TASK_ID_AMEC_MASTER, // AMEC SMH tasks // TASK_ID_CORE_DATA_CONTROL, // TASK_ID_GPU_SM, // GPU State Machine -// TASK_ID_DIMM_SM, // DIMM State Machine + TASK_ID_DIMM_SM, // DIMM State Machine // TASK_ID_MEM_DEADMAN, // Memory deadman timer TASK_END // This must always be the last enum in this list, // so that TASK_END always equals the last task ID + 1. @@ -97,13 +97,13 @@ typedef struct RTL_FLAG_NO_APSS | RTL_FLAG_MSTR_READY | RTL_FLAG_STANDBY | \ RTL_FLAG_APSS_NOT_INITD) -#define CENTAUR_CONTROL_RTL_FLAGS (RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_ACTIVE | \ - RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | \ - RTL_FLAG_APSS_NOT_INITD) +#define MEMORY_CONTROL_RTL_FLAGS (RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_ACTIVE | \ + RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | \ + RTL_FLAG_APSS_NOT_INITD) -#define CENTAUR_DATA_RTL_FLAGS (RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | \ - RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | \ - RTL_FLAG_RUN | RTL_FLAG_APSS_NOT_INITD) +#define MEMORY_DATA_RTL_FLAGS (RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | \ + RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | \ + RTL_FLAG_RUN | RTL_FLAG_APSS_NOT_INITD) // Tick Timer definitions #define MICS_PER_TICK 250 // Number of micro-seconds per tick diff --git a/src/occ_405/rtls/rtls_tables.c b/src/occ_405/rtls/rtls_tables.c index 69c6219..9d63762 100755 --- a/src/occ_405/rtls/rtls_tables.c +++ b/src/occ_405/rtls/rtls_tables.c @@ -33,6 +33,7 @@ #include <centaur_data.h> #include <centaur_control.h> #include "amec_master_smh.h" +#include "dimm.h" //flags for task table #define APSS_TASK_FLAGS RTL_FLAG_MSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_RUN @@ -47,9 +48,9 @@ #define FLAGS_LOW_CORES_DATA RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | RTL_FLAG_APSS_NOT_INITD #define FLAGS_HIGH_CORES_DATA RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | RTL_FLAG_APSS_NOT_INITD -//Start out with centaur tasks not running. -#define FLAGS_CENTAUR_DATA RTL_FLAG_NONE -#define FLAGS_CENTAUR_CONTROL RTL_FLAG_NONE +// Start out with memory tasks not running, then start during transition to observation in memory_init() +#define FLAGS_MEMORY_DATA RTL_FLAG_NONE +#define FLAGS_MEMORY_CONTROL RTL_FLAG_NONE #define FLAGS_FAST_CORES_DATA RTL_FLAG_MSTR | RTL_FLAG_NOTMSTR | RTL_FLAG_OBS | RTL_FLAG_ACTIVE | RTL_FLAG_MSTR_READY | RTL_FLAG_NO_APSS | RTL_FLAG_RUN | RTL_FLAG_APSS_NOT_INITD @@ -71,7 +72,6 @@ // TEMP/TODO: These are not yet implemented #define FLAGS_GPU_SM -#define FLAGS_DIMM_SM #define FLAGS_MEM_DEADMAN // Global tick sequences @@ -121,8 +121,7 @@ task_t G_task_table[TASK_END] = { // { FLAGS_CORE_DATA_CONTROL, task_core_data_control, NULL }, // TASK_ID_CORE_DATA_CONTROL // TEMP -- NOT YET IMPLEMENTED // { FLAGS_GPU_SM, task_gpu_sm, NULL }, // TASK_ID_GPU_SM -// TEMP -- NOT YET IMPLEMENTED -// { FLAGS_DIMM_SM, task_dimm_sm, NULL }, // TASK_ID_DIMM_SM + { FLAGS_MEMORY_DATA, task_dimm_sm, NULL }, // TASK_ID_DIMM_SM // TEMP -- NOT YET IMPLEMENTED // { FLAGS_MEM_DEADMAN, task_mem_deadman, NULL }, // TASK_ID_MEM_DEADMAN }; @@ -130,7 +129,7 @@ task_t G_task_table[TASK_END] = { const uint8_t G_tick0_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -169,7 +168,7 @@ const uint8_t G_tick1_seq[] = { const uint8_t G_tick2_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -207,7 +206,7 @@ const uint8_t G_tick3_seq[] = { const uint8_t G_tick4_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -246,7 +245,7 @@ const uint8_t G_tick5_seq[] = { const uint8_t G_tick6_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -284,7 +283,7 @@ const uint8_t G_tick7_seq[] = { const uint8_t G_tick8_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -323,7 +322,7 @@ const uint8_t G_tick9_seq[] = { const uint8_t G_tick10_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -361,7 +360,7 @@ const uint8_t G_tick11_seq[] = { const uint8_t G_tick12_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, @@ -400,7 +399,7 @@ const uint8_t G_tick13_seq[] = { const uint8_t G_tick14_seq[] = { TASK_ID_APSS_START, TASK_ID_CORE_DATA_LOW, - //TASK_ID_DIMM_SM, + TASK_ID_DIMM_SM, TASK_ID_APSS_CONT, TASK_ID_CORE_DATA_HIGH, TASK_ID_APSS_DONE, diff --git a/src/occ_405/state.c b/src/occ_405/state.c index 8cb1124..b784fa4 100755 --- a/src/occ_405/state.c +++ b/src/occ_405/state.c @@ -40,6 +40,7 @@ //#include "heartbeat.h" #include "scom.h" #include <fir_data_collect.h> +#include <dimm.h> extern proc_gpsm_dcm_sync_occfw_t G_proc_dcm_sync_state; extern bool G_mem_monitoring_allowed; @@ -135,37 +136,8 @@ errlHndl_t SMGR_standby_to_observation() l_error_logged = FALSE; TRAC_IMP("SMGR: Standby to Observation Transition Started"); -// TEMP -- NOT SUPPORTED YET IN PHASE1 -/* - //This flag is set if tmgt sends us at least one data set in the - //mem config data packet. No data sets will be sent for centaur ec less than 2.0 - //due to an intermittent hw failure that can occur on those chips. + memory_init(); - if(G_mem_monitoring_allowed) - { - if(!rtl_task_is_runnable(TASK_ID_CENTAUR_DATA)) - { - - TRAC_INFO("SMGR_standby_to_observation: 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("SMGR_standby_to_observation: OCC is being reset, centaur_init failed"); - } - else - { - //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; - } - } - } -*/ // Set the RTL Flags to indicate which tasks can run // - Set OBSERVATION b/c we're in OBSERVATION State rtl_clr_run_mask_deferred(RTL_FLAG_STANDBY); diff --git a/src/occ_405/topfiles.mk b/src/occ_405/topfiles.mk index c13d742..58aa999 100644 --- a/src/occ_405/topfiles.mk +++ b/src/occ_405/topfiles.mk @@ -47,6 +47,7 @@ TOP-C-SOURCES = amec/amec_data.c \ dcom/dcomMasterRx.c \ dcom/dcomSlaveRx.c \ dcom/dcomSlaveTx.c \ + dimm/dimm.c \ errl/errl.c \ firdata/fir_data_collect.c \ homer.c \ diff --git a/src/occ_405/trac/trac.h b/src/occ_405/trac/trac.h index dad0ad4..92fd9bf 100755 --- a/src/occ_405/trac/trac.h +++ b/src/occ_405/trac/trac.h @@ -287,6 +287,16 @@ extern void dumpHexString(const void *i_data, const unsigned int len, const char #define CNFG_DBG_HEXDUMP(data, len, string) #endif +#ifdef DIMM_DEBUG + #define DIMM_DBG(frmt,args...) \ + DBG_PRINT(frmt,##args) + #define DIMM_DBG_HEXDUMP(data, len, string) \ + DEBUG_HEXDUMP(data, len, string) +#else + #define DIMM_DBG(frmt,args...) + #define DIMM_DBG_HEXDUMP(data, len, string) +#endif + #else // NO_TRAC_STRINGS #define TRAC_ERR(frmt,args...) @@ -307,6 +317,7 @@ extern void dumpHexString(const void *i_data, const unsigned int len, const char #define SNSR_DBG(frmt,args...) #define TMER_DBG(frmt,args...) #define CNFG_DBG(frmt,args...) +#define DIMM_DBG(frmt,args...) #define MAIN_DBG_HEXDUMP(frmt,args...) #define RTLS_DBG_HEXDUMP(frmt,args...) @@ -322,6 +333,7 @@ extern void dumpHexString(const void *i_data, const unsigned int len, const char #define SNSR_DBG_HEXDUMP(frmt,args...) #define TMER_DBG_HEXDUMP(frmt,args...) #define CNFG_DBG_HEXDUMP(frmt,args...) +#define DIMM_DBG_HEXDUMP(frmt,args...) #endif |