📄 acecpu32backend.cpp
字号:
status = ::ACE_ReadTargetMemory ( emulator_, (ACE_TargetAddress) pTgtAddr, (void *) pDestAddr, (uint32) numToRead ); if (status != ACE_SUCCESS) { (void) stateRestore_m (oldState); return (wdbErrFigure_m ("ACE_ReadTargetMemory ()", status, WDB_ERR_MEM_ACCES)); } pTgtAddr += numToRead; pDestAddr += numToRead; } return (stateRestore_m (oldState)); }/********************************************************************************* Ace_T::memWrite_m - write a chunk of target memory.** This function write a chunk of target memory. ** XXX - At present, the ACE API can not handle large requests, * consequently, this functions breaks large requests up into smaller* requests of size Ace_T::MaxMtu.*/UINT32 Ace_T::memWrite_m (WDB_MEM_XFER * pMemXfer) { int status; ACE_OperatingMode oldState; // XXX - misleading because valid addresses exist // outside of these bounds.#if 0 // Check that memory access is valid UINT32 aceMemBase = wdbTgtInfo_.rtInfo.memBase; UINT32 aceMemSize = wdbTgtInfo_.rtInfo.memSize; if ( ((UINT32) pMemXfer->destination < aceMemBase) || ((UINT32) pMemXfer->destination + pMemXfer->numBytes) > (aceMemBase + aceMemSize) ) { WPWR_LOG_WARN ("Invalid memory access of %#x bytes at %#x.\n", pMemXfer->numBytes, pMemXfer->destination); }#endif // Enter background mode. if (stateBDM_m (oldState) != WDB_OK) { return (WDB_ERR_AGENT_MODE); } // The target server does not break up requests which // exceed the back end's MTU, so we need to do that here. TGT_INT_T numLeft; // num bytes left to write. TGT_INT_T numToWrite; // num bytes to write in this iteration. UINT8 * pTgtAddr; // address to start next write. UINT8 * pSourceAddr; // where to put result of write. pTgtAddr = (UINT8 *) pMemXfer->destination; pSourceAddr = (UINT8 *) pMemXfer->source; for ( numLeft = pMemXfer->numBytes; numLeft > 0; numLeft -= Ace_T::MaxMtu ) { numToWrite = ((numLeft > Ace_T::MaxMtu) ? (TGT_INT_T) Ace_T::MaxMtu : numLeft); status = ::ACE_WriteTargetMemory ( emulator_, (ACE_TargetAddress) pTgtAddr, (const void *) pSourceAddr, (uint32) numToWrite ); if (status != ACE_SUCCESS) { (void) stateRestore_m (oldState); return (wdbErrFigure_m ("ACE_WriteTargetMemory ()", status, WDB_ERR_MEM_ACCES)); } pTgtAddr += numToWrite; pSourceAddr += numToWrite; } return (stateRestore_m (oldState)); }/********************************************************************************* Ace_T::regsGet_m - read IU registers on target.**/UINT32 Ace_T::regsGet_m ( WDB_REG_READ_DESC * pRegRead, WDB_MEM_XFER * pMemXfer ) { int status; ACE_AllRegisters aceRegSet; char * pWrsRegSet; ACE_OperatingMode oldState;#if 1// #ifndef WIN32// XXX - remove if this breaks under MSVC 4.2 static Ace_T::REG_SET_68K wrsRegSet;#else static WRS_REG_SET_68K wrsRegSet;#endif if (pRegRead->context.contextType != WDB_CTX_SYSTEM) { return (WDB_ERR_INVALID_CONTEXT); } if (pRegRead->regSetType != WTX_REG_SET_IU) { return (WDB_ERR_INVALID_PARAMS); } // Check if back end is in "exception" state if (isExcState_m ()) { return (excRegsGet_m (pRegRead, pMemXfer)); } // Enter background mode. if (stateBDM_m (oldState) != WDB_OK) { return (WDB_ERR_AGENT_MODE); } //////////////////////////////////////////////////////////////////////////// // CrossWind only reads one register at a time. // Because register accesses are often slow, check for such an // access, and if so, read only one register. if (pRegRead->memRegion.numBytes <= 4) { static uint32 aceRegBuf; // value of register read. uint32 aceRegSize; ACE_Register whichAceReg; // which register to read. // Convert WRS register identifier into an ACE identifier. status = whichAceRegGet_m (pRegRead->memRegion.baseAddr, &whichAceReg, &aceRegSize); if (status != WDB_OK) { return (status); } aceRegBuf = 0x0; // GDB thinks the status register is 32-bits. // Consequently, we need to adjust the buffer // pointer for the ACE API which uses 16-bits // for the SR. if ((whichAceReg == ACE_REG_SR) && (pRegRead->memRegion.numBytes == 4)) { UINT8 * pAceRegBuf = (UINT8 *) &aceRegBuf; pAceRegBuf += 2; // skip padding in WRS REG_SET. status = regGetOne_m (whichAceReg, pAceRegBuf); // Convert host-byte ordering of ACE's API to // Opaque byte ordering used by Tornado. *(UINT16 *) pAceRegBuf = FIX_16 (*(UINT16 *) pAceRegBuf); } else { status = regGetOne_m (whichAceReg, &aceRegBuf); // Convert host-byte ordering of ACE's API to // Opaque byte ordering used by Tornado. aceRegBuf = FIX_32 (aceRegBuf); } if (status != WDB_OK) { return (status); } pMemXfer->numBytes = pRegRead->memRegion.numBytes; pMemXfer->source = (WDB_OPQ_DATA_T) &aceRegBuf; pMemXfer->destination = 0; return (stateRestore_m (oldState)); } // End of special case for reading just one register. //////////////////////////////////////////////////////////////////////////// // Otherwise, the request is for more than one register, // so it is most efficient to read the whole register set. status = ::ACE_ReadAllTargetRegisters (emulator_, &aceRegSet); if (status != ACE_SUCCESS) { return (wdbErrFigure_m ("ACE_ReadAllTargetRegisters ()", status, WDB_ERR_PROC_FAILED)); } // Force ACE register info into WRS data structure, which is defined // in ${WIND_BASE}/target/h/arch/mc68k/regsMc68k.h. ::memset (&wrsRegSet, 0x00, sizeof (wrsRegSet)); // Convert host byte ordering of ACE's API to // Opaque byte ordering of Tornado. wrsRegSet.dataReg[0] = FIX_32 (aceRegSet.Dx[0]); /* data registers */ wrsRegSet.dataReg[1] = FIX_32 (aceRegSet.Dx[1]); wrsRegSet.dataReg[2] = FIX_32 (aceRegSet.Dx[2]); wrsRegSet.dataReg[3] = FIX_32 (aceRegSet.Dx[3]); wrsRegSet.dataReg[4] = FIX_32 (aceRegSet.Dx[4]); wrsRegSet.dataReg[5] = FIX_32 (aceRegSet.Dx[5]); wrsRegSet.dataReg[6] = FIX_32 (aceRegSet.Dx[6]); wrsRegSet.dataReg[7] = FIX_32 (aceRegSet.Dx[7]); wrsRegSet.addrReg[0] = FIX_32 (aceRegSet.Ax[0]); /* address registers */ wrsRegSet.addrReg[1] = FIX_32 (aceRegSet.Ax[1]); wrsRegSet.addrReg[2] = FIX_32 (aceRegSet.Ax[2]); wrsRegSet.addrReg[3] = FIX_32 (aceRegSet.Ax[3]); wrsRegSet.addrReg[4] = FIX_32 (aceRegSet.Ax[4]); wrsRegSet.addrReg[5] = FIX_32 (aceRegSet.Ax[5]); wrsRegSet.addrReg[6] = FIX_32 (aceRegSet.Ax[6]); wrsRegSet.addrReg[7] = FIX_32 (aceRegSet.Ax[7]); wrsRegSet.sr = FIX_16 (aceRegSet.SR); wrsRegSet.pc = (INSTR *) FIX_32 (aceRegSet.PC); // Set up pMemXfer to return register info. pMemXfer->numBytes = pRegRead->memRegion.numBytes; // The WDB protocol allows using pRegRead->memRegion.baseAddr to // store an index of the first byte in the REG_SET // to read. It is possible that the compiler might pad the // REG_SET structure and cause the line pMemXfer->source // to create alignment problems. pWrsRegSet = (char *) &wrsRegSet; pMemXfer->source = &pWrsRegSet [(int)pRegRead->memRegion.baseAddr]; pMemXfer->destination = 0; return (stateRestore_m (oldState)); }/********************************************************************************* Ace_T::regsSet_m - write target registers.*/UINT32 Ace_T::regsSet_m (WDB_REG_WRITE_DESC * pRegWrite) { ACE_AllRegisters aceRegSet; ACE_OperatingMode oldState; int status; // ACE API return value REG_SET_68K wrsRegSet; char * pWrsRegBuf; // pointer to treat reg set as opaque if (pRegWrite->context.contextType != WDB_CTX_SYSTEM) { return (WDB_ERR_INVALID_CONTEXT); } if (pRegWrite->regSetType != WTX_REG_SET_IU) { return (WDB_ERR_INVALID_PARAMS); } // Check if back end is in "exception" state if (isExcState_m ()) { WPWR_LOG_WARN ("Ace_T::regsSet_m () - attempt to set registers in " "exception state.\n"); } // Enter background mode if (stateBDM_m (oldState) != WDB_OK) { return (WDB_ERR_PROC_FAILED); } //////////////////////////////////////////////////////////////////////////// // CrossWind only writes one register at a time. // Because register accesses are often slow, check for such an // access, and if so, write only one register. if (pRegWrite->memXfer.numBytes <= 4) { uint32 aceRegSize; ACE_Register whichAceReg; // which register to read. status = whichAceRegGet_m (pRegWrite->memXfer.destination, &whichAceReg, &aceRegSize); if (status != WDB_OK) { return (status); } // XXX - this assumes VxWorks is the target OS. // To modify A7, ACE's API requires modification of SSP instead! if (whichAceReg == ACE_REG_A7) { whichAceReg = ACE_REG_SSP; } // GDB thinks the status register is 32-bits. // Adjust the buffer for ACE's API which uses 16-bits. if ((whichAceReg == ACE_REG_SR) && (pRegWrite->memXfer.numBytes == 4)) { UINT8 * pRegWriteVal = (UINT8 *) pRegWrite->memXfer.source; pRegWriteVal += 2; // Skip padding in WRS's REG_SET. // memXfer.source contains register information // in the same representation it would appear in // target memory (i.e., it is opaque). The // ACE API expects this information in host byte // ordering, so we must convert the register value. *(UINT16 *) pRegWriteVal = FIX_16 (*(UINT16 *) pRegWriteVal); status = regSetOne_m (whichAceReg, pRegWriteVal); } else { // memXfer.source contains register information // in the same representation it would appear in // target memory (i.e., it is opaque). The // ACE API expects this information in host byte // ordering, so we must convert the register value. UINT32 aceRegBuf = FIX_32 (*(UINT32 *) pRegWrite->memXfer.source); status = regSetOne_m (whichAceReg, (UINT8 *) &aceRegBuf); } if (status != WDB_OK) { return (status); } return (stateRestore_m (oldState)); } // End of writing only one register //////////////////////////////////////////////////////////////////////////// // Read all target registers status = ::ACE_ReadAllTargetRegisters (emulator_, &aceRegSet); if (status != ACE_SUCCESS) { // resume old state (void) stateRestore_m (oldState); return (wdbErrFigure_m ("ACE_ReadAllTargetRegisters ()", status, WDB_ERR_PROC_FAILED)); } // Force ACE register info into WRS data structures (defined in // ${WIND_BASE}/target/h/arch/mc68k/regsMc68k.h) ::memset (&wrsRegSet, 0x00, sizeof (wrsRegSet)); // memXfer.source contains register information // in the same representation it would appear in // target memory (i.e., it is opaque). The // ACE API expects this information in host byte // ordering, so we must convert the register value. wrsRegSet.dataReg[0] = FIX_32 (aceRegSet.Dx[0]); /* data registers */ wrsRegSet.dataReg[1] = FIX_32 (aceRegSet.Dx[1]); wrsRegSet.dataReg[2] = FIX_32 (aceRegSet.Dx[2]); wrsRegSet.dataReg[3] = FIX_32 (aceRegSet.Dx[3]); wrsRegSet.dataReg[4] = FIX_32 (aceRegSet.Dx[4]); wrsRegSet.dataReg[5] = FIX_32 (aceRegSet.Dx[5]); wrsRegSet.dataReg[6] = FIX_32 (aceRegSet.Dx[6]); wrsRegSet.dataReg[7] = FIX_32 (aceRegSet.Dx[7]); wrsRegSet.addrReg[0] = FIX_32 (aceRegSet.Ax[0]); /* address registers */ wrsRegSet.addrReg[1] = FIX_32 (aceRegSet.Ax[1]); wrsRegSet.addrReg[2] = FIX_32 (aceRegSet.Ax[2]); wrsRegSet.addrReg[3] = FIX_32 (aceRegSet.Ax[3]); wrsRegSet.addrReg[4] = FIX_32 (aceRegSet.Ax[4]); wrsRegSet.addrReg[5] = FIX_32 (aceRegSet.Ax[5]); wrsRegSet.addrReg[6] = FIX_32 (aceRegSet.Ax[6]); wrsRegSet.addrReg[7] = FIX_32 (aceRegSet.Ax[7]); wrsRegSet.sr = FIX_16 (aceRegSet.SR); wrsRegSet.pc = (INSTR *) FIX_32 (aceRegSet.PC); // Modify desired registers pWrsRegBuf = (char *) &wrsRegSet; ::memcpy ((void *) (pWrsRegBuf + pRegWrite->memXfer.destination), (void *) pRegWrite->memXfer.source, pRegWrite->memXfer.numBytes); // Store in ACE's reg set. aceRegSet.Dx[0] = FIX_32 (wrsRegSet.dataReg[0]); /* data registers */ aceRegSet.Dx[1] = FIX_32 (wrsRegSet.dataReg[1]); aceRegSet.Dx[2] = FIX_32 (wrsRegSet.dataReg[2]); aceRegSet.Dx[3] = FIX_32 (wrsRegSet.dataReg[3]); aceRegSet.Dx[4] = FIX_32 (wrsRegSet.dataReg[4]); aceRegSet.Dx[5] = FIX_32 (wrsRegSet.dataReg[5]); aceRegSet.Dx[6] = FIX_32 (wrsRegSet.dataReg[6]); aceRegSet.Dx[7] = FIX_32 (wrsRegSet.dataReg[7]); aceRegSet.Ax[0] = FIX_32 (wrsRegSet.addrReg[0]); /* address regs */ aceRegSet.Ax[1] = FIX_32 (wrsRegSet.addrReg[1]); aceRegSet.Ax[2] = FIX_32 (wrsRegSet.addrReg[2]); aceRegSet.Ax[3] = FIX_32 (wrsRegSet.addrReg[3]); aceRegSet.Ax[4] = FIX_32 (wrsRegSet.addrReg[4]); aceRegSet.Ax[5] = FIX_32 (wrsRegSet.addrReg[5]); aceRegSet.Ax[6] = FIX_32 (wrsRegSet.addrReg[6]); aceRegSet.Ax[7] = FIX_32 (wrsRegSet.addrReg[7]); // Ignored in ACE's API // Must set SSP instead aceRegSet.SSP = FIX_32 (wrsRegSet.addrReg[7]); // This assumes the use // of vxWorks! aceRegSet.SR = FIX_16 (wrsRegSet.sr); aceRegSet.PC = FIX_32 ((uint32) wrsRegSet.pc); status = ::ACE_WriteAllTargetRegisters (emulator_, &aceRegSet); if (status != ACE_SUCCESS) { (void) stateRestore_m (oldState); return (wdbErrFigure_m ("ACE_WriteAllTargetRegisters ()", status, WDB_ERR_PROC_FAILED)); } else { return (stateRestore_m (oldState)); } }/********************************************************************************* Ace_T::contextSuspend_m - suspend a context.** This method only supports suspension of the entire system.* It is not possible to stop only a task. This is typical of* system-level debugging strategies, like emulators.*/UINT32 Ace_T::contextSuspend_m (WDB_CTX * pContext) { int status; ACE_OperatingMode oldState; if (pContext->contextType != WDB_CTX_SYSTEM) { return (WDB_ERR_AGENT_MODE); } // Enter background mode. if (stateBDM_m (oldState) != WDB_OK) { return (WDB_ERR_AGENT_MODE); } status = ACE_StopTarget (emulator_); return (wdbErrFigure_m ("ACE_StopTarget ()", status, WDB_ERR_PROC_FAILED)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -