//! (HCS12) Reads contents of core registers //! //! @param registers pointer to structure to receive the register values //! //! @return 0 => Success,\n !=0 => Fail //! TBDML_API unsigned char _tbdml_read_regs(registers_t *registers) { uint8_t rc; unsigned long value; rc = USBDM_ReadReg(HCS12_RegPC, &value); if (rc != BDM_RC_OK) return rc; registers->hc12.pc = (uint16_t)value; rc = USBDM_ReadReg(HCS12_RegSP, &value); if (rc != BDM_RC_OK) return rc; registers->hc12.sp = (uint16_t)value; rc = USBDM_ReadReg(HCS12_RegX, &value); if (rc != BDM_RC_OK) return rc; registers->hc12.ix = (uint16_t)value; rc = USBDM_ReadReg(HCS12_RegY, &value); if (rc != BDM_RC_OK) return rc; registers->hc12.iy = (uint16_t)value; rc = USBDM_ReadReg(HCS12_RegD, &value); if (rc != BDM_RC_OK) return rc; registers->hc12.d = (uint16_t)value; rc = USBDM_ReadDReg(0xFF06,&value); if (rc != BDM_RC_OK) return rc; registers->hc12.ccr = (uint8_t)value; return BDM_RC_OK; }
//! (HCS08 & RS08) Reads contents of core registers //! //! @param registers pointer to structure to receive the register values //! //! @return 0 => Success,\n !=0 => Fail //! OSBDM_API unsigned char _opensourcebdm_read_regs(registers_t *registers) { U8 rc; unsigned long value; rc = USBDM_ReadReg(HCS08_RegPC, &value); if (rc != BDM_RC_OK) return rc; registers->hcs08.pc = (U16)value; rc = USBDM_ReadReg(HCS08_RegSP, &value); if (rc != BDM_RC_OK) return rc; registers->hcs08.sp = (U16)value; rc = USBDM_ReadReg(HCS08_RegHX, &value); if (rc != BDM_RC_OK) return rc; registers->hcs08.hx = (U16)value; rc = USBDM_ReadReg(HCS08_RegA, &value); if (rc != BDM_RC_OK) return rc; registers->hcs08.a = (U8)value; rc = USBDM_ReadReg(HCS08_RegCCR, &value); if (rc != BDM_RC_OK) return rc; registers->hcs08.ccr = (U8)value; return BDM_RC_OK; }
//! 2.2.6.2 Read Value from Register //! //! @param dnRegNumber //! @param drvValue //! USBDM_GDI_API DiReturnT DiRegisterRead ( DiUInt32T dnRegNumber, pDiRegisterValueT drvValue ) { unsigned long dataValue = 0xDEADBEEF; USBDM_ErrorCode rc = BDM_RC_OK; Logging::print("DiRegisterRead(0x%X(%d))\n", dnRegNumber, dnRegNumber); CHECK_ERROR_STATE(); if (dnRegNumber>=cfv234regID_FIRST_DEBUG_REG) { dnRegNumber -= cfv234regID_FIRST_DEBUG_REG; rc = USBDM_ReadDReg(dnRegNumber,&dataValue); Logging::print("DiRegisterRead(0x%X(%s) => 0x%08X)\n", dnRegNumber, getCFVxDebugRegName(dnRegNumber), (uint32_t)dataValue); } else if (dnRegNumber >= cfv234regID_FIRST_CONTROL_REG) { dnRegNumber -= cfv234regID_FIRST_CONTROL_REG; rc = USBDM_ReadCReg(dnRegNumber,&dataValue); Logging::print("DiRegisterRead(0x%X(%s) => 0x%08X)\n", dnRegNumber, getCFVxControlRegName(dnRegNumber), (uint32_t)dataValue); } else { switch (dnRegNumber) { case cfv234regID_pc : rc = USBDM_ReadCReg(CFVx_CRegPC,&dataValue); Logging::print("DiRegisterRead(0x%X(%s) => 0x%08X)\n", CFVx_CRegPC, getCFVxControlRegName(CFVx_CRegPC), (uint32_t)dataValue); break; case cfv234regID_sr : rc = USBDM_ReadCReg(CFVx_CRegSR,&dataValue); Logging::print("DiRegisterRead(0x%X(%s) => 0x%08X)\n", CFVx_CRegSR, getCFVxControlRegName(CFVx_CRegSR), (uint32_t)dataValue); break; default : // D0-7, A0-7 if (dnRegNumber<=cfv234regID_a7) { rc = USBDM_ReadReg(dnRegNumber,&dataValue); Logging::print("DiRegisterRead(0x%X(%s) => 0x%08X)\n", dnRegNumber, getCFVxRegName(dnRegNumber), (uint32_t)dataValue); } else { Logging::print("DiRegisterRead(Illegal reg# = 0x%X (%d)\n", dnRegNumber, dnRegNumber); rc = BDM_RC_ILLEGAL_PARAMS; } break; } } if (rc != BDM_RC_OK) { Logging::print("DiRegisterRead(0x%X) => error\n", dnRegNumber); return setErrorState(DI_ERR_NONFATAL, rc); } *drvValue = (U32c)dataValue; Logging::print("0x%X(%d) => 0x%08X\n", dnRegNumber, dnRegNumber, dataValue); return setErrorState(DI_OK); }
//! 2.2.6.2 Read Value from Register //! //! @param dnRegNumber //! @param drvValue //! USBDM_GDI_DECLSPEC DiReturnT DiRegisterRead ( DiUInt32T dnRegNumber, pDiRegisterValueT drvValue ) { unsigned long dataValue = 0xDEADBEEF; USBDM_ErrorCode rc = BDM_RC_OK; LOGGING; log.print("0x%X(%d)\n", dnRegNumber, dnRegNumber); CHECK_ERROR_STATE(); if (dnRegNumber > S12Z_RegCCR) { return setErrorState(DI_ERR_PARAM, ("Illegal register identifier")); } rc = USBDM_ReadReg(dnRegNumber, &dataValue); if (rc != BDM_RC_OK) { log.print("DiRegisterRead(0x%X) => error\n", dnRegNumber); return setErrorState(DI_ERR_NONFATAL, rc); } *drvValue = (U32c)dataValue; log.print("0x%lX(%ld) => 0x%08lX\n", (unsigned long)dnRegNumber, (unsigned long)dnRegNumber, (unsigned long)dataValue); return setErrorState(DI_OK); }
//! 2.2.6.2 Read Value from Register //! //! @param dnRegNumber //! @param drvValue //! USBDM_GDI_DECLSPEC DiReturnT DiRegisterRead ( DiUInt32T dnRegNumber, pDiRegisterValueT drvValue ) { LOGGING; log.print("0x%X(%d)\n", dnRegNumber, dnRegNumber); unsigned long dataValue = 0xDEADBEEF; USBDM_ErrorCode rc = BDM_RC_OK; log.print("0x%X(%d)\n", dnRegNumber, dnRegNumber); if (forceMassErase) { // Dummy register reads until device in unsecured *drvValue = (U32c)dataValue; return setErrorState(DI_OK); } CHECK_ERROR_STATE(); if (dnRegNumber>cfv1regID_FIRST_DEBUG_regID_BYTE) switch (dnRegNumber) { case cfv1regID_xcsr_byte : rc = USBDM_ReadStatusReg(&dataValue); break; case cfv1regID_csr2_byte : rc = USBDM_ReadDReg(CFV1_DRegCSR2byte,&dataValue); break; case cfv1regID_csr3_byte : rc = USBDM_ReadDReg(CFV1_DRegCSR3byte,&dataValue); break; default : log.print("DiRegisterRead(Illegal Reg# 0x%X(%d)\n", dnRegNumber, dnRegNumber); rc = BDM_RC_ILLEGAL_PARAMS; break; } else if (dnRegNumber>cfv1regID_FIRST_DEBUG_REG) rc = USBDM_ReadDReg(dnRegNumber-cfv1regID_FIRST_DEBUG_REG,&dataValue); else if (dnRegNumber > cfv1regID_FIRST_CONTROL_REG) rc = USBDM_ReadCReg(dnRegNumber-cfv1regID_FIRST_CONTROL_REG,&dataValue); else { switch (dnRegNumber) { case cfv1regID_pc : rc = USBDM_ReadCReg(CFV1_CRegPC,&dataValue); break; case cfv1regID_sr : rc = USBDM_ReadCReg(CFV1_CRegSR,&dataValue); break; default : // D0-7, A0-7 if (dnRegNumber>15) { log.print("DiRegisterRead(Illegal Reg# 0x%X(%d)\n", dnRegNumber, dnRegNumber); rc = BDM_RC_ILLEGAL_PARAMS; } else rc = USBDM_ReadReg(dnRegNumber,&dataValue); break; } } if (rc != BDM_RC_OK) { log.print("DiRegisterRead(0x%X) => error\n", dnRegNumber); return setErrorState(DI_ERR_NONFATAL, rc); } *drvValue = (U32c)dataValue; log.print("0x%lX(%ld) => 0x%08lX\n", (unsigned long)dnRegNumber, (unsigned long)dnRegNumber, (unsigned long)dataValue); return setErrorState(DI_OK); }
USBDM_ErrorCode BdmInterface_RS08::readPC(unsigned long *regValue) { return USBDM_ReadReg(RS08_RegCCR_PC, regValue); };
//! 2.2.8.2 Execute a Single Step //! //! @param dnNrInstructions //! USBDM_GDI_DECLSPEC DiReturnT DiExecSingleStep ( DiUInt32T dnNrInstructions ) { LOGGING_Q; log.print("(%d)\n", dnNrInstructions); USBDM_ErrorCode BDMrc; long unsigned ccrValue; long unsigned pcValue; unsigned char currentOpcode; const int interruptMask = (1<<3); const int tapOpcode = 0x84; const int tpaOpcode = 0x85; const int seiOpcode = 0x9B; const int cliOpcode = 0x9A; const int waitOpcode = 0x8F; const int rtiOpcode = 0x80; const int swiOpcode = 0x83; const int stopOpcode = 0x8E; CHECK_ERROR_STATE(); #if (TARGET == MC56F80xx) BDMrc = DSC_TargetStepN(dnNrInstructions); #else if (dnNrInstructions>1) { log.print("DiExecSingleStep() - Only a single step is supported!\n"); return setErrorState(DI_ERR_PARAM, ("Only a single step is allowed")); } /* * Cases to consider when masking interrupts during step * * +--------+-----------+---------+-----------------------------------------------------+ * | Opcode | Initial I | Final I | Problem - action | * +--------+-----------+---------+-----------------------------------------------------+ * | --- | 1 | X | None - no action (interrupts already masked) | * +--------+-----------+---------+-----------------------------------------------------+ * | CLI | 0 | ? | It may be possible for an interrupt to occur, | * | WAIT | | | setting I-flag which is then incorrectly cleared. | * | STOP | | | (I don't think it applies to CLI but be safe.) | * | SWI | | | - don't 'fix' CCR | * +--------+-----------+---------+-----------------------------------------------------+ * | RTI | 0 | 1 | Contrived but possible situation. I flag | * | | | | incorrectly cleared - don't 'fix' CCR | * +--------+-----------+---------+-----------------------------------------------------+ * | SEI | 0 | 1 | The instruction may set I-flag which is then | * | TAP | 0 | 1 | incorrectly cleared - don't 'fix' CCR | * +--------+-----------+---------+-----------------------------------------------------+ * | TPA | 0 | X | The wrong value is transferred to A - fix A | * +--------+-----------+---------+-----------------------------------------------------+ * | --- | 0 | 0 | CCR change - clear I-flag in new CCR | * +--------+-----------+---------+-----------------------------------------------------+ */ if (bdmOptions.maskInterrupts) { log.print("DiExecSingleStep() - checking if interrupt masking needed\n"); USBDM_ReadReg(HCS08_RegCCR, &ccrValue); if ((ccrValue&interruptMask) != 0) { // Interrupts already masked - just step BDMrc = USBDM_TargetStep(); } else { // Mask interrupts log.print("DiExecSingleStep() - masking interrupts\n"); USBDM_WriteReg(HCS08_RegCCR, ccrValue|interruptMask); // Get current instruction opcode USBDM_ReadReg(HCS08_RegPC, &pcValue); USBDM_ReadMemory(1,1,pcValue,¤tOpcode); // Do a step BDMrc = USBDM_TargetStep(); switch(currentOpcode) { case cliOpcode : case waitOpcode : case seiOpcode : case tapOpcode : case rtiOpcode : case swiOpcode : // Not ever stepped - treated as subroutine? case stopOpcode : log.print("DiExecSingleStep() - skipping CCR restore\n"); // Don't 'fix' CCR as updated by instruction or int ack break; case tpaOpcode : // Fix A & CCR (clear I flag) log.print("DiExecSingleStep() - fixing A & CCR reg\n"); USBDM_WriteReg(HCS08_RegA, ccrValue&~interruptMask); USBDM_WriteReg(HCS08_RegCCR, ccrValue&~interruptMask); break; default : // Fix CCR (clear I flag) // Unmask interrupts log.print("DiExecSingleStep() - fixing CCR reg\n"); USBDM_ReadReg(HCS08_RegCCR, &ccrValue); USBDM_WriteReg(HCS08_RegCCR, ccrValue&~interruptMask); break; } } } else BDMrc = USBDM_TargetStep(); #endif if (BDMrc != BDM_RC_OK) { return setErrorState(DI_ERR_NONFATAL, BDMrc); } return setErrorState(DI_OK); }
USBDM_ErrorCode BdmInterface_ARM::readPC(unsigned long *regValue) { return USBDM_ReadReg(ARM_RegPC, regValue); }
//! 2.2.8.6 Get DI Execution/Exit Status //! //! @param pdesExitStatus //! //! @return \n //! DI_OK => OK \n //! DI_ERR_FATAL => Error see \ref currentErrorString //! USBDM_GDI_API DiReturnT DiExecGetStatus ( pDiExitStatusT pdesExitStatus ) { LOGGING; USBDM_ErrorCode BDMrc; static DiExitCauseT lastStatus = DI_WAIT_USER; // Logging::print("DiExecGetStatus()\n"); // Defaults pdesExitStatus->dscCause = DI_WAIT_UNKNOWN; pdesExitStatus->dwBpId = 0x1000400; // bkpt ID? pdesExitStatus->szReason = (DiStringT)"unknown state"; // Removed as prevents CW retry strategy // CHECK_ERROR_STATE(); if (bdmOptions.autoReconnect) { USBDM_ErrorCode bdmRc = targetConnect(softConnectOptions); if (bdmRc != BDM_RC_OK) { Logging::print("DiExecGetStatus()=> connect failed\n"); return setErrorState(DI_ERR_COMMUNICATION, bdmRc); } } else { USBDM_GetBDMStatus(&USBDMStatus); } // pdesExitStatus->szReason = (DiStringT)getBDMStatusName(&USBDMStatus); if (USBDMStatus.reset_recent == RESET_DETECTED) { Logging::print("DiExecGetStatus()=>Target has been reset\n"); mtwksDisplayLine("Target RESET detected\n"); } if (bdmOptions.usePSTSignals) { // Check processor state using PST signals if (USBDMStatus.halt_state) { // Processor halted pdesExitStatus->dscCause = DI_WAIT_UNKNOWN; pdesExitStatus->szReason = (DiStringT)"Debug Halted"; if (lastStatus != pdesExitStatus->dscCause) { Logging::print("DiExecGetStatus(PST) status change => DI_WAIT_UNKNOWN, (%s)\n", pdesExitStatus->szReason); } } else { // Processor executing pdesExitStatus->dscCause = DI_WAIT_RUNNING; pdesExitStatus->szReason = (DiStringT)"Running"; if (lastStatus != pdesExitStatus->dscCause) { Logging::print("DiExecGetStatus(PST) status change => DI_WAIT_RUNNING, (%s)\n", pdesExitStatus->szReason); } } } else { // Probe D0 register - if fail assume processor running! // BUG - If stopped D0 can still be read so CW thinks the target is halted // but is still running. unsigned long int dummy; BDMrc = USBDM_ReadReg(CFVx_RegD0, &dummy); if (BDMrc == BDM_RC_OK) { // Processor halted pdesExitStatus->dscCause = DI_WAIT_UNKNOWN; pdesExitStatus->szReason = (DiStringT)"Debug Halted"; if (lastStatus != pdesExitStatus->dscCause) { Logging::print("DiExecGetStatus() status change => DI_WAIT_UNKNOWN, (%s)\n", pdesExitStatus->szReason); } } else { // Processor executing pdesExitStatus->dscCause = DI_WAIT_RUNNING; pdesExitStatus->szReason = (DiStringT)"Running"; if (lastStatus != pdesExitStatus->dscCause) { Logging::print("DiExecGetStatus() status change => DI_WAIT_RUNNING, (%s)\n", pdesExitStatus->szReason); } } } lastStatus = pdesExitStatus->dscCause; return setErrorState(DI_OK); }
//! (CFv1) Read Core registers //! //! @param regNo Register # //! //! @return 32-bit number //! OSBDM_API unsigned int _opensourcebdm_read_reg(unsigned char regNo) { unsigned long value; USBDM_ReadReg(regNo, &value); return value; }