Пример #1
0
// 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()
Пример #2
0
// 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()
Пример #3
0
// Verifies that each core is at the correct frequency after they have had
// time to stabilize
void amec_verify_pstate()
{
    uint8_t                             l_core = 0;
    int8_t                              l_pstate_from_fmax = 0;
    gpe_bulk_core_data_t *              l_core_data_ptr;
    pmc_pmsr_ffcdc_data_t               l_pmc_pmsr_ffdc;
    errlHndl_t                          l_err = NULL;

    if ( (G_time_until_freq_check == 0) &&
            ( CURRENT_MODE() != OCC_MODE_DYN_POWER_SAVE ) &&
            ( CURRENT_MODE() != OCC_MODE_DYN_POWER_SAVE_FP ) &&
            (!G_sysConfigData.system_type.kvm))
    {
        // Reset the counter
        G_time_until_freq_check = FREQ_CHG_CHECK_TIME;

        // Convert fmax to the corresponding pstate
        l_pstate_from_fmax = proc_freq2pstate(g_amec->sys.fmax);

        for( l_core = 0; l_core < MAX_NUM_CORES; l_core++ )
        {
            // If the core isn't present, skip it
            if(!CORE_PRESENT(l_core))
            {
                l_pmc_pmsr_ffdc.pmsr_ffdc_data.data[l_core].value = 0;
                continue;
            }

            // Get pointer to core data
            l_core_data_ptr = proc_get_bulk_core_data_ptr(l_core);

            // Get the core's pmsr data
            l_pmc_pmsr_ffdc.pmsr_ffdc_data.data[l_core] = l_core_data_ptr->pcb_slave.pmsr;

            // Verify that the core is running at the correct frequency
            // If not, log an error
            if( (l_pstate_from_fmax != l_pmc_pmsr_ffdc.pmsr_ffdc_data.data[l_core].fields.local_pstate_actual) &&
                (l_pstate_from_fmax > l_pmc_pmsr_ffdc.pmsr_ffdc_data.data[l_core].fields.pv_min) &&
                (l_err == NULL) )
            {
                TRAC_ERR("Frequency mismatch in core %d: actual_ps[%d] req_ps[%d] fmax[%d] mode[%d].",
                    l_core,
                    l_pmc_pmsr_ffdc.pmsr_ffdc_data.data[l_core].fields.local_pstate_actual,
                    l_pstate_from_fmax,
                    g_amec->sys.fmax,
                    CURRENT_MODE());

                fill_pmc_ffdc_buffer(&l_pmc_pmsr_ffdc.pmc_ffcdc_data);

                /* @
                 * @moduleid   AMEC_VERIFY_FREQ_MID
                 * @reasonCode TARGET_FREQ_FAILURE
                 * @severity   ERRL_SEV_PREDICTIVE
                 * @userdata1  0
                 * @userdata2  0
                 * @userdata4  OCC_NO_EXTENDED_RC
                 * @devdesc    A core is not running at the expected frequency
                 */
                l_err = createErrl( AMEC_VERIFY_FREQ_MID,      // i_modId,
                                    TARGET_FREQ_FAILURE,       // i_reasonCode,
                                    OCC_NO_EXTENDED_RC,
                                    ERRL_SEV_UNRECOVERABLE,
                                    NULL,                      // i_trace,
                                    DEFAULT_TRACE_SIZE,        // i_traceSz,
                                    0,                         // i_userData1,
                                    0);                        // i_userData2

                //Add firmware callout
                addCalloutToErrl(l_err,
                        ERRL_CALLOUT_TYPE_COMPONENT_ID,
                        ERRL_COMPONENT_ID_FIRMWARE,
                        ERRL_CALLOUT_PRIORITY_HIGH);

                //Add processor callout
                addCalloutToErrl(l_err,
                        ERRL_CALLOUT_TYPE_HUID,
                        G_sysConfigData.proc_huid,
                        ERRL_CALLOUT_PRIORITY_MED);
            }
        }

        if( l_err != NULL)
        {
            //Add our register dump to the error log
            addUsrDtlsToErrl(l_err,
                    (uint8_t*) &l_pmc_pmsr_ffdc,
                    sizeof(l_pmc_pmsr_ffdc),
                    ERRL_USR_DTL_STRUCT_VERSION_1,
                    ERRL_USR_DTL_BINARY_DATA);

            REQUEST_RESET(l_err);
        }
    }
}
Пример #4
0
// Check and update lock ownership for the specified i2c engine.
// Returns true if OCC owns the lock, or false if host owns lock
//
// If host has requesed the i2c lock, it will be released and an external interrupt
// will be generated/queued and function will return false.
// If the host has not released the lock, function will return false.
// If the host cleared its lock bit, OCC will take back ownership and return true.
//
bool check_and_update_i2c_lock(const uint8_t i_engine)
{
    bool occ_owns_lock = true;

    if ((PIB_I2C_ENGINE_E == i_engine) ||
        (PIB_I2C_ENGINE_D == i_engine) ||
        (PIB_I2C_ENGINE_C == i_engine))
    {
        bool needRetry = false;
        do
        {
            ocb_occflg_t original_occflags;
            original_occflags.value = in32(OCB_OCCFLG);

            LOCK_DBG("check_and_update_i2c_lock: I2C engine %d - host=%d, occ=%d (dimmTick=%d)",
                     i_engine, original_occflags.fields.i2c_engine3_lock_host, original_occflags.fields.i2c_engine3_lock_occ, DIMM_TICK);
            if (occ_owns_i2c_lock(original_occflags, i_engine))
            {
                if (host_wants_i2c_lock(original_occflags, i_engine))
                {
                    // Host requested lock, clear the OCC lock and notify host
                    update_i2c_lock(LOCK_RELEASE, i_engine);
                    occ_owns_lock = false;
                }
                // else OCC already owns the lock
            }
            else
            {
                // OCC does not own the lock
                occ_owns_lock = false;
                if (false == host_wants_i2c_lock(original_occflags, i_engine))
                {
                    // Host is not requesting the lock, acquire lock for OCC
                    update_i2c_lock(LOCK_ACQUIRE, i_engine);
                    occ_owns_lock = true;
                }
                // else Host still holds the lock
            }

            if ((occ_owns_lock) &&
                (original_occflags.fields.i2c_engine1_lock_host == 0) &&
                (original_occflags.fields.i2c_engine1_lock_occ == 0))
            {
                // If neither lock bit is set, we must read back the register to make
                // sure the host did not set at same time (lock conflict)
                ocb_occflg_t verify_occflags;
                verify_occflags.value = in32(OCB_OCCFLG);
                if (host_wants_i2c_lock(verify_occflags, i_engine))
                {
                    // Host wrote their lock bit at same time, clear OCC lock and notify host
                    update_i2c_lock(LOCK_RELEASE, i_engine);
                    occ_owns_lock = false;
                }
                else
                {
                    if (false == occ_owns_i2c_lock(verify_occflags, i_engine))
                    {
                        // ERROR - OCC OWNERSHIP BIT DID NOT GET SET
                        INTR_TRAC_ERR("check_and_update_i2c_lock: I2C lock bit did not get set (OCCFLAGS reg: 0x%08X)",
                                      verify_occflags.value);

                        if (needRetry)
                        {
                            // After one retry, log error and goto safe
                            /*
                             * @errortype
                             * @moduleid    I2C_LOCK_UPDATE
                             * @reasoncode  OCI_WRITE_FAILURE
                             * @userdata1   I2C engine number
                             * @userdata2   OCC Flags register
                             * @devdesc     OCI write failure setting I2C ownership bit
                             */
                            errlHndl_t err = createErrl(I2C_LOCK_UPDATE,
                                                        OCI_WRITE_FAILURE,
                                                        OCC_NO_EXTENDED_RC,
                                                        ERRL_SEV_PREDICTIVE,
                                                        NULL,
                                                        DEFAULT_TRACE_SIZE,
                                                        i_engine,
                                                        verify_occflags.value);

                            //Callout firmware
                            addCalloutToErrl(err,
                                             ERRL_CALLOUT_TYPE_COMPONENT_ID,
                                             ERRL_COMPONENT_ID_FIRMWARE,
                                             ERRL_CALLOUT_PRIORITY_MED);

                            //Callout processor
                            addCalloutToErrl(err,
                                             ERRL_CALLOUT_TYPE_HUID,
                                             G_sysConfigData.proc_huid,
                                             ERRL_CALLOUT_PRIORITY_LOW);

                            REQUEST_RESET(err);
                            occ_owns_lock = false;
                            break;
                        }
                        needRetry = true;
                    }
                    // else verify succeeded (OCC owns lock)
                }
            }
        } while (needRetry);
    }
    else
    {
        // Invalid engine
        INTR_TRAC_ERR("check_and_update_i2c_lock: Invalid engine specified: 0x%02X", i_engine);
    }

    return occ_owns_lock;

} // end check_and_update_i2c_lock()
Пример #5
0
//*************************************************************************
// Functions
//*************************************************************************
void amec_vectorize_core_sensor(sensor_t * l_sensor,
                                vectorSensor_t * l_vector,
                                const VECTOR_SENSOR_OP l_op,
                                uint16_t l_sensor_elem_array_gsid)
{
#define VECTOR_CREATE_FAILURE   1
#define VECTOR_ADD_ELEM_FAILURE 2

  int l_idx = 0;    // Used to index the for loops for vector create
  int l_rc  = 0;    // Indicates failure to add a sensor to vector
  uint16_t l_gsid  = 0xFFFF;
  errlHndl_t l_err = NULL;

  do
  {
    // Grab GSID for errl in case of failure
    l_gsid = l_sensor->gsid;

    // Vectorize the sensor
    sensor_vectorize(l_sensor,
        l_vector,
        l_op);

    // If vectorize worked, add elements to the vector sensor
    if(NULL != l_sensor->vector)
    {
      // Loop through cores
      for(l_idx = 0; l_idx < MAX_NUM_CORES; l_idx++)
      {
        // Add elements to the vector sensor
        sensor_vector_elem_add(l_sensor->vector,
                               l_idx,
                               AMECSENSOR_ARRAY_PTR(l_sensor_elem_array_gsid, l_idx));
        // If core is not present, disable this vector element
        if(!CORE_PRESENT(l_idx))
        {
          sensor_vector_elem_enable(l_sensor->vector,
                                    l_idx,
                                    0 /* Disable */);
        }
      }

      // Sanity check, we should have MAX_NUM_CORES entries in
      // vector sensor
      if(l_sensor->vector->size != MAX_NUM_CORES)
      {
        // Set l_rc and break out so that we can create an errl
        l_rc = VECTOR_ADD_ELEM_FAILURE;
        break;
      }
    }
    else
    {
      // Set l_rc and break out so that we can create an errl
      l_rc = VECTOR_CREATE_FAILURE;
      break;
    }
  }while(0);

  if(l_rc)
  {
    //If fail to create pore flex object then there is a problem.
    TRAC_ERR("Failed to vectorize sensor[0x%x, 0x%x]", l_gsid, l_rc );

    /* @
     * @errortype
     * @moduleid    AMEC_VECTORIZE_FW_SENSORS
     * @reasoncode  SSX_GENERIC_FAILURE
     * @userdata1   return code
     * @userdata2   gsid of failed sensor
     * @userdata4   OCC_NO_EXTENDED_RC
     * @devdesc     Firmware failure in call to vectorize sensor
     */
    l_err = createErrl(
        AMEC_VECTORIZE_FW_SENSORS,      //modId
        SSX_GENERIC_FAILURE,            //reasoncode
        OCC_NO_EXTENDED_RC,             //Extended reason code
        ERRL_SEV_UNRECOVERABLE,         //Severity
        NULL,//TODO: create trace       //Trace Buf
        DEFAULT_TRACE_SIZE,             //Trace Size
        l_rc,                           //userdata1
        l_gsid                          //userdata2
        );

    REQUEST_RESET(l_err);
  }
}
Пример #6
0
// Function Specification
//
// Name:  dbug_err_inject
//
// Description: Injects an error
//
// End Function Specification
void dbug_err_inject(const cmdh_fsp_cmd_t * i_cmd_ptr,
                           cmdh_fsp_rsp_t * i_rsp_ptr)
{
    errlHndl_t l_err;
    cmdh_dbug_inject_errl_query_t *l_cmd_ptr = (cmdh_dbug_inject_errl_query_t*) i_cmd_ptr;

    i_rsp_ptr->data_length[0] = 0;
    i_rsp_ptr->data_length[1] = 0;
    G_rsp_status = ERRL_RC_SUCCESS;

    if(!strncmp(l_cmd_ptr->comp, "RST", OCC_TRACE_NAME_SIZE))
    {
        l_err = createErrl(CMDH_DBUG_MID,     //modId
                           INTERNAL_FAILURE,             //reasoncode
                           OCC_NO_EXTENDED_RC,           //Extended reason code
                           ERRL_SEV_PREDICTIVE,          //Severity
                           NULL,                         //Trace Buf
                           DEFAULT_TRACE_SIZE,           //Trace Size
                           0xff,                         //userdata1
                           0);                           //userdata2

        if (INVALID_ERR_HNDL == l_err)
        {
            G_rsp_status = ERRL_RC_INTERNAL_FAIL;
        }

        addCalloutToErrl(l_err,
                         ERRL_CALLOUT_TYPE_HUID,         //callout type (HUID/CompID)
                         G_sysConfigData.proc_huid,      //callout data
                         ERRL_CALLOUT_PRIORITY_HIGH);    //priority

        REQUEST_RESET(l_err);
    }
    else
    {
        l_err = createErrl(CMDH_DBUG_MID,     //modId
                           INTERNAL_FAILURE,             //reasoncode
                           OCC_NO_EXTENDED_RC,           //Extended reason code
                           ERRL_SEV_UNRECOVERABLE,       //Severity
                           TRAC_get_td(l_cmd_ptr->comp), //Trace Buf
                           DEFAULT_TRACE_SIZE,           //Trace Size
                           0xff,                         //userdata1
                           0);                           //userdata2

        if (INVALID_ERR_HNDL == l_err)
        {
            G_rsp_status = ERRL_RC_INTERNAL_FAIL;
        }

        // Commit Error log
        commitErrl(&l_err);
    }

    if (G_rsp_status == ERRL_RC_INTERNAL_FAIL)
    {
        TRAC_ERR("cmdh_dbug_inject_errl: Fail creating ERR Log\n");
    }
    else
    {
        TRAC_INFO("cmdh_dbug_inject_errl: inject errl for COMP : %s\n", l_cmd_ptr->comp);
    }

    return;
}
Пример #7
0
// Function Specification
//
// Name:  amec_slave_init
//
// Description:  Perform initialization of any/all AMEC Slave Functions
//
// End Function Specification
void amec_slave_init()
{
  errlHndl_t l_err = NULL;   // Error handler
  int         rc   = 0;      // Return code
  int         rc2  = 0;      // Return code

  // Set the GPE Request Pointers to NULL in case the create fails.
  G_fw_timing.gpe0_timing_request = NULL;
  G_fw_timing.gpe1_timing_request = NULL;

  // Initializes the GPE routine that will be used to measure the worst case
  // timings for GPE0
  rc  = pore_flex_create( &G_gpe_nop_request[0],        //gpe_req for the task
                          &G_pore_gpe0_queue,           //queue
                          (void *) GPE_pore_nop,        //entry point
                          (uint32_t)  NULL,             //parm for the task
                          SSX_WAIT_FOREVER,             //no timeout
                          (AsyncRequestCallback) amec_slv_update_gpe_sensors,    //callback
                          (void *) GPE_ENGINE_0,        //callback argument
                          ASYNC_CALLBACK_IMMEDIATE );   //options

  // Initializes the GPE routine that will be used to measure the worst case
  // timings for GPE1
  rc2 = pore_flex_create( &G_gpe_nop_request[1],        //gpe_req for the task
                          &G_pore_gpe1_queue,           //queue
                          (void *)GPE_pore_nop,         //entry point
                          (uint32_t) NULL,              //parm for the task
                          SSX_WAIT_FOREVER,             //no timeout
                          (AsyncRequestCallback) amec_slv_update_gpe_sensors,    //callback
                          (void *) GPE_ENGINE_1,        //callback argument
                          ASYNC_CALLBACK_IMMEDIATE );   //options

  // If we couldn't create the poreFlex objects, there must be a major problem
  // so we will log an error and halt OCC.
  if( rc || rc2 )
  {
    //If fail to create pore flex object then there is a problem.
    TRAC_ERR("Failed to create GPE duration poreFlex object[0x%x, 0x%x]", rc, rc2 );

    /* @
     * @errortype
     * @moduleid    AMEC_INITIALIZE_FW_SENSORS
     * @reasoncode  SSX_GENERIC_FAILURE
     * @userdata1   return code - gpe0
     * @userdata2   return code - gpe1
     * @userdata4   OCC_NO_EXTENDED_RC
     * @devdesc     Failure to create PORE-GPE poreFlex object for FW timing
     *              analysis.
     *
     */
    l_err = createErrl(
        AMEC_INITIALIZE_FW_SENSORS,         //modId
        SSX_GENERIC_FAILURE,                //reasoncode
        OCC_NO_EXTENDED_RC,                 //Extended reason code
        ERRL_SEV_PREDICTIVE,                //Severity
        NULL,    //TODO: create trace       //Trace Buf
        DEFAULT_TRACE_SIZE,                 //Trace Size
        rc,                                 //userdata1
        rc2                                 //userdata2
    );

    REQUEST_RESET(l_err);
  }
  else
  {
    // Everything was successful, so set FW timing pointers to these
    // GPE Request objects
    G_fw_timing.gpe0_timing_request = &G_gpe_nop_request[0];
    G_fw_timing.gpe1_timing_request = &G_gpe_nop_request[1];
  }

  // Initialize Vector Sensors for AMEC use
  amec_init_vector_sensors();

  // Initialize AMEC internal parameters
  amec_init_gamec_struct();

}
Пример #8
0
// Function Specification
//
// Name:  proc_gpsm_dcm_sync_enable_pstates_smh
//
// Description:  Step through all the states & synch needed to enable
//               Pstates on both master & slave on a DCM.  This also
//               works for a SCM, which will act as DCM master (as far
//               as this function is concerned.)
//
// End Function Specification
void proc_gpsm_dcm_sync_enable_pstates_smh(void)
{
    // Static Locals
    static GpsmEnablePstatesMasterInfo l_master_info;
    static Pstate l_voltage_pstate, l_freq_pstate;

    // Local Variables
    int l_rc = 0;
    errlHndl_t l_errlHndl = NULL;

    if(!gpsm_dcm_slave_p())
    {
        // ---------------------------------------
        // SCM or DCM Master
        // ---------------------------------------
        switch( G_proc_dcm_sync_state.sync_state_master )
        {
            case PROC_GPSM_SYNC_NO_PSTATE_TABLE:
                // Waiting for Pstate Table from TMGT
                break;

            case PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED:
                PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master);
                // DCM SYNC (MasterWaitForSlave):  Wait for slave to install Pstate table
                if(gpsm_dcm_mode_p()){
                    if( G_proc_dcm_sync_state.sync_state_slave == PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED)
                    {
                        // Move to next state in state machine
                        G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER;
                    }
                }
                else
                {
                    // Move to next state in state machine
                    G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER;
                }
                break;

            case  PROC_GPSM_SYNC_READY_TO_ENABLE_MASTER:
                PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master);

                // Pstate tables has been installed, so now Master can start to enable Pstates
                l_rc = gpsm_enable_pstates_master(&l_master_info, &l_voltage_pstate, &l_freq_pstate);
                if(l_rc)
                {
                    // Error
                    TRAC_ERR("MSTR: gpsm_enable_pstates_master failed with rc=0x%08x", l_rc);
                    G_proc_dcm_sync_state.sync_state_master =  PROC_GPSM_SYNC_PSTATE_ERROR;
                    break;
                }
                TRAC_IMP("MSTR: Initial Pstates: V: %d, F: %d\n",l_voltage_pstate, l_freq_pstate);

                // DCM SYNC (Master2Slave):  Send V & F Pstate to slave
                G_proc_dcm_sync_state.dcm_pair_id = G_pob_id.chip_id;
                G_proc_dcm_sync_state.pstate_v = l_voltage_pstate;
                G_proc_dcm_sync_state.pstate_f = l_freq_pstate;

                // Move to next state in state machine
                G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED;
                break;

            case  PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED:
                PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master);
                // DCM SYNC (MasterWaitForSlave):  Wait for slave to complete gpsm_enable_pstates_slave()
                if(gpsm_dcm_mode_p()){
                    if( G_proc_dcm_sync_state.sync_state_slave == PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED)
                    {
                        // Move to next state in state machine
                        G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE;
                    }
                }
                else
                {
                    G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE;
                }
                break;


            case PROC_GPSM_SYNC_READY_TO_ENABLE_SLAVE:
                PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master);

                // Master does next step of enabling Pstates, now that slave has done it's enable
                l_rc = gpsm_enable_pstates_slave(&l_master_info, l_voltage_pstate, l_freq_pstate);
                if(l_rc)
                {
                    // Error
                    TRAC_ERR("MSTR: gpsm_enable_pstates_slave failed with rc=0x%08x", l_rc);
                    G_proc_dcm_sync_state.sync_state_master =  PROC_GPSM_SYNC_PSTATE_ERROR;
                    break;
                }
                TRAC_INFO("MSTR: Completed DCM Pstate Slave Init\n");
                G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED;
                break;

            case PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED:
                PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master);
                // Master puts this chip in Pstate HW mode
                l_rc = gpsm_hw_mode();
                if(l_rc)
                {
                    // Error
                    TRAC_ERR("MSTR: gpsm_hw_mode failed with rc=0x%08x", l_rc);
                    G_proc_dcm_sync_state.sync_state_master =  PROC_GPSM_SYNC_PSTATE_ERROR;
                    break;
                }
                // DCM SYNC (Master2Slave):  Tell Slave Master has entered HW mmode
                G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_HW_MODE;
                break;

            case PROC_GPSM_SYNC_PSTATE_HW_MODE:
                PROC_DBG("GPST DCM Master State %d\n",G_proc_dcm_sync_state.sync_state_master);
                // DCM SYNC (Master2Slave): Wait for Slave to Enter HW Mode
                if(gpsm_dcm_mode_p()){
                    if( G_proc_dcm_sync_state.sync_state_slave == PROC_GPSM_SYNC_PSTATE_HW_MODE)
                    {
                        TRAC_INFO("MSTR: Completed DCM Pstate Enable");
                        G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED;

                        //do additional setup if in kvm mode
                        proc_pstate_kvm_setup();
                    }
                }
                else
                {
                    G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED;
                    TRAC_INFO("MSTR: Completed SCM Pstate Enable");

                    //do additional setup if in kvm mode
                    proc_pstate_kvm_setup();
                }
                break;

            case PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED:
                // Final State
                // Pstates Enabled on both modules in DCM
                break;

           case PROC_GPSM_SYNC_PSTATE_ERROR:
               // Do nothing, something will have to come and kick us out of this state
               break;

            default:
                G_proc_dcm_sync_state.sync_state_master = PROC_GPSM_SYNC_NO_PSTATE_TABLE;
                break;
        }
    }
    else if (gpsm_dcm_slave_p())
    {
        // ---------------------------------------
        // DCM Slave
        //  - Don't need to check if DCM, since we can't come in here unless DCM
        // ---------------------------------------

       switch( G_proc_dcm_sync_state.sync_state_slave)
       {
           case PROC_GPSM_SYNC_NO_PSTATE_TABLE:
               // Waiting for Pstate Table from TMGT
               break;

           case PROC_GPSM_SYNC_PSTATE_TABLE_INSTALLED:
               // Pstate table has been installed, but slave needs to wait
               // for master before it can do anything else.

               // DCM SYNC (SlaveWaitForMaster):  Send V & F Pstate to slave
               // Wait for Master to complete gpsm_enable_pstates_master()
               // before running gpsm_enable_pstates_slave()
               if( G_proc_dcm_sync_state.sync_state_master == PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED)
               {
                   // Go to next state
                   G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED;
               }
               break;


           case PROC_GPSM_SYNC_PSTATE_MASTER_ENABLED:
               PROC_DBG("GPST DCM Slave State %d\n",G_proc_dcm_sync_state.sync_state_slave);
               // Read the initial Pstates from the data DCM master sent
               l_voltage_pstate = G_proc_dcm_sync_state.pstate_v;
               l_freq_pstate = G_proc_dcm_sync_state.pstate_f;

               // NULL is passed to this function when run on dcm slave
               l_rc = gpsm_enable_pstates_slave(NULL, l_voltage_pstate, l_freq_pstate);
               if(l_rc)
               {
                   // Error
                   TRAC_ERR("SLV: gpsm_enable_pstates_slave failed with rc=0x%08x", l_rc);
                   G_proc_dcm_sync_state.sync_state_slave =  PROC_GPSM_SYNC_PSTATE_ERROR;
                   break;
               }
               TRAC_INFO("SLV: Completed DCM Pstate Slave Init\n");

               // DCM SYNC (Slave2Master):
               // Tell Master that slave has run gpsm_enable_pstates_slave()

               // Go to next state
               G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED;
               break;

           case PROC_GPSM_SYNC_PSTATE_SLAVE_ENABLED:
               // DCM SYNC (SlaveWaitForMaster):  Wait for Master to run gpsm_hw_mode
               if( G_proc_dcm_sync_state.sync_state_master == PROC_GPSM_SYNC_PSTATE_HW_MODE)
               {
                   // Enter Pstate HW mode
                   l_rc = gpsm_hw_mode();
                   if(l_rc)
                   {
                       // Error
                       TRAC_ERR("SLV: gpsm_hw_mode failed with rc=0x%08x", l_rc);
                       G_proc_dcm_sync_state.sync_state_slave =  PROC_GPSM_SYNC_PSTATE_ERROR;
                       break;
                   }

                   // DCM SYNC (Slave2Master): Tell master that DCM slave made it to HW mode

                   // Go to next state
                   G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_HW_MODE;
               }
               break;

           case PROC_GPSM_SYNC_PSTATE_HW_MODE:
               // Slave & Master now both know each other has HW mode enabled
               if( G_proc_dcm_sync_state.sync_state_master == PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED)
               {
                   G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED;
                   TRAC_INFO("SLV: Completed DCM Pstate Enable");

                   //do additional setup if in kvm mode
                   proc_pstate_kvm_setup();
               }
               break;

           case PROC_GPSM_SYNC_PSTATE_HW_MODE_ENABLED:
               // Final State
               // Pstates Enabled on both modules in DCM
               break;

           case PROC_GPSM_SYNC_PSTATE_ERROR:
               // Do nothing, something will have to come and kick us out of this state
               break;

           default:
               G_proc_dcm_sync_state.sync_state_slave = PROC_GPSM_SYNC_NO_PSTATE_TABLE;
               break;

       }
    }

    // If we are in the process of running through the state machine,
    // we will do a sem_post to speed up the DCOM Thread and step us
    // through faster.
    if( PROC_GPSM_SYNC_NO_PSTATE_TABLE != proc_gpsm_dcm_sync_get_my_state()
        && !proc_is_hwpstate_enabled() )
    {
       ssx_semaphore_post(&G_dcomThreadWakeupSem);
    }

    // If we broke out of loops above because of an error, create an
    // error log and return it to caller.
    if(l_rc)
    {
        /* @
         * @errortype
         * @moduleid    PROC_ENABLE_PSTATES_SMH_MOD
         * @reasoncode  SSX_GENERIC_FAILURE
         * @userdata1   SRAM Address of the Pstate Table
         * @userdata2   Return Code of call that failed
         * @userdata4   OCC_NO_EXTENDED_RC
         * @devdesc     Failed to install Pstate Table
         */
        l_errlHndl = createErrl(
                PROC_ENABLE_PSTATES_SMH_MOD,        //modId
                SSX_GENERIC_FAILURE,                //reasoncode
                OCC_NO_EXTENDED_RC,                 //Extended reason code
                ERRL_SEV_PREDICTIVE,                //Severity
                NULL,    //TODO: create trace       //Trace Buf
                DEFAULT_TRACE_SIZE,                 //Trace Size
                (uint32_t) &G_global_pstate_table,  //userdata1
                l_rc);                              //userdata2
        addCalloutToErrl(l_errlHndl,
                         ERRL_CALLOUT_TYPE_COMPONENT_ID,
                         ERRL_COMPONENT_ID_FIRMWARE,
                         ERRL_CALLOUT_PRIORITY_HIGH);
        addCalloutToErrl(l_errlHndl,
                         ERRL_CALLOUT_TYPE_HUID,
                         G_sysConfigData.proc_huid,
                         ERRL_CALLOUT_PRIORITY_LOW);
        REQUEST_RESET(l_errlHndl);
    }

    return;
}
Пример #9
0
// Function Specification
//
// Name:  proc_pstate_kvm_setup
//
// Description: Get everything set up for KVM mode
//
// End Function Specification
void proc_pstate_kvm_setup()
{
    int                                 l_core;
    int                                 l_rc = 0;
    uint32_t                            l_configured_cores;
    pcbs_pcbspm_mode_reg_t              l_ppmr;
    pcbs_pmgp1_reg_t                    l_pmgp1;
    pcbs_power_management_bounds_reg_t  l_pmbr;
    errlHndl_t                          l_errlHndl;

    do
    {
        //only run this in KVM mode
        if(!G_sysConfigData.system_type.kvm)
        {
            break;
        }

        l_configured_cores = ~in32(PMC_CORE_DECONFIGURATION_REG);

        // Do per-core configuration
        for(l_core = 0; l_core < PGP_NCORES; l_core++, l_configured_cores <<= 1)
        {
            if(!(l_configured_cores & 0x80000000)) continue;

            //do read-modify-write to allow pmax clip to also clip voltage (not just frequency)
            l_rc = getscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core),
                       &(l_ppmr.value), NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: getscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d",
                         l_rc, l_core);
                break;
            }
            l_ppmr.fields.enable_clipping_of_global_pstate_req = 1;
            l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PCBSPM_MODE_REG, l_core),
                 l_ppmr.value, NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PCBSPM_MODE_REG) failed. rc=%d, hw_core=%d",
                         l_rc, l_core);
                break;
            }

            //per Vaidy Srinivasan, clear bit 11 in the Power Management GP1 register
            l_pmgp1.value = 0;
            l_pmgp1.fields.pm_spr_override_en = 1;
            l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_PMGP1_REG_AND, l_core),
                           ~l_pmgp1.value, NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_PMGB1_REG_OR) failed. rc=0x%08x, hw_core=%d",
                         l_rc, l_core);
                break;
            }

            //set pmax/pmin clip initial settings
            l_pmbr.value = 0;
            l_pmbr.fields.pmin_clip = gpst_pmin(&G_global_pstate_table)+1; //Per David Du, we must use pmin+1 to avoid gpsa hang
            l_pmbr.fields.pmax_clip = gpst_pmax(&G_global_pstate_table);
            l_rc = putscom_ffdc(CORE_CHIPLET_ADDRESS(PCBS_POWER_MANAGEMENT_BOUNDS_REG, l_core),
                           l_pmbr.value, NULL); //commit errors internally
            if(l_rc)
            {
                TRAC_ERR("proc_pstate_kvm_setup: putscom(PCBS_POWER_MANAGEMENT_BOUNDS_REG) failed. rc=0x%08x, hw_core=%d",
                         l_rc, l_core);
                break;
            }

        }// end of per-core config

        if(l_rc)
        {
            break;
        }

        // Set the voltage clipping register to match the pmax/pmin clip values set above.
        pmc_rail_bounds_register_t prbr;
        prbr.value = in32(PMC_RAIL_BOUNDS_REGISTER);
        prbr.fields.pmin_rail = gpst_pmin(&G_global_pstate_table);
        prbr.fields.pmax_rail = gpst_pmax(&G_global_pstate_table);
        TRAC_IMP("pmin clip pstate = %d, pmax clip pstate = %d", prbr.fields.pmin_rail, prbr.fields.pmax_rail);
        out32(PMC_RAIL_BOUNDS_REGISTER, prbr.value);

        // Initialize the sapphire table in SRAM (sets valid bit)
        populate_pstate_to_sapphire_tbl();

        // copy sram image into mainstore HOMER
        populate_sapphire_tbl_to_mem();
        TRAC_IMP("proc_pstate_kvm_setup: RUNNING IN KVM MODE");
    }while(0);

    if(l_rc)
    {
        // Create Error Log and request reset
        /* @
         * @errortype
         * @moduleid    PROC_PSTATE_KVM_SETUP_MOD
         * @reasoncode  PROC_SCOM_ERROR
         * @userdata1   l_configured_cores
         * @userdata2   Return Code of call that failed
         * @userdata4   OCC_NO_EXTENDED_RC
         * @devdesc     OCC failed to scom a core register
         */
        l_errlHndl = createErrl(
                PROC_PSTATE_KVM_SETUP_MOD,          //modId
                PROC_SCOM_ERROR,                    //reasoncode
                OCC_NO_EXTENDED_RC,                 //Extended reason code
                ERRL_SEV_PREDICTIVE,                //Severity
                NULL,                               //Trace Buf
                DEFAULT_TRACE_SIZE,                 //Trace Size
                l_configured_cores,                 //userdata1
                l_rc                                //userdata2
                );

        addCalloutToErrl(l_errlHndl,
                ERRL_CALLOUT_TYPE_HUID,
                G_sysConfigData.proc_huid,
                ERRL_CALLOUT_PRIORITY_HIGH);
        addCalloutToErrl(l_errlHndl,
                ERRL_CALLOUT_TYPE_COMPONENT_ID,
                ERRL_COMPONENT_ID_FIRMWARE,
                ERRL_CALLOUT_PRIORITY_MED);

        REQUEST_RESET(l_errlHndl);
    }
}
Пример #10
0
// Function Specification
//
// Name: dcom_error_check
//
// Description: keep track of failure counts
//
// End Function Specification
void dcom_error_check( const dcom_error_type_t i_error_type, const bool i_clear_error, const uint32_t i_orc, const uint32_t i_orc_ext)
{
    static uint16_t L_rx_slv_outbox_fail_count = 0;
    uint16_t        l_modId = 0;
    uint16_t        *l_count_ptr = NULL;

    if ( i_error_type == SLAVE_INBOX )
    {
        l_count_ptr = &G_dcomSlvInboxCounter.currentFailCount;
        l_modId = DCOM_MID_TASK_RX_SLV_INBOX;
    }
    // if the i_error_type == SLAVE_OUTBOX then set the outbox count
    else
    {
        l_count_ptr = &L_rx_slv_outbox_fail_count;
        l_modId = DCOM_MID_TASK_RX_SLV_OUTBOX;
    }

    if ( i_clear_error )
    {
        *l_count_ptr = 0;
    }
    else
    {
        (*l_count_ptr)++;

        if ( *l_count_ptr == DCOM_250us_GAP )
        {
            // Trace an imp trace log
            TRAC_IMP("l_count_ptr[%d], L_outbox[%d], L_inbox[%d]",
                *l_count_ptr,
                L_rx_slv_outbox_fail_count,
                G_dcomSlvInboxCounter.currentFailCount );
        }
        else if ( *l_count_ptr == DCOM_4MS_GAP )
        {
            // Create and commit error log
            // NOTE: SRC tags are NOT needed here, they are
            //       taken care of by the caller
            errlHndl_t  l_errl = createErrl(
                l_modId,                        //ModId
                i_orc,                          //Reasoncode
                i_orc_ext,                      //Extended reasoncode
                ERRL_SEV_UNRECOVERABLE,         //Severity
                NULL,                           //Trace Buf
                DEFAULT_TRACE_SIZE,             //Trace Size
                *l_count_ptr,                   //Userdata1
                0                               //Userdata2
                );

            // Commit log
            commitErrl( &l_errl );

            // Call request nominal macro to change state
            REQUEST_NOMINAL();
        }
        else if ( *l_count_ptr == DCOM_1S_GAP )
        {
            // Create and commit error log
            // NOTE: SRC tags are NOT needed here, they are
            //       taken care of by the caller
            errlHndl_t  l_errl = createErrl(
                l_modId,                        //ModId
                i_orc,                          //Reasoncode
                i_orc_ext,                      //Extended reasoncode
                ERRL_SEV_UNRECOVERABLE,         //Severity
                NULL,                           //Trace Buf
                DEFAULT_TRACE_SIZE,             //Trace Size
                *l_count_ptr,                   //Userdata1
                0                               //Userdata2
                );

            // Commit log
            // Call request reset macro
            REQUEST_RESET(l_errl);
        }
    }
}
Пример #11
0
// Function Specification
//
// Name: dcom_initialize_pbax_queues
//
// Description: Initialize the PBAX Queues for sending doorbells
//
// End Function Specification
void dcom_initialize_pbax_queues(void)
{
    // SSX return codes
    int l_rc = 0;

    do
    {
        //disabled pbax send before configuring PBAX
        pbax_send_disable();

        // TODO: With the new design, PBAX node and chip IDs are set by hostboot
        //       Remove these ID parameters from the pbax_configure function?
        l_rc = pbax_configure(G_occ_role,                     // master
                              G_pbax_id.node_id,              // node id
                              G_pbax_id.chip_id,              // chipd id
                              PBAX_CONFIGURE_RCV_GROUP_MASK); // group_mask

        if(l_rc != 0)
        {
            TRAC_ERR("Error configuring the pbax rc[%x]",l_rc);
            break;
        }

        //enabled pbax send does not return errors
        pbax_send_enable();

        if(G_occ_role == OCC_SLAVE)
        {
            // create pbax rx queue 1
            l_rc = pbax_queue_create( &G_pbax_read_queue[1], //queue
                    ASYNC_ENGINE_PBAX_PUSH1,                 //engine
                    G_pbax_queue_rx1_buffer,                 //cq base
                    NUM_ENTRIES_PBAX_QUEUE1,                 //cq entries
                    PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE       //protocol
                    );

            if(l_rc != 0)
            {
                TRAC_ERR("Error creating pbax queue 1 rc[%x]",l_rc);
                break;
            }

            // create pbax rx queue o
            l_rc = pbax_queue_create( &G_pbax_read_queue[0],//queue
                    ASYNC_ENGINE_PBAX_PUSH0,                //engine
                    G_pbax_queue_rx0_buffer,                //cq base
                    NUM_ENTRIES_PBAX_QUEUE0,                //cq entries
                    PBAX_INTERRUPT_PROTOCOL_AGGRESSIVE      //protocol
                    );

            if(l_rc != 0)
            {
                TRAC_ERR("Error creating pbax queue 0 rc[%x]",l_rc);
                break;
            }

            // enable the read 1 queue
            l_rc = pbax_queue_enable(&G_pbax_read_queue[1]);

            if(l_rc != 0)
            {
                TRAC_ERR("Error enabling queue 1 rc[%x]",l_rc);
                break;
            }
        }

        if(G_occ_role == OCC_MASTER)
        {
            l_rc = pbax_target_create( &G_pbax_multicast_target,    // target,
                    PBAX_BROADCAST,                                 // type
                    PBAX_SYSTEM,                                    // scope TODO
                    0,                                              // queue
                    G_pbax_id.node_id,                              // node
                    PBAX_BROADCAST_GROUP);                          // chip_or_group

            if(l_rc != 0)
            {
                TRAC_ERR("Error creating pbax target for master TX operations SSXrc[%x]",l_rc);
                break;
            }

        }

    }while(0);

    if(l_rc)
    {
        /* @
         * @errortype
         * @moduleid    DCOM_MID_INIT_PBAX_QUEUES
         * @reasoncode  SSX_GENERIC_FAILURE
         * @userdata1   SSX RC
         * @userdata4   OCC_NO_EXTENDED_RC
         * @devdesc     Failure initializing the PBAX queues
         */
        errlHndl_t  l_errl = createErrl(
            DCOM_MID_INIT_PBAX_QUEUES,          //ModId
            SSX_GENERIC_FAILURE,                //Reasoncode
            OCC_NO_EXTENDED_RC,                 //Extended reasoncode
            ERRL_SEV_UNRECOVERABLE,             //Severity
            NULL,                               //Trace Buf
            DEFAULT_TRACE_SIZE,                 //Trace Size
            l_rc,                               //Userdata1
            0                                   //Userdata2
            );

        // Commit log and request reset
        REQUEST_RESET(l_errl);
    }
}