Пример #1
0
// Function Specification
//
// Name:  cmdh_mnfg_read_pstate_table
//
// Description: This function handles the manufacturing command to read
// the generated Pstate table from main memory 3K blocks at a time
//
// End Function Specification
uint8_t cmdh_mnfg_read_pstate_table(const cmdh_fsp_cmd_t * i_cmd_ptr,
                                            cmdh_fsp_rsp_t * o_rsp_ptr)
{
    uint8_t                       l_rc = ERRL_RC_SUCCESS;
    uint16_t                      l_datalength = 0;
    uint16_t                      l_resp_data_length = 0;
    uint32_t                      block_offset = 0;
    uint32_t                      main_mem_address = 0;
    int                           l_ssxrc = SSX_OK;
    mnfg_read_pstate_table_cmd_t  *l_cmd_ptr = (mnfg_read_pstate_table_cmd_t*) i_cmd_ptr;

    do
    {
        // Check command packet data length
        l_datalength = CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr);
        if(l_datalength != (sizeof(mnfg_read_pstate_table_cmd_t) -
                            sizeof(cmdh_fsp_cmd_header_t)))
        {
            TRAC_ERR("cmdh_mnfg_read_pstate_table: incorrect data length. exp[%d] act[%d]",
                     (sizeof(mnfg_read_pstate_table_cmd_t) -
                      sizeof(cmdh_fsp_cmd_header_t)),
                      l_datalength);
            l_rc = ERRL_RC_INVALID_CMD_LEN;
            break;
        }

        // Process request
        if(l_cmd_ptr->request == MFG_PSTATE_READ_REQUEST_QUERY)
        {
            memcpy(&o_rsp_ptr->data[0], &G_pgpe_header.generated_pstate_table_homer_offset, 4);
            memcpy(&o_rsp_ptr->data[4], &G_pgpe_header.generated_pstate_table_length, 4);
            l_resp_data_length = MFG_PSTATE_READ_QUERY_RSP_SIZE;

            TRAC_INFO("cmdh_mnfg_read_pstate_table: Query table memory offset[0x%08x] table length[%d]",
                     G_pgpe_header.generated_pstate_table_homer_offset,
                     G_pgpe_header.generated_pstate_table_length);
            break;
        }

        // Calculate the starting main memory address for block to read
        block_offset = MFG_PSTATE_READ_MAX_RSP_SIZE * l_cmd_ptr->request;
        if(block_offset > G_pgpe_header.generated_pstate_table_length)
        {
            TRAC_ERR("cmdh_mnfg_read_pstate_table: Block request %d out of range.  Pstate Table size %d",
                     l_cmd_ptr->request,
                     G_pgpe_header.generated_pstate_table_length);
            l_rc = ERRL_RC_INVALID_DATA;
            break;
        }

        main_mem_address = G_pgpe_header.generated_pstate_table_homer_offset + block_offset;

        // Copy Pstate table from main memory to SRAM
        // Set up a copy request
        l_ssxrc = bce_request_create(&G_mfg_pba_request,                  // block copy object
                                     &G_pba_bcde_queue,                   // mainstore to sram copy engine
                                     main_mem_address,                    // mainstore address
                                     (uint32_t)&G_mfg_read_pstate_table,  // sram starting address
                                     sizeof(mfg_read_pstate_table_t),     // size of copy
                                     SSX_SECONDS(1),                      // timeout
                                     NULL,                                // no call back
                                     NULL,                                // no call back arguments
                                     ASYNC_REQUEST_BLOCKING);             // blocking request

        if(l_ssxrc != SSX_OK)
        {
            TRAC_ERR("cmdh_mnfg_read_pstate_table: BCDE request create failure rc=[%08X]", -l_ssxrc);
            l_rc = ERRL_RC_INTERNAL_FAIL;
            break;
        }

        // Do actual copying
        l_ssxrc = bce_request_schedule(&G_mfg_pba_request);

        if(l_ssxrc != SSX_OK)
        {
            TRAC_ERR("cmdh_mnfg_read_pstate_table: BCE request schedule failure rc=[%08X]", -l_ssxrc);
            l_rc = ERRL_RC_INTERNAL_FAIL;
            break;
        }

        // Determine the rsp data length
        l_resp_data_length = MFG_PSTATE_READ_MAX_RSP_SIZE;

        if((block_offset + MFG_PSTATE_READ_MAX_RSP_SIZE) > G_pgpe_header.generated_pstate_table_length)
        {
            l_resp_data_length = G_pgpe_header.generated_pstate_table_length - block_offset;
        }

        // Copy to response buffer
        memcpy(o_rsp_ptr->data,
               &G_mfg_read_pstate_table,
               l_resp_data_length);

        TRAC_INFO("cmdh_mnfg_read_pstate_table: Read from main memory[0x%08x] block offset[%d] length[%d]",
                   main_mem_address,
                   block_offset,
                   l_resp_data_length);
    }while(0);

    // Populate the response data header
    G_rsp_status = l_rc;
    o_rsp_ptr->data_length[0] = ((uint8_t *)&l_resp_data_length)[0];
    o_rsp_ptr->data_length[1] = ((uint8_t *)&l_resp_data_length)[1];

    return l_rc;
}
Пример #2
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));
    }
}
Пример #3
0
// Function Specification
//
// Name:  apss_initialize
//
// Description: Completes all APSS initialization including GPIOs, altitude and
//              mode
//
// End Function Specification
errlHndl_t apss_initialize()
{
    errlHndl_t l_err = NULL;
    PoreFlex request;

    // Setup the GPIO init structure to pass to the GPE program
    G_gpe_apss_initialize_gpio_args.error.error = 0;
    G_gpe_apss_initialize_gpio_args.error.ffdc = 0;
    G_gpe_apss_initialize_gpio_args.config0.direction
                                = G_gpio_config[0].direction;
    G_gpe_apss_initialize_gpio_args.config0.drive
                                = G_gpio_config[0].drive;
    G_gpe_apss_initialize_gpio_args.config0.interrupt
                                = G_gpio_config[0].interrupt;
    G_gpe_apss_initialize_gpio_args.config1.direction
                                = G_gpio_config[1].direction;
    G_gpe_apss_initialize_gpio_args.config1.drive = G_gpio_config[1].drive;
    G_gpe_apss_initialize_gpio_args.config1.interrupt
                                = G_gpio_config[1].interrupt;

    // Create/schedule GPE_apss_initialize_gpio and wait for it to complete (BLOCKING)
    TRAC_INFO("Creating request for GPE_apss_initialize_gpio");
    pore_flex_create(&request,                                  // request
                     &G_pore_gpe0_queue,                        // queue
                     (void*)GPE_apss_initialize_gpio,           // GPE entry_point
                     (uint32_t)&G_gpe_apss_initialize_gpio_args,// GPE argument_ptr
                     SSX_SECONDS(5),                            // timeout
                     NULL,                                      // callback
                     NULL,                                      // callback arg
                     ASYNC_REQUEST_BLOCKING);                   // options
    // Schedule the request to be executed
    pore_flex_schedule(&request);

    // Check for a timeout, will create the error log later
    // NOTE: As of 2013/07/16, simics will still fail here on a OCC reset

    if(ASYNC_REQUEST_STATE_TIMED_OUT == request.request.completion_state)
    {
        // For whatever reason, we hit a timeout.  It could be either
        // that the HW did not work, or the request didn't ever make
        // it to the front of the queue.
        // Let's log an error, and include the FFDC data if it was
        // generated.
        TRAC_ERR("Timeout communicating with PORE-GPE for APSS Init");
    }

    TRAC_INFO("GPE_apss_initialize_gpio completed w/rc=0x%08x\n",
              request.request.completion_state);

    // Only continue if completed without errors...
    if (ASYNC_REQUEST_STATE_COMPLETE == request.request.completion_state)
    {
        // Setup the composite mode structure to pass to the GPE program
        G_gpe_apss_set_composite_mode_args.error.error = 0;
        G_gpe_apss_set_composite_mode_args.error.ffdc = 0;
        G_gpe_apss_set_composite_mode_args.config.numAdcChannelsToRead =
                        G_apss_composite_config.numAdcChannelsToRead;
        G_gpe_apss_set_composite_mode_args.config.numGpioPortsToRead =
                        G_apss_composite_config.numGpioPortsToRead;

        // Create/schedule GPE_apss_set_composite_mode and wait for it to complete (BLOCKING)
        TRAC_INFO("Creating request for GPE_apss_set_composite_mode");
        pore_flex_create(&request,                                    // request
                         &G_pore_gpe0_queue,                          // queue
                         (void*)GPE_apss_set_composite_mode,          // GPE entry_point
                         (uint32_t)&G_gpe_apss_set_composite_mode_args,// GPE argument_ptr
                         SSX_SECONDS(5),                              // timeout
                         NULL,                                        // callback
                         NULL,                                        // callback arg
                         ASYNC_REQUEST_BLOCKING);                     // options
        pore_flex_schedule(&request);

        // Check for a timeout, will create the error log later
        if(ASYNC_REQUEST_STATE_TIMED_OUT == request.request.completion_state)
        {
            // For whatever reason, we hit a timeout.  It could be either
            // that the HW did not work, or the request didn't ever make
            // it to the front of the queue.
            // Let's log an error, and include the FFDC data if it was
            // generated.
            TRAC_ERR("Timeout communicating with PORE-GPE for APSS Init");
        }

        TRAC_INFO("GPE_apss_set_composite_mode completed w/rc=0x%08x",
                  request.request.completion_state);

        if (ASYNC_REQUEST_STATE_COMPLETE != request.request.completion_state)
        {
            /*
             * @errortype
             * @moduleid    PSS_MID_APSS_INIT
             * @reasoncode  INTERNAL_FAILURE
             * @userdata1   GPE returned rc code
             * @userdata2   GPE returned abort code
             * @userdata4   ERC_PSS_COMPOSITE_MODE_FAIL
             * @devdesc     Failure from GPE for setting composite mode on
             *              APSS
             */
            l_err = createErrl(PSS_MID_APSS_INIT,               // i_modId,
                               INTERNAL_FAILURE,                // i_reasonCode,
                               ERC_PSS_COMPOSITE_MODE_FAIL,     // extended reason code
                               ERRL_SEV_UNRECOVERABLE,          // i_severity
                               NULL,                            // i_trace,
                               0x0000,                          // i_traceSz,
                               request.request.completion_state,       // i_userData1,
                               request.request.abort_state);           // i_userData2
            addUsrDtlsToErrl(l_err,
                             (uint8_t*)&G_gpe_apss_set_composite_mode_args,
                             sizeof(G_gpe_apss_set_composite_mode_args),
                             ERRL_STRUCT_VERSION_1,
                             ERRL_USR_DTL_TRACE_DATA);

            // Returning an error log will cause us to go to safe
            // state so we can report error to FSP
        }


        TRAC_INFO("apss_initialize: Creating request G_meas_start_request.");
        //Create the request for measure start. Scheduling will happen in apss.c
        pore_flex_create(&G_meas_start_request,
                         &G_pore_gpe0_queue,                          // queue
                         (void*)GPE_apss_start_pwr_meas_read,         // entry_point
                         (uint32_t)&G_gpe_start_pwr_meas_read_args,   // entry_point arg
                         SSX_WAIT_FOREVER,                            // no timeout
                         NULL,                                        // callback
                         NULL,                                        // callback arg
                         ASYNC_CALLBACK_IMMEDIATE);                   // options

        TRAC_INFO("apss_initialize: Creating request G_meas_cont_request.");
        //Create the request for measure continue. Scheduling will happen in apss.c
        pore_flex_create(&G_meas_cont_request,
                         &G_pore_gpe0_queue,                          // request
                         (void*)GPE_apss_continue_pwr_meas_read,      // entry_point
                         (uint32_t)&G_gpe_continue_pwr_meas_read_args, // entry_point arg
                         SSX_WAIT_FOREVER,                            // no timeout
                         NULL,                                        // callback
                         NULL,                                        // callback arg
                         ASYNC_CALLBACK_IMMEDIATE);                   // options

        TRAC_INFO("apss_initialize: Creating request G_meas_complete_request.");
        //Create the request for measure complete. Scheduling will happen in apss.c
        pore_flex_create(&G_meas_complete_request,
                         &G_pore_gpe0_queue,                          // queue
                         (void*)GPE_apss_complete_pwr_meas_read,      // entry_point
                         (uint32_t)&G_gpe_complete_pwr_meas_read_args,// entry_point arg
                         SSX_WAIT_FOREVER,                            // no timeout
                         (AsyncRequestCallback)reformat_meas_data,    // callback,
                         (void*)NULL,                                 // callback arg
                         ASYNC_CALLBACK_IMMEDIATE);                   // options

    }
    else
    {
        /*
         * @errortype
         * @moduleid    PSS_MID_APSS_INIT
         * @reasoncode  INTERNAL_FAILURE
         * @userdata1   GPE returned rc code
         * @userdata2   GPE returned abort code
         * @userdata4   ERC_PSS_GPIO_INIT_FAIL
         * @devdesc     Failure from GPE for gpio initialization on APSS
         */
        l_err = createErrl(PSS_MID_APSS_INIT,           // i_modId,
                           INTERNAL_FAILURE,            // i_reasonCode,
                           ERC_PSS_GPIO_INIT_FAIL,      // extended reason code
                           ERRL_SEV_UNRECOVERABLE,      // i_severity
                           NULL,                        // tracDesc_t i_trace,
                           0x0000,                      // i_traceSz,
                           request.request.completion_state,   // i_userData1,
                           request.request.abort_state);       // i_userData2
        addUsrDtlsToErrl(l_err,
                         (uint8_t*)&G_gpe_apss_initialize_gpio_args,
                         sizeof(G_gpe_apss_initialize_gpio_args),
                         ERRL_STRUCT_VERSION_1,
                         ERRL_USR_DTL_TRACE_DATA);

        // Returning an error log will cause us to go to safe
        // state so we can report error to FSP
    }

    return l_err;
}
Пример #4
0
// Function Specification
//
// Name: cmdh_snapshot_sync
//
// Description: Resets the snapshot buffer array and starts a new snapshot buffer from time 0.
//
// End Function Specification
errlHndl_t cmdh_snapshot_sync(const cmdh_fsp_cmd_t * i_cmd_ptr,
                                    cmdh_fsp_rsp_t * o_rsp_ptr)
{
    cmdh_snapshot_sync_query_t      *l_cmd_ptr = (cmdh_snapshot_sync_query_t *) i_cmd_ptr;
    cmdh_snapshot_sync_resp_t       *l_resp_ptr = (cmdh_snapshot_sync_resp_t *) o_rsp_ptr;
    errlHndl_t                      l_err = NULL;
    uint8_t                         l_query_sz = 0;
    ERRL_RC                         l_rc = 0;

    do
    {
        l_query_sz = CMDH_DATALEN_FIELD_UINT16(i_cmd_ptr);
        // Verify query data size
        if(l_query_sz != CMDH_SNAPSHOT_SYNC_DATA_SIZE)
        {
            TRAC_ERR("cmdh_snapshot_sync: Received an invalid packet size. Expecting 1 byte, received:%i",
                     l_query_sz);
            l_rc = ERRL_RC_INVALID_CMD_LEN;
            break;
        }

        l_cmd_ptr = (cmdh_snapshot_sync_query_t *)i_cmd_ptr;

        // Check received packet version
        if (CMDH_SNAPSHOT_SYNC_VERSION != l_cmd_ptr->version)
        {
            TRAC_ERR("cmdh_snapshot_sync: Version %i cmd is not supported.", l_cmd_ptr->version);
            l_rc = ERRL_RC_INVALID_DATA;
            break;
        }

        // Set the global reset flag, that will cause all saved data to be cleared in the
        // next callback that is done every 30 seconds via a timer.
        g_cmdh_snapshot_reset = TRUE;

        // Reset current index to stop any possible calls from tmgt to get snapshot buffers.
        g_cmdh_snapshot_cur_index = CMDH_SNAPSHOT_DEFAULT_CUR_INDEX;

        // Reset timer and start counting from now. This will cause a call to the snapshot_callback
        // function below which will reset the other globals based on the fact that g_cmdh_snapshot_reset
        // is set to true.
        l_rc = ssx_timer_schedule(&G_snapshotTimer, 0, SSX_SECONDS(30));
        if (l_rc != SSX_OK)
        {
            TRAC_ERR("cmdh_snapshot_sync: reseting the snapshot timer failed.");
            break;
        }

        TRAC_INFO("cmdh_snapshot_sync: Snapshot buffer has been reset!");

        l_resp_ptr->data_length[0] = 0;
        l_resp_ptr->data_length[1] = 0;
        G_rsp_status = 0;
    }while(FALSE);

    if (l_rc)
    {
        // Build Error Response packet
        cmdh_build_errl_rsp(i_cmd_ptr, o_rsp_ptr, l_rc, &l_err);
    }
    return(l_err);
}