Esempio n. 1
0
File: dimm.c Progetto: ploetzma/occ
// 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()
Esempio n. 2
0
// Function Specification
//
// Name: proc_check_for_sapphire_updates
//
// Description: Checks if the sapphire table needs an update
//              and updates if necessary.
//
// End Function Specification
void proc_check_for_sapphire_updates()
{
    uint8_t l_latest_throttle_reason;

    //If safe state is requested then that overrides anything from amec
    if(isSafeStateRequested())
    {
        l_latest_throttle_reason = OCC_RESET;
    }
    else
    {
        l_latest_throttle_reason = G_amec_kvm_throt_reason;
    }

    //If the throttle reason changed, update it in the HOMER
    if(G_sapphire_table.config.throttle != l_latest_throttle_reason)
    {
        TRAC_INFO("proc_check_for_sapphire_updates: throttle reason changed to %d", l_latest_throttle_reason);
        G_sapphire_table.config.throttle = l_latest_throttle_reason;
        G_sapphire_table.config.version = 0x02; // default 0x02
        G_sapphire_table.config.valid = 0x01; //default 0x01
        populate_sapphire_tbl_to_mem();
    }
}
Esempio n. 3
0
// Function Specification
//
// Name:  Dcom_thread_routine
//
// Description: Purpose of this task is to handle messages passed from
//              Master to Slave and vice versa.
//
//              Nothing in this thread should be time-critical, but should
//              happen more often than the 1-second that other threads run
//              at.
//
//              This thread currently runs ~1ms, based on the RTL loop of
//              250us.
//
//              FWIW -- It is pointless to set this thread to run any more
//              often than the length of the RTL loop, since it is acting
//              on data passed back and forth via that loop.
//
// End Function Specification
void Dcom_thread_routine(void *arg)
{
    OCC_STATE l_newOccState  = 0;
    OCC_MODE  l_newOccMode   = 0;
    SsxTimer  l_timeout_timer;
    errlHndl_t l_errlHndl = NULL;
    // --------------------------------------------------
    // Create a timer that pops every 10 seconds to wake up
    // this thread, in case a semaphore never gets posted.
    // TODO: Is this really needed?
    // --------------------------------------------------
    ssx_timer_create(&l_timeout_timer,
                     (SsxTimerCallback) ssx_semaphore_post,
                     (void *) &G_dcomThreadWakeupSem);
    ssx_timer_schedule(&l_timeout_timer,
                       SSX_SECONDS(10),
                       SSX_SECONDS(10));

    for(;;)
    {
        // --------------------------------------------------
        // Wait on Semaphore until we get new data over DCOM
        // (signalled by sem_post() or timeout occurs.
        // Sem timeout is designed to be the slowest
        // interval we will attempt to run this thread at.
        // --------------------------------------------------

        // Wait for sem_post before we run through this thread.
        ssx_semaphore_pend(&G_dcomThreadWakeupSem, SSX_WAIT_FOREVER);

        // --------------------------------------------------
        // Counter to ensure thread is running (can wrap)
        // --------------------------------------------------
        G_dcom_thread_counter++;

        // --------------------------------------------------
        // Check if we need to update the sapphire table
        // --------------------------------------------------
        if(G_sysConfigData.system_type.kvm)
        {
            proc_check_for_sapphire_updates();
        }

        // --------------------------------------------------
        // Set Mode and State Based on Master
        // --------------------------------------------------
        l_newOccState = (G_occ_master_state == CURRENT_STATE()) ? OCC_STATE_NOCHANGE : G_occ_master_state;

        if(G_sysConfigData.system_type.kvm)
        {
            l_newOccMode  = (G_occ_master_mode  == G_occ_external_req_mode_kvm ) ? OCC_MODE_NOCHANGE : G_occ_master_mode;
        }
        else
        {
            l_newOccMode  = (G_occ_master_mode  == CURRENT_MODE() ) ? OCC_MODE_NOCHANGE : G_occ_master_mode;
        }

        // Override State if SAFE state is requested
        l_newOccState = ( isSafeStateRequested() ) ? OCC_STATE_SAFE : l_newOccState;

        // Override State if we are in SAFE state already
        l_newOccState = ( OCC_STATE_SAFE == CURRENT_STATE() ) ? OCC_STATE_NOCHANGE : l_newOccState;

        if( (OCC_STATE_NOCHANGE != l_newOccState)
            || (OCC_MODE_NOCHANGE != l_newOccMode) )
        {
            // If we're active, then we should always process the mode change first
            // If we're not active, then we should always process the state change first
            if(OCC_STATE_ACTIVE == CURRENT_STATE())
            {
                // Set the new mode
                l_errlHndl = SMGR_set_mode(l_newOccMode, 0 /* TODO V/F */ );
                if(l_errlHndl)
                {
                    commitErrl(&l_errlHndl);
                }
                // Set the new state
                l_errlHndl = SMGR_set_state(l_newOccState);
                if(l_errlHndl)
                {
                    commitErrl(&l_errlHndl);
                }
            }
            else
            {
                // Set the new state
                l_errlHndl = SMGR_set_state(l_newOccState);
                                if(l_errlHndl)
                {
                    commitErrl(&l_errlHndl);
                }
                // Set the new mode
                l_errlHndl = SMGR_set_mode(l_newOccMode, 0 /* TODO V/F */ );
                if(l_errlHndl)
                {
                    commitErrl(&l_errlHndl);
                }
            }
        }

        // --------------------------------------------------
        // DCM PStates
        // \_ can do sem_post to increment through state machine
        // --------------------------------------------------
        if(OCC_STATE_SAFE != CURRENT_STATE())
        {
            proc_gpsm_dcm_sync_enable_pstates_smh();
        }

        // --------------------------------------------------
        // SSX Sleep
        // --------------------------------------------------
        // Even if semaphores are continually posted, there is no reason
        // for us to run this thread any more often than once every 250us
        // so we don't starve any other thread
        ssx_sleep(SSX_MICROSECONDS(250));
    }
}
Esempio n. 4
0
File: dcom.c Progetto: ploetzma/occ
// Function Specification
//
// Name: task_dcom_parse_occfwmsg
//
// Description: Purpose of this task is to handle and acknowledge
//              fw messages passed from Master to Slave and vice versa.
//
// End Function Specification
void task_dcom_parse_occfwmsg(task_t *i_self)
{
    if(G_occ_role == OCC_MASTER)
    {
        // Local slave index counter
        uint32_t l_slv_idx      = 0;

        // Loop and collect occ data for each slave occ
        for(; l_slv_idx < MAX_OCCS; l_slv_idx++)
        {
            // Verify all slave are in correct state and mode
            G_dcom_slv_outbox_rx[l_slv_idx].occ_fw_mailbox[0] = CURRENT_STATE();

            if(G_sysConfigData.system_type.kvm )
            {
                G_dcom_slv_outbox_rx[l_slv_idx].occ_fw_mailbox[1] = G_occ_external_req_mode_kvm;
            }
            else
            {
                G_dcom_slv_outbox_rx[l_slv_idx].occ_fw_mailbox[1] = CURRENT_MODE();
            }

            // Acknowledge all slave event flags
            G_slave_event_flags_ack[l_slv_idx] = G_dcom_slv_outbox_rx[l_slv_idx].occ_fw_mailbox[3];

            // Clear master event flags if slave has acknowledged them and the event has cleared
            G_master_event_flags &= ~G_dcom_slv_outbox_rx[l_slv_idx].occ_fw_mailbox[2];

        }

    }//End master role check

    // Check if master has changed state and mode and update if changed
    // so that we can handle it in a thread.
    if( (G_occ_master_state != G_dcom_slv_inbox_rx.occ_fw_mailbox[0])
        || (G_occ_master_mode != G_dcom_slv_inbox_rx.occ_fw_mailbox[1]) )
    {
        if( ! isSafeStateRequested() )
        {
            G_occ_master_state = G_dcom_slv_inbox_rx.occ_fw_mailbox[0];
            G_occ_master_mode  = G_dcom_slv_inbox_rx.occ_fw_mailbox[1];
            ssx_semaphore_post(&G_dcomThreadWakeupSem);
        }
    }

    // If we are master, we don't want to update based on
    // the data sent to us, because it corrupts the 'golden' data
    // If we are in standby, we don't want to update because
    // the data may not have been set up yet, and would be set to zero.
    if(OCC_MASTER != G_occ_role )
    {
        // Update the system mode frequencies if they have changed
        int l_mode    = 0;
        bool l_change = FALSE;
        bool l_all_zero = TRUE;

        // Check if all values are zero
        for(l_mode = 0; l_mode<OCC_MODE_COUNT; l_mode++)
        {
            if( (0 != G_dcom_slv_inbox_rx.sys_mode_freq.table[l_mode]) )
            {
                l_all_zero = FALSE;
                break;
            }
        }

        extern data_cnfg_t * G_data_cnfg;
        if( l_all_zero == FALSE)
        {
            for(l_mode =0; l_mode<OCC_MODE_COUNT; l_mode++)
            {
                // Don't trust a frequency of 0x0000
                if( (0 != G_dcom_slv_inbox_rx.sys_mode_freq.table[l_mode]) )
                {
                    if(G_sysConfigData.sys_mode_freq.table[l_mode]
                            != G_dcom_slv_inbox_rx.sys_mode_freq.table[l_mode])
                    {
                        TRAC_INFO("New Frequency for Mode %d: Old: %d MHz -> New: %d MHz",l_mode,
                                G_sysConfigData.sys_mode_freq.table[l_mode],
                                G_dcom_slv_inbox_rx.sys_mode_freq.table[l_mode]);

                        // Update mode frequency
                        G_sysConfigData.sys_mode_freq.table[l_mode] =
                            G_dcom_slv_inbox_rx.sys_mode_freq.table[l_mode];

                        l_change = TRUE;
                    }
                }
            }

            if(l_change)
            {
                // Update "update count" for debug purposes
                G_sysConfigData.sys_mode_freq.update_count =
                    G_dcom_slv_inbox_rx.sys_mode_freq.update_count;

                // Change Data Request Mask to indicate we got this data
                extern data_cnfg_t * G_data_cnfg;
                G_data_cnfg->data_mask |= DATA_MASK_FREQ_PRESENT;

                // Notify AMEC that the frequencies have changed
                AMEC_data_change(DATA_MASK_FREQ_PRESENT);
            }
        }
        else
        {
            // Clear Data Request Mask and data
            G_data_cnfg->data_mask &= (~DATA_MASK_FREQ_PRESENT);
            memset(&G_sysConfigData.sys_mode_freq.table[0], 0, sizeof(G_sysConfigData.sys_mode_freq.table));
        }
    }

    // Copy mnfg parameters into g_amec structure
    g_amec->foverride_enable = G_dcom_slv_inbox_rx.foverride_enable;
    g_amec->foverride = G_dcom_slv_inbox_rx.foverride;

    // Copy IPS parameters sent by Master OCC
    g_amec->slv_ips_freq_request = G_dcom_slv_inbox_rx.ips_freq_request;

    // Copy DPS tunable parameters sent by Master OCC if required
    if(G_dcom_slv_inbox_rx.tunable_param_overwrite)
    {
        AMEC_part_overwrite_dps_parameters();

        if(G_dcom_slv_inbox_rx.tunable_param_overwrite == 1)
        {
            g_amec->slv_dps_param_overwrite = TRUE;
        }
        else
        {
            g_amec->slv_dps_param_overwrite = FALSE;
        }
    }

    // Copy soft frequency boundaries sent by Master OCC
    g_amec->part_config.part_list[0].soft_fmin = G_dcom_slv_inbox_rx.soft_fmin;
    g_amec->part_config.part_list[0].soft_fmax = G_dcom_slv_inbox_rx.soft_fmax;

    // acknowledge all masters event flags
    G_master_event_flags_ack = G_dcom_slv_inbox_rx.occ_fw_mailbox[2];

    // clear slave event flags if master has acknowledged them and the event has cleared
    G_slave_event_flags = (G_slave_event_flags & (~(G_dcom_slv_inbox_rx.occ_fw_mailbox[3])));
}