📄 estcpu32backend.cpp
字号:
{ int status; // XXX // Do not touch target if an exception occurred. // This is a work-around for the EST API's lack of // timely knowlege about the emulator's operating mode. if (isExcState_m ()) { oldState = EST_MODE_BKM; return (WDB_OK); } oldState = (EST_OperatingMode) ::EST_GetOperatingMode (emulator_); switch (oldState) { case EST_MODE_BKM: status = EST_SUCCESS; break; case EST_MODE_RUN: /* Running */ case EST_MODE_TRC: /* Non-realtime trace */ status = ::EST_StopTarget (emulator_); if (status != EST_SUCCESS) { return wdbErrFigure_m ("EST_StopTarget ()", status, WDB_ERR_PROC_FAILED); } break; case EST_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 = ::EST_Initialize (emulator_, EST_INN_COMMAND); if (status != EST_SUCCESS) { return wdbErrFigure_m ("EST_Initialize ()", status, WDB_ERR_PROC_FAILED); } break; case EST_MODE_NOCONNECT: /* Not connected... */ case EST_MODE_SIM: /* Simulation mode */ case EST_MODE_PFA: /* Performance */ status = EST_FAILURE; WPWR_LOG_ERR ("Est_T::stateBKM_m () : invalid state %s.\n", ::EST_OperatingModeImage (oldState)); break; default: status = EST_FAILURE; WPWR_LOG_ERR ("Est_T::stateBKM_m () : invalid mode %d.\n", oldState); break; } return (wdbErrFigure_m ("Est_T::stateBKM_m ()", status, WDB_ERR_AGENT_MODE)); }/********************************************************************************* Est_T::stateRestore_m - Restores the old state was called.** This method restores the system to the state it was in before* background (BKM) mode was entered.*/UINT32 Est_T::stateRestore_m (EST_OperatingMode oldState) { int status = EST_FAILURE; // XXX // Do not touch target if an exception occurred. // This is a work-around for the EST API's lack of // timely knowlege about the emulator's operating mode. if (isExcState_m ()) { return (WDB_OK); } switch (oldState) { case EST_MODE_BKM: status = EST_SUCCESS; break; case EST_MODE_RUN: /* Running */ status = ::EST_StartTarget (emulator_, 1, // Resume from current PC 0); break; case EST_MODE_NOCONNECT: /* Not connected... */ case EST_MODE_SIM: /* Simulation mode */ case EST_MODE_PFA: /* Performance */ // XXX - should handle TRC mode? case EST_MODE_TRC: /* Non-realtime trace */ status = EST_FAILURE; WPWR_LOG_ERR ("Est_T::stateRestore_m () : invalid state %s.\n", ::EST_OperatingModeImage (oldState)); break; case EST_MODE_ERR: /* Error */ status = EST_SUCCESS; // Ignore this state and remain in BKM. break; default: status = EST_FAILURE; WPWR_LOG_ERR ("Est_T::stateRestore_m () : invalid mode %d.\n", oldState); break; } return (wdbErrFigure_m ("Est_T::stateRestore_m ()", status, WDB_ERR_PROC_FAILED)); }/********************************************************************************* Est_T::eventQueuePut_m - put a valid event on the event queue.*/void Est_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; } } }/********************************************************************************* Est_T::eventQueueGet_m - get an event from the event queue.*/void Est_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; } }/********************************************************************************* Est_T::regGetOne_m - read only one register.** Caveat - the emulator is assumed to be in background (BKM) state!*/UINT32 Est_T::regGetOne_m ( uint16 estRegNum, void * pRegValue ) { int status; // the emulator is assumed to be in background (BKM) state! status = ::EST_ReadTargetRegister (emulator_, (uint16) estRegNum, pRegValue ); return (wdbErrFigure_m ("EST_ReadTargetRegister ()", status, WDB_ERR_PROC_FAILED)); }/********************************************************************************* Est_T::regSetOne_m - write only one register.** Caveat - the emulator is assumed to be in background (BKM) state!*/UINT32 Est_T::regSetOne_m ( uint16 estRegNum, void * pRegValue ) { int status; // the emulator is assumed to be in background (BKM) state! status = ::EST_WriteTargetRegister (emulator_, (uint16) estRegNum, pRegValue ); return (wdbErrFigure_m ("EST_WriteTargetRegister ()", status, WDB_ERR_PROC_FAILED)); }/********************************************************************************* Est_T::whichEstRegGet_m - converts a Wind River offset to EST's information.** This functions converts the byte offset into a WRS REG_SET structure,* for the 68k, into the corresponding EST register information.** Warning: this function is highly architecture-dependent.*/UINT32 Est_T::whichEstRegGet_m ( UINT32 regSetOffset, EST_Register * pWhichEstReg, uint32 * pEstRegSize ) { // Determine which EST register is specified // by the register set offset. // // Warning: this is highly architecture dependent! switch (regSetOffset) { // Data Registers: case 0: *pWhichEstReg = EST_REG_D0; break; case 4: *pWhichEstReg = EST_REG_D1; break; case 8: *pWhichEstReg = EST_REG_D2; break; case 12: *pWhichEstReg = EST_REG_D3; break; case 16: *pWhichEstReg = EST_REG_D4; break; case 20: *pWhichEstReg = EST_REG_D5; break; case 24: *pWhichEstReg = EST_REG_D6; break; case 28: *pWhichEstReg = EST_REG_D7; break; // Address Registers case (32 + 0): *pWhichEstReg = EST_REG_A0; break; case (32 + 4): *pWhichEstReg = EST_REG_A1; break; case (32 + 8): *pWhichEstReg = EST_REG_A2; break; case (32 + 12): *pWhichEstReg = EST_REG_A3; break; case (32 + 16): *pWhichEstReg = EST_REG_A4; break; case (32 + 20): *pWhichEstReg = EST_REG_A5; break; case (32 + 24): *pWhichEstReg = EST_REG_A6; break; case (32 + 28): *pWhichEstReg = EST_REG_A7; break; // Status Register case 64: // GDB is thinks the status register is 32-bits. case 66: *pWhichEstReg = EST_REG_SR; break; // Program counter case 68: *pWhichEstReg = EST_REG_PC; break; default: return (WDB_ERR_INVALID_PARAMS); break; } *pEstRegSize = EST_RegisterSize (*pWhichEstReg); return (WDB_OK); }/********************************************************************************* Est_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 Est_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./********************************************************************************* Est_T::halt_m - halt target processor.*/UINT32 Est_T::halt_m () { UINT32 status; status = stateBKM_m (oldTgtState_); return (status); }/********************************************************************************* Est_T::unhalt_m - unhalt target processor.** If previous state was running, resume target,* otherwise remain halted.*/UINT32 Est_T::unhalt_m () { UINT32 status; status = stateRestore_m (oldTgtState_); return (status); }/********************************************************************************* Est_T::fdGet_m - returns event file descriptor.*/int Est_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./********************************************************************************* Est_T::excStateEnter_m - put EST back end in "exception" state.*/UINT32 Est_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); }/********************************************************************************* Est_T::excStateExit_m - return EST back end to "normal" state.** Only call this function if the emulator is in BKM mode,* which should be true whenever the back end is in "exception" state.*/UINT32 Est_T::excStateExit_m (BOOL doStep) { if (excCount_ == 0) { WPWR_LOG_ERR ("Est_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 Est_StepTarget() to // step one instruction to bypass the 'bgnd' instruction, or // to use Est_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 EST_StepTargetOutOf() to step one instruction, because // this function does not generate a breakpoint event. if (doStep) { EST_TargetAddress startAddr; EST_TargetAddress endAddr; int status; startAddr = (EST_TargetAddress) pExcRegSet_->pc; endAddr = startAddr + 1; status = ::EST_StepTargetOutOf (emulator_, startAddr, endAddr); if (status != EST_SUCCESS) { return (wdbErrFigure_m ("EST_StepTargetOutOf ()", status, WDB_ERR_PROC_FAILED)); } } return (WDB_OK); }/********************************************************************************* Est_T::excRegsGet_m - read REG_SET from task which generated exception.*/UINT32 Est_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 + -