📄 acecpu32backend.cpp
字号:
{ int status; // XXX // Do not touch target if an exception occurred. // This is a work-around for the ACE API's lack of // timely knowlege about the emulator's operating mode. if (isExcState_m ()) { oldState = ACE_MODE_BDM; return (WDB_OK); } oldState = (ACE_OperatingMode) ::ACE_GetOperatingMode (emulator_); switch (oldState) { case ACE_MODE_BDM: status = ACE_SUCCESS; break; case ACE_MODE_RUN: /* Running */ case ACE_MODE_TRC: /* Non-realtime trace */ status = ::ACE_StopTarget (emulator_); if (status != ACE_SUCCESS) { return wdbErrFigure_m ("ACE_StopTarget ()", status, WDB_ERR_PROC_FAILED); } break; case ACE_MODE_ERR: /* Error */ // Re-initialize emulator (and target) to change from ERR mode // to background mode. Note: the INN command only reinitializes // background mode and does not reinitialize the target. status = ::ACE_Initialize (emulator_, ACE_INN_COMMAND); if (status != ACE_SUCCESS) { return wdbErrFigure_m ("ACE_Initialize ()", status, WDB_ERR_PROC_FAILED); } break; case ACE_MODE_NOCONNECT: /* Not connected... */ case ACE_MODE_SIM: /* Simulation mode */ case ACE_MODE_PFA: /* Performance */ status = ACE_FAILURE; WPWR_LOG_ERR ("Ace_T::stateBDM_m () : invalid state %s.\n", ::ACE_OperatingModeImage (oldState)); break; default: status = ACE_FAILURE; WPWR_LOG_ERR ("Ace_T::stateBDM_m () : invalid mode %d.\n", oldState); break; } return (wdbErrFigure_m ("Ace_T::stateBDM_m ()", status, WDB_ERR_AGENT_MODE)); }/********************************************************************************* Ace_T::stateRestore_m - Restores the old state was called.** This method restores the system to the state it was in before* background (BDM) mode was entered.*/UINT32 Ace_T::stateRestore_m (ACE_OperatingMode oldState) { int status = ACE_FAILURE; // XXX // Do not touch target if an exception occurred. // This is a work-around for the ACE API's lack of // timely knowlege about the emulator's operating mode. if (isExcState_m ()) { return (WDB_OK); } switch (oldState) { case ACE_MODE_BDM: status = ACE_SUCCESS; break; case ACE_MODE_RUN: /* Running */ status = ::ACE_StartTarget (emulator_, 1, // Resume from current PC 0); break; case ACE_MODE_NOCONNECT: /* Not connected... */ case ACE_MODE_SIM: /* Simulation mode */ case ACE_MODE_PFA: /* Performance */ // XXX - should handle TRC mode? case ACE_MODE_TRC: /* Non-realtime trace */ status = ACE_FAILURE; WPWR_LOG_ERR ("Ace_T::stateRestore_m () : invalid state %s.\n", ::ACE_OperatingModeImage (oldState)); break; case ACE_MODE_ERR: /* Error */ status = ACE_SUCCESS; // Ignore this state and remain in BDM. break; default: status = ACE_FAILURE; WPWR_LOG_ERR ("Ace_T::stateRestore_m () : invalid mode %d.\n", oldState); break; } return (wdbErrFigure_m ("Ace_T::stateRestore_m ()", status, WDB_ERR_PROC_FAILED)); }/********************************************************************************* Ace_T::eventQueuePut_m - put a valid event on the event queue.*/void Ace_T::eventQueuePut_m (Event_T * pWdbEvent) { if (pWdbEvent == NULL) { WPWR_LOG_ERR ("new () failed for event callback.\n"); } else { // enqueue valid events if (pWdbEvent->wdbEvent_.evtType != WDB_EVT_NONE) { eventQueue_.append (pWdbEvent); isEvent_ = TRUE; } } }/********************************************************************************* Ace_T::eventQueueGet_m - get an event from the event queue.*/void Ace_T::eventQueueGet_m (WDB_EVT_DATA * pEvtData) { // Pop event off queue Event_T * pWdbEvent = (Event_T *) eventQueue_.get (); if (pWdbEvent == rwnil) { // Queue is empty, but we must synthesize a // bogus event for the target server. isEvent_ = FALSE; // Note: the target server converts this event type into the // event type UNKNOWN for the tools. pEvtData->evtType = WDB_EVT_NONE; return; } else { // The event is valid. *pEvtData = pWdbEvent->wdbEvent_; delete pWdbEvent; if (eventQueue_.isEmpty ()) isEvent_ = FALSE; // Clear event flag return; } }/********************************************************************************* Ace_T::regGetOne_m - read only one register.** Caveat - the emulator is assumed to be in background (BDM) state!*/UINT32 Ace_T::regGetOne_m ( uint16 aceRegNum, void * pRegValue ) { int status; // the emulator is assumed to be in background (BDM) state! status = ::ACE_ReadTargetRegister (emulator_, (uint16) aceRegNum, pRegValue ); return (wdbErrFigure_m ("ACE_ReadTargetRegister ()", status, WDB_ERR_PROC_FAILED)); }/********************************************************************************* Ace_T::regSetOne_m - write only one register.** Caveat - the emulator is assumed to be in background (BDM) state!*/UINT32 Ace_T::regSetOne_m ( uint16 aceRegNum, void * pRegValue ) { int status; // the emulator is assumed to be in background (BDM) state! status = ::ACE_WriteTargetRegister (emulator_, (uint16) aceRegNum, pRegValue ); return (wdbErrFigure_m ("ACE_WriteTargetRegister ()", status, WDB_ERR_PROC_FAILED)); }/********************************************************************************* Ace_T::whichAceRegGet_m - converts a Wind River offset to ACE's information.** This functions converts the byte offset into a WRS REG_SET structure,* for the 68k, into the corresponding ACE register information.** Warning: this function is highly architecture-dependent.*/UINT32 Ace_T::whichAceRegGet_m ( UINT32 regSetOffset, ACE_Register * pWhichAceReg, uint32 * pAceRegSize ) { // Determine which ACE register is specified // by the register set offset. // // Warning: this is highly architecture dependent! switch (regSetOffset) { // Data Registers: case 0: *pWhichAceReg = ACE_REG_D0; break; case 4: *pWhichAceReg = ACE_REG_D1; break; case 8: *pWhichAceReg = ACE_REG_D2; break; case 12: *pWhichAceReg = ACE_REG_D3; break; case 16: *pWhichAceReg = ACE_REG_D4; break; case 20: *pWhichAceReg = ACE_REG_D5; break; case 24: *pWhichAceReg = ACE_REG_D6; break; case 28: *pWhichAceReg = ACE_REG_D7; break; // Address Registers case (32 + 0): *pWhichAceReg = ACE_REG_A0; break; case (32 + 4): *pWhichAceReg = ACE_REG_A1; break; case (32 + 8): *pWhichAceReg = ACE_REG_A2; break; case (32 + 12): *pWhichAceReg = ACE_REG_A3; break; case (32 + 16): *pWhichAceReg = ACE_REG_A4; break; case (32 + 20): *pWhichAceReg = ACE_REG_A5; break; case (32 + 24): *pWhichAceReg = ACE_REG_A6; break; case (32 + 28): *pWhichAceReg = ACE_REG_A7; break; // Status Register case 64: // GDB is thinks the status register is 32-bits. case 66: *pWhichAceReg = ACE_REG_SR; break; // Program counter case 68: *pWhichAceReg = ACE_REG_PC; break; default: return (WDB_ERR_INVALID_PARAMS); break; } *pAceRegSize = ACE_RegisterSize (*pWhichAceReg); return (WDB_OK); }/********************************************************************************* Ace_T::memChecksum_m - perform checksum on a chunk of target memory.** Caveat - because of performance limitations of the API, the checksum* is only performed on small chunks of memory. Large requests are failed.*/UINT32 Ace_T::memChecksum_m ( WDB_MEM_REGION * pMemRegion, UINT32 * pChecksumValue ) { // Only perform checksum on small regions if (pMemRegion->numBytes < 128 ) { return (Backend_T::memChecksum_m (pMemRegion, pChecksumValue)); } *pChecksumValue = 0x0; return (WDB_OK); };////////////////////////////////////////////////////////////////////////////////// Backend_T's mandatory helper methods./********************************************************************************* Ace_T::halt_m - halt target processor.*/UINT32 Ace_T::halt_m () { UINT32 status; status = stateBDM_m (oldTgtState_); return (status); }/********************************************************************************* Ace_T::unhalt_m - unhalt target processor.** If previous state was running, resume target,* otherwise remain halted.*/UINT32 Ace_T::unhalt_m () { UINT32 status; status = stateRestore_m (oldTgtState_); return (status); }/********************************************************************************* Ace_T::fdGet_m - returns event file descriptor.*/int Ace_T::fdGet_m () { return eventFd_; }////////////////////////////////////////////////////////////////////////////////// Exception Management Methods//// When a target exception occurs, the back end is notified// of the exception by a target-resident exception hook// which gathers information about the exception, and executes// the 'bgnd' instruction. The back end must then switch// from "normal" to "exception" state. In "exception" state,// attempts to read IU registers will return the value of the// IU registers for the task which generated the execption. Also,// the contextCont, contextStep, and contextResume operations// cause the back end to step over the 'bgnd' instruction, and// return to "normal" state./********************************************************************************* Ace_T::excStateEnter_m - put ACE back end in "exception" state.*/UINT32 Ace_T::excStateEnter_m (BDM_EXC_INFO * pExcInfo) { STATUS status; // increment exception flag. excCount_++; // get IU registers for the context which generated the exception. TGT_ADDR_T tgtRegAddr = (TGT_ADDR_T) pExcInfo->pIuRegs; status = tgtRead_s (tgtRegAddr, pExcRegSet_, sizeof (*pExcRegSet_)); if (status != OK) { WPWR_LOG_ERR ("Backend_T::tgtRead_s() failed!\n"); return (WDB_ERR_MEM_ACCES); } return (WDB_OK); }/********************************************************************************* Ace_T::excStateExit_m - return ACE back end to "normal" state.** Only call this function if the emulator is in BDM mode,* which should be true whenever the back end is in "exception" state.*/UINT32 Ace_T::excStateExit_m (BOOL doStep) { if (excCount_ == 0) { WPWR_LOG_ERR ("Ace_T::excStateExit_m () - unmatched exit attempt.\n"); return (WDB_ERR_PROC_FAILED); } // decrement exception count. excCount_--; // step past 'bgnd' instruction. // // Intuitively, you would want to use Ace_StepTarget() to // step one instruction to bypass the 'bgnd' instruction, or // to use Ace_StartTarget() to continue. Unfortunately, the // former causes a breakpoint event, and the later can not // continue past a 'bgnd' instruction. The work around is to // use ACE_StepTargetOutOf() to step one instruction, because // this function does not generate a breakpoint event. if (doStep) { ACE_TargetAddress startAddr; ACE_TargetAddress endAddr; int status; startAddr = (ACE_TargetAddress) pExcRegSet_->pc; endAddr = startAddr + 1; status = ::ACE_StepTargetOutOf (emulator_, startAddr, endAddr); if (status != ACE_SUCCESS) { return (wdbErrFigure_m ("ACE_StepTargetOutOf ()", status, WDB_ERR_PROC_FAILED)); } } return (WDB_OK); }/********************************************************************************* Ace_T::excRegsGet_m - read REG_SET from task which generated exception.*/UINT32 Ace_T::excRegsGet_m ( WDB_REG_READ_DESC * pRegRead, WDB_MEM_XFER * pMemXfer ) { char * pWrsRegSet; pMemXfer->numBytes = pRegRead->memRegion.numBytes; pMemXfer->destination = 0; pWrsRegSet = (char *) pExcRegSet_; pMemXfer->source = &pWrsRegSet [(int)pRegRead->memRegion.baseAddr]; return (WDB_OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -