void DLM_APIENTRY crDLMSendList(unsigned long listIdentifier, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); if (listState) { crDLMSendDLMList(listState->dlm, listIdentifier, dispatchTable); } }
/** * This routine should be called when a MakeCurrent changes the current * context. It sets the thread data (or global data, in an unthreaded * environment) appropriately; this in turn changes the behavior of * the installed DLM API functions. */ void DLM_APIENTRY crDLMSetCurrentState(CRDLMContextState *state) { CRDLMContextState *currentState = CURRENT_STATE(); if (currentState != state) { SET_CURRENT_STATE(state); } }
void DLM_APIENTRY crDLMReplayListsState(GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); if (listState) { crDLMReplayDLMListsState(listState->dlm, n, type, lists, dispatchTable); } }
void DLM_APIENTRY crDLMSendAllLists(SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); if (listState) { crDLMSendAllDLMLists(listState->dlm, dispatchTable); } }
void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); /* If we're currently using this context, release it first */ if (listState == state) crDLMSetCurrentState(NULL); /* Try to free the DLM. This will either decrement the use count, * or will actually free the DLM, if we were the last user. */ crDLMFreeDLM(state->dlm, dispatchTable); state->dlm = NULL; /* If any buffers still remain (e.g. because there was an open * display list), remove those as well. */ if (state->currentListInfo) { crdlmFreeDisplayListResourcesCb((void *)state->currentListInfo, (void *)dispatchTable); state->currentListInfo = NULL; } state->currentListIdentifier = 0; /* Free the state record itself */ crFree(state); }
/* Return whether the current thread is involved in playback. * This is useful for some routines to selectively choose their * unpack state, for example (as replayed DLM functions must be * unpacked with crStateNativePixelPacking instead of the * normal unpack state, for example. */ CRDLMReplayState DLM_APIENTRY crDLMGetReplayState(void) { CRDLMContextState *listState = CURRENT_STATE(); if (listState) { return listState->replayState; } else { return CRDLM_IMMEDIATE; } }
void DLM_APIENTRY crDLMReplayListState(unsigned long listIdentifier, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); if (listState) { CRDLMReplayState oldReplayState = listState->replayState; listState->replayState = CRDLM_REPLAY_STATE_FUNCTIONS; crDLMReplayDLMListState(listState->dlm, listIdentifier, dispatchTable); listState->replayState = oldReplayState; } }
int32_t DLM_APIENTRY crDLMSaveState(void) { CRDLMContextState *pListState = CURRENT_STATE(); if (pListState) crHashtableWalk(pListState->dlm->displayLists, crDLMSaveListsCb, (void *)NULL); else crDebug("Saving Display Lists: no data to save."); return 0; }
void DLM_APIENTRY crDLMListBase( GLuint base ) { CRDLMContextState *listState = CURRENT_STATE(); if (listState == NULL) { crWarning ("DLM error: ListBase(%d) called with no current state (%s line %d)\n", (int) base, __FILE__, __LINE__); return; } listState->listBase = base; }
GLuint DLM_APIENTRY crDLMGenLists(GLsizei range) { CRDLMContextState *listState = CURRENT_STATE(); if (listState == NULL) { crWarning ("DLM error: GenLists(%d) called with no current state (%s line %d)\n", (int) range, __FILE__, __LINE__); return 0; } return crHashtableAllocKeys(listState->dlm->displayLists, range); }
void crDLMComputeBoundingBox(unsigned long listId) { static GLboolean tableInitialized = GL_FALSE; static SPUDispatchTable t; CRDLMContextState *listState = CURRENT_STATE(); CRDLM *dlm = listState->dlm; DLMListInfo *listInfo = (DLMListInfo *) crHashtableSearch(dlm->displayLists, listId); if (!tableInitialized) { InitDispatchTable(&t); crStateInitMatrixStack(&ModelViewStack, CR_MAX_MODELVIEW_STACK_DEPTH); crStateInitMatrixStack(&DummyStack, CR_MAX_MODELVIEW_STACK_DEPTH); tableInitialized = GL_TRUE; } CurrentStack = &ModelViewStack; Xmin = Ymin = Zmin = FLT_MAX; Xmax = Ymax = Zmax = -FLT_MAX; crDLMReplayDLMList(listState->dlm, listId, &t); if (Xmin == FLT_MAX) { /* XXX review this choice of default bounds */ /* crDebug("Warning: no bounding box!"); */ Xmin = -100; Xmax = 100; Ymin = -100; Ymax = 100; Zmin = -100; Zmax = 100; } /* crDebug("List %d bbox: %f, %f, %f .. %f, %f, %f", (int) listId, Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); */ listInfo->bbox.xmin = Xmin; listInfo->bbox.ymin = Ymin; listInfo->bbox.zmin = Zmin; listInfo->bbox.xmax = Xmax; listInfo->bbox.ymax = Ymax; listInfo->bbox.zmax = Zmax; }
GLboolean DLM_APIENTRY crDLMIsList(GLuint list) { CRDLMContextState *listState = CURRENT_STATE(); if (listState == NULL) { crWarning ("DLM error: IsLists(%d) called with no current state (%s line %d)\n", (int) list, __FILE__, __LINE__); return 0; } if (list == 0) return GL_FALSE; return crHashtableIsKeyUsed(listState->dlm->displayLists, list); }
/** * Release host and guest IDs, free memory resources. */ void DLM_APIENTRY crDLMDeleteLists(GLuint list, GLsizei range, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); crDebug("DLM: DeleteLists(%u, %d) (DLM=%p).", list, range, listState ? listState->dlm : 0); if (listState) { if (range >= 0) { int i; /* Free resources: host memory, host IDs and guest IDs. */ DLM_LOCK(listState->dlm) for (i = 0; i < range; i++) crHashtableDeleteEx(listState->dlm->displayLists, list + i, crdlmFreeDisplayListResourcesCb, dispatchTable); DLM_UNLOCK(listState->dlm) } else
void DLM_APIENTRY crDLMEndList(void) { CRDLMContextState *listState = CURRENT_STATE(); /* Error check: cannot call EndList without a (successful) * preceding NewList. * * The caller is expected to check for glNewList within * a glBegin/glEnd sequence. */ if (listState == NULL) { crWarning("DLM error: EndList called with no current state (%s line %d)\n", __FILE__, __LINE__); return; } if (listState->currentListInfo == NULL) { crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION, "EndList called while no display list was open"); return; } DLM_LOCK(listState->dlm) /* This function will either replace the list information that's * already present with our new list information, freeing the * former list information; or will add the new information * to the set of display lists, depending on whether the * list already exists or not. */ crHashtableReplace(listState->dlm->displayLists, listState->currentListIdentifier, listState->currentListInfo, crdlm_free_list); DLM_UNLOCK(listState->dlm) /* reset the current state to show the list had been ended */ listState->currentListIdentifier = 0; listState->currentListInfo = NULL; listState->currentListMode = GL_FALSE; }
void DLM_APIENTRY crDLMReplayDLMListsState(CRDLM *dlm, GLsizei n, GLenum type, const GLvoid * lists, SPUDispatchTable *dispatchTable) { unsigned long listId; CRDLMContextState *listState = CURRENT_STATE(); #define EXPAND(TYPENAME, TYPE, REFERENCE, INCREMENT) \ case TYPENAME: {\ TYPE p = (TYPE)lists;\ while (n--) {\ listId = listState->listBase + (unsigned long) (REFERENCE);\ crDLMReplayDLMListState(dlm, listId, dispatchTable);\ INCREMENT;\ }\ break;\ } CALL_LISTS_SWITCH(type, break) #undef EXPAND }
void DLM_APIENTRY crDLMDeleteLists(GLuint firstListIdentifier, GLsizei range) { CRDLMContextState *listState = CURRENT_STATE(); register int i; if (listState == NULL) { crWarning ("DLM error: DeleteLists(%d,%d) called with no current state (%s line %d)\n", (int) firstListIdentifier, (int) range, __FILE__, __LINE__); return; } if (range < 0) { char msg[1000]; sprintf(msg, "DeleteLists called with range (%d) less than zero", (int) range); crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE, msg); return; } /* Interestingly, there doesn't seem to be an error for deleting * display list 0, which cannot exist. * * We could delete the desired lists by walking the entire hash of * display lists and looking for and deleting any in our range; or we * could delete lists one by one. The former is faster if the hashing * algorithm is inefficient or if we're deleting all or most of our * lists; the latter is faster if we're deleting a relatively small * number of lists. * * For now, we'll go with the latter; it's also easier to implement * given the current functions available. */ DLM_LOCK(listState->dlm) for (i = 0; i < range; i++) { crHashtableDelete(listState->dlm->displayLists, firstListIdentifier + i, crdlm_free_list); } DLM_UNLOCK(listState->dlm) }
// Function Specification // // Name: dcom_build_occfw_msg // // Description: Copy data into occ fw msg portion // // End Function Specification void dcom_build_occfw_msg( const dcom_error_type_t i_which_msg ) { if ( i_which_msg == SLAVE_INBOX ) { uint32_t l_slv_idx = 0; // For each occ slave for(; l_slv_idx < MAX_OCCS; l_slv_idx++) { G_dcom_slv_inbox_tx[l_slv_idx].occ_fw_mailbox[0] = G_occ_external_req_state; G_dcom_slv_inbox_tx[l_slv_idx].occ_fw_mailbox[1] = G_occ_external_req_mode; G_dcom_slv_inbox_tx[l_slv_idx].occ_fw_mailbox[2] = G_master_event_flags; G_dcom_slv_inbox_tx[l_slv_idx].occ_fw_mailbox[3] = G_slave_event_flags_ack[l_slv_idx]; G_dcom_slv_inbox_tx[l_slv_idx].occ_fw_mailbox[4] = 0; } } else if ( i_which_msg == SLAVE_OUTBOX ) { G_dcom_slv_outbox_tx.occ_fw_mailbox[0] = CURRENT_STATE(); if(G_sysConfigData.system_type.kvm ) { G_dcom_slv_outbox_tx.occ_fw_mailbox[1] = G_occ_external_req_mode_kvm; } else { G_dcom_slv_outbox_tx.occ_fw_mailbox[1] = CURRENT_MODE(); } G_dcom_slv_outbox_tx.occ_fw_mailbox[2] = G_master_event_flags_ack; G_dcom_slv_outbox_tx.occ_fw_mailbox[3] = G_slave_event_flags; G_dcom_slv_outbox_tx.occ_fw_mailbox[4] = SMGR_validate_get_valid_states(); } }
/* * Return mode of list currently being compiled. Should be * GL_FALSE if no list is being compiled, or GL_COMPILE if a * list is being compiled but not executed, or GL_COMPILE_AND_EXECUTE * if a list is being compiled and executed. */ GLenum DLM_APIENTRY crDLMGetCurrentMode(void) { CRDLMContextState *listState = CURRENT_STATE(); return listState ? listState->currentListMode : 0; }
void state_help_menu(User *usr, char c) { char filename[MAX_PATHLEN]; if (usr == NULL) return; Enter(state_help_menu); switch(c) { case INIT_PROMPT: break; case INIT_STATE: usr->runtime_flags |= RTF_BUSY; buffer_text(usr); Put(usr, "<magenta>\n" "<hotkey>Introduction Editing recipient <hotkey>lists\n" "e<hotkey>Xpress messages Editing with <hotkey>colors\n" "<hotkey>Friends and enemies <hotkey>Navigating the --More-- prompt\n" ); Put(usr, "Reading and posting <hotkey>messages\n" "The <hotkey>room system\n" "Customizing your <hotkey>profile <hotkey>Other commands\n" ); read_menu(usr); Return; case ' ': case KEY_RETURN: case KEY_CTRL('C'): case KEY_CTRL('D'): case KEY_BS: Put(usr, "\n"); RET(usr); Return; case KEY_CTRL('L'): Put(usr, "\n"); CURRENT_STATE(usr); Return; case '`': CALL(usr, STATE_BOSS); Return; case 'i': case 'I': Put(usr, "Introduction\n"); HELP_TEXT("intro"); case 'x': case 'X': Put(usr, "eXpress Messages\n"); HELP_TEXT("xmsg"); case 'f': case 'F': Put(usr, "Friends and Enemies\n"); HELP_TEXT("friends"); case 'm': case 'M': Put(usr, "Reading and posting messages\n"); HELP_TEXT("msgs"); case 'r': case 'R': Put(usr, "The room system\n"); HELP_TEXT("rooms"); case 'p': case 'P': Put(usr, "Customizing your profile\n"); HELP_TEXT("profile"); case 'l': case 'L': Put(usr, "Editing recipient lists\n"); HELP_TEXT("recipients"); case 'c': case 'C': Put(usr, "Editing with colors\n"); HELP_TEXT("colors"); case 'n': case 'N': Put(usr, "Navigating the --More-- prompt\n"); HELP_TEXT("more"); case 'o': case 'O': Put(usr, "Other commands\n"); HELP_TEXT("other"); } Print(usr, "<yellow>\n[Help] %c <white>", (usr->runtime_flags & RTF_SYSOP) ? '#' : '>'); Return; }
/** * Generate host and guest IDs, setup IDs mapping between host and guest. */ GLuint DLM_APIENTRY crDLMGenLists(GLsizei range, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); GLuint idHostRangeStart = 0; GLuint idGuestRangeStart = 0; crDebug("DLM: GenLists(%d) (DLM=%p).", range, listState ? listState->dlm : 0); if (listState) { idHostRangeStart = dispatchTable->GenLists(range); if (idHostRangeStart > 0) { idGuestRangeStart = crHashtableAllocKeys(listState->dlm->displayLists, range); if (idGuestRangeStart > 0) { GLuint i; bool fSuccess = true; /* Now have successfully generated IDs range for host and guest. Let's make IDs association. */ for (i = 0; i < (GLuint)range; i++) { DLMListInfo *pListInfo; pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo)); if (pListInfo) { crMemset(pListInfo, 0, sizeof(DLMListInfo)); pListInfo->hwid = idHostRangeStart + i; /* Insert pre-initialized list data which contains IDs mapping into the hash. */ crHashtableReplace(listState->dlm->displayLists, idGuestRangeStart + i, pListInfo, NULL); } else { fSuccess = false; break; } } /* All structures allocated and initialized successfully. */ if (fSuccess) return idGuestRangeStart; /* Rollback some data was not allocated. */ crDLMDeleteLists(idGuestRangeStart, range, NULL /* we do DeleteLists() later in this routine */ ); } else crDebug("DLM: Can't allocate Display List IDs range for the guest."); dispatchTable->DeleteLists(idHostRangeStart, range); } else crDebug("DLM: Can't allocate Display List IDs range on the host side."); } else crDebug("DLM: GenLists(%u) called with no current state.", range); /* Can't reserve IDs range. */ return 0; }
/* * Return id of list currently being compiled. Returns 0 of there's no * current DLM state, or if no list is being compiled. */ GLuint DLM_APIENTRY crDLMGetCurrentList(void) { CRDLMContextState *listState = CURRENT_STATE(); return listState ? listState->currentListIdentifier : 0; }
/* * Begin compiling a list. */ void DLM_APIENTRY crDLMNewList(GLuint listIdentifier, GLenum mode) { DLMListInfo *listInfo; CRDLMContextState *listState = CURRENT_STATE(); /* Error checks: 0 is not a valid identifier, and * we can't call NewList if NewList has been called * more recently than EndList. * * The caller is expected to check for an improper * mode parameter (GL_INVALID_ENUM), or for a NewList * within a glBegin/glEnd (GL_INVALID_OPERATION). */ if (listState == NULL) { crWarning("DLM error: NewList(%d,%d) called with no current state (%s line %d)\n", (int) listIdentifier, (int) mode, __FILE__, __LINE__); return; } if (listIdentifier == 0) { crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE, "NewList called with a list identifier of 0"); return; } if (listState->currentListInfo != NULL) { char msg[1000]; sprintf(msg, "NewList called with display list %d while display list %d was already open", (int) listIdentifier, (int) listState->currentListIdentifier); crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION, msg); return; } listInfo = (DLMListInfo *) crCalloc(sizeof(DLMListInfo)); if (!(listInfo)) { char msg[1000]; sprintf(msg, "could not allocate %u bytes of memory in NewList", (unsigned) sizeof(DLMListInfo)); crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY, msg); return; } listInfo->first = listInfo->last = NULL; listInfo->stateFirst = listInfo->stateLast = NULL; listInfo->references = crAllocHashtable(); if (!(listInfo->references)) { crFree(listInfo); crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "could not allocate memory in NewList"); return; } listInfo->numInstances = 0; listInfo->listSent = GL_FALSE; listInfo->bbox.xmin = FLT_MAX; listInfo->bbox.xmax = -FLT_MAX; listInfo->bbox.ymin = FLT_MAX; listInfo->bbox.ymax = -FLT_MAX; listInfo->bbox.zmin = FLT_MAX; listInfo->bbox.zmax = -FLT_MAX; listState->currentListInfo = listInfo; listState->currentListIdentifier = listIdentifier; listState->currentListMode = mode; }
// 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)); } }
// Function Specification // // Name: amec_slv_check_perf // // Description: Slave OCC's Detect and log degraded performance errors // This function will run every tick. // // Thread: RealTime Loop // // Task Flags: // // End Function Specification void amec_slv_check_perf(void) { /*------------------------------------------------------------------------*/ /* Local Variables */ /*------------------------------------------------------------------------*/ static BOOLEAN l_prev_failsafe_state = FALSE; static BOOLEAN l_prev_ovs_state = FALSE; static BOOLEAN l_prev_pcap_state = FALSE; static ERRL_SEVERITY l_pcap_sev = ERRL_SEV_PREDICTIVE; static BOOLEAN l_throttle_traced = FALSE; static uint64_t l_time = 0; /*------------------------------------------------------------------------*/ /* Code */ /*------------------------------------------------------------------------*/ // Verify that cores are at proper frequency amec_verify_pstate(); do { // was frequency limited by power ? if ( G_non_dps_power_limited != TRUE ) { if(l_throttle_traced) { TRAC_INFO("Frequency not limited by power algorithms anymore"); l_throttle_traced = FALSE; } // we are done break and return break; } // frequency limited due to failsafe condition ? if ( AMEC_INTF_GET_FAILSAFE() == TRUE ) { if ( l_prev_failsafe_state == TRUE) { // we are done break and return break; } else { // log this error ONLY ONCE per IPL l_prev_failsafe_state = TRUE; TRAC_ERR("Frequency limited due to failsafe condition(mode:%d, state:%d)", CURRENT_MODE(), CURRENT_STATE()); l_throttle_traced = TRUE; l_time = ssx_timebase_get(); // log error that calls out OVS procedure // set error severity to RRL_SEV_PREDICTIVE /* @ * @errortype * @moduleid AMEC_SLAVE_CHECK_PERFORMANCE * @reasoncode INTERNAL_FAILURE * @userdata1 Previous FailSafe State * @userdata4 ERC_AMEC_SLAVE_FAILSAFE_STATE * @devdesc Frequency limited due to failsafe condition */ errlHndl_t l_errl = createErrl(AMEC_SLAVE_CHECK_PERFORMANCE, //modId INTERNAL_FAILURE, //reasoncode ERC_AMEC_SLAVE_FAILSAFE_STATE,//Extended reason code ERRL_SEV_PREDICTIVE, //Severity NULL, //Trace Buf DEFAULT_TRACE_SIZE, //Trace Size l_prev_failsafe_state, //userdata1 0); //userdata2 addCalloutToErrl( l_errl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_OVERSUBSCRIPTION, ERRL_CALLOUT_PRIORITY_HIGH ); // and sets the consolidate action flag setErrlActions( l_errl, ERRL_ACTIONS_CONSOLIDATE_ERRORS ); // Commit Error commitErrl(&l_errl); // we are done lets break break; } } // frequency limited due to oversubscription condition ? if ( AMEC_INTF_GET_OVERSUBSCRIPTION() == TRUE ) { if ( l_prev_ovs_state == TRUE) { // we are done break and return break; } else { // log this error ONLY ONCE per IPL l_prev_ovs_state = TRUE; TRAC_ERR("Frequency limited due to oversubscription condition(mode:%d, state:%d)", CURRENT_MODE(), CURRENT_STATE()); l_throttle_traced = TRUE; l_time = ssx_timebase_get(); // log error that calls out OVS procedure // set error severity to RRL_SEV_PREDICTIVE // Updated the RC to match the actual RC passed to createErrl() /* @ * @errortype * @moduleid AMEC_SLAVE_CHECK_PERFORMANCE * @reasoncode OVERSUB_LIMIT_ALERT * @userdata1 Previous OVS State * @userdata4 ERC_AMEC_SLAVE_OVS_STATE * @devdesc Frequency limited due to oversubscription condition */ errlHndl_t l_errl = createErrl(AMEC_SLAVE_CHECK_PERFORMANCE, //modId OVERSUB_LIMIT_ALERT, //reasoncode ERC_AMEC_SLAVE_OVS_STATE, //Extended reason code ERRL_SEV_PREDICTIVE, //Severity NULL, //Trace Buf DEFAULT_TRACE_SIZE, //Trace Size l_prev_ovs_state, //userdata1 0); //userdata2 // Callout to Oversubscription addCalloutToErrl( l_errl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_OVERSUBSCRIPTION, ERRL_CALLOUT_PRIORITY_HIGH ); // Callout to APSS addCalloutToErrl( l_errl, ERRL_CALLOUT_TYPE_HUID, G_sysConfigData.apss_huid, ERRL_CALLOUT_PRIORITY_MED ); // Callout to Firmware addCalloutToErrl( l_errl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_FIRMWARE, ERRL_CALLOUT_PRIORITY_LOW ); // and sets the consolidate action flag setErrlActions( l_errl, ERRL_ACTIONS_CONSOLIDATE_ERRORS ); // Commit Error commitErrl(&l_errl); // we are done lets break break; } } uint16_t l_snrBulkPwr = AMECSENSOR_PTR(PWR250US)->sample; // frequency limited due to system power cap condition ? if (( l_snrBulkPwr > (G_sysConfigData.pcap.system_pcap - PDROP_THRESH) ) && ( G_sysConfigData.pcap.current_pcap == 0 )) { if ( l_prev_pcap_state == TRUE) { // we are done break and return break; } else { //log this error ONLY ONCE per IPL l_prev_pcap_state = TRUE; TRAC_ERR("Frequency limited due to power cap condition(mode:%d, state:%d)", CURRENT_MODE(), CURRENT_STATE()); TRAC_ERR("SnrBulkPwr %d > Sys Pcap %d ",l_snrBulkPwr, G_sysConfigData.pcap.system_pcap ); TRAC_ERR("SnrFanPwr %d, SnrIOPwr %d, SnrStoragePwr %d, SnrGpuPrw %d ", AMECSENSOR_PTR(PWR250USFAN)->sample, AMECSENSOR_PTR(PWR250USIO)->sample, AMECSENSOR_PTR(PWR250USSTORE)->sample, AMECSENSOR_PTR(PWR250USGPU)->sample ); TRAC_ERR("SnrProcPwr 0 %d, SnrProcPwr 1 %d, SnrProcPwr 2 %d, SnrProcPwr 3 %d", g_amec->proc_snr_pwr[0], g_amec->proc_snr_pwr[1], g_amec->proc_snr_pwr[2], g_amec->proc_snr_pwr[3] ); TRAC_ERR("SnrMemPwr 0 %d, SnrMemPwr 1 %d, SnrMemPwr 2 %d, SnrMemPwr 3 %d", g_amec->mem_snr_pwr[0], g_amec->mem_snr_pwr[1], g_amec->mem_snr_pwr[2], g_amec->mem_snr_pwr[3] ); l_throttle_traced = TRUE; l_time = ssx_timebase_get(); // log error that calls out firmware and APSS procedure // set error severity to l_pcap_sev /* @ * @errortype * @moduleid AMEC_SLAVE_CHECK_PERFORMANCE * @reasoncode PCAP_THROTTLE_POWER_LIMIT * @userdata1 Current Sensor Bulk Power * @userdata2 System PCAP * @userdata4 ERC_AMEC_SLAVE_POWERCAP * @devdesc Frequency limited due to PowerCap condition */ errlHndl_t l_errl = createErrl(AMEC_SLAVE_CHECK_PERFORMANCE, //modId PCAP_THROTTLE_POWER_LIMIT, //reasoncode ERC_AMEC_SLAVE_POWERCAP, //Extended reason code l_pcap_sev, //Severity NULL, //Trace Buf DEFAULT_TRACE_SIZE, //Trace Size l_snrBulkPwr, //userdata1 G_sysConfigData.pcap.system_pcap);//userdata2 addCalloutToErrl( l_errl, ERRL_CALLOUT_TYPE_COMPONENT_ID, ERRL_COMPONENT_ID_FIRMWARE, ERRL_CALLOUT_PRIORITY_HIGH ); addCalloutToErrl( l_errl, ERRL_CALLOUT_TYPE_HUID, G_sysConfigData.apss_huid, ERRL_CALLOUT_PRIORITY_HIGH ); // and sets the consolidate action flag setErrlActions( l_errl, ERRL_ACTIONS_CONSOLIDATE_ERRORS ); // then l_pcap_sev to informational l_pcap_sev = ERRL_SEV_INFORMATIONAL; // Commit Error commitErrl(&l_errl); // we are done lets break break; } } // trottle trace to every 3600 seconds (1hr = 3600000) if(!l_throttle_traced && ( DURATION_IN_MS_UNTIL_NOW_FROM(l_time) > 3600000 ) ) { TRAC_INFO("Frequency power limited due to transient condition: PowerLimited=%x, FailSafe=%x, OverSubScription=%x CurrentBulkPwr=%x", G_non_dps_power_limited, AMEC_INTF_GET_FAILSAFE(), AMEC_INTF_GET_OVERSUBSCRIPTION(), l_snrBulkPwr ); l_throttle_traced = TRUE; l_time = ssx_timebase_get(); } } while( 0 ); return; }
// 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]))); }
CRDLMContextState DLM_APIENTRY *crDLMGetCurrentState(void) { return CURRENT_STATE(); }