📄 estcpu32backend.cpp
字号:
status = ::EST_ReadTargetMemory ( emulator_, (EST_TargetAddress) pTgtAddr, (void *) pDestAddr, (uint32) numToRead ); if (status != EST_SUCCESS) { (void) stateRestore_m (oldState); return (wdbErrFigure_m ("EST_ReadTargetMemory ()", status, WDB_ERR_MEM_ACCES)); } pTgtAddr += numToRead; pDestAddr += numToRead; } return (stateRestore_m (oldState)); }/********************************************************************************* Est_T::memWrite_m - write a chunk of target memory.** This function write a chunk of target memory. ** XXX - At present, the EST API can not handle large requests, * consequently, this functions breaks large requests up into smaller* requests of size Est_T::MaxMtu.*/UINT32 Est_T::memWrite_m (WDB_MEM_XFER * pMemXfer) { int status; EST_OperatingMode oldState; // XXX - misleading because valid addresses exist // outside of these bounds.#if 0 // Check that memory access is valid UINT32 estMemBase = wdbTgtInfo_.rtInfo.memBase; UINT32 estMemSize = wdbTgtInfo_.rtInfo.memSize; if ( ((UINT32) pMemXfer->destination < estMemBase) || ((UINT32) pMemXfer->destination + pMemXfer->numBytes) > (estMemBase + estMemSize) ) { WPWR_LOG_WARN ("Invalid memory access of %#x bytes at %#x.\n", pMemXfer->numBytes, pMemXfer->destination); }#endif // Enter background mode. if (stateBKM_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 -= Est_T::MaxMtu ) { numToWrite = ((numLeft > Est_T::MaxMtu) ? (TGT_INT_T) Est_T::MaxMtu : numLeft); status = ::EST_WriteTargetMemory ( emulator_, (EST_TargetAddress) pTgtAddr, (const void *) pSourceAddr, (uint32) numToWrite ); if (status != EST_SUCCESS) { (void) stateRestore_m (oldState); return (wdbErrFigure_m ("EST_WriteTargetMemory ()", status, WDB_ERR_MEM_ACCES)); } pTgtAddr += numToWrite; pSourceAddr += numToWrite; } return (stateRestore_m (oldState)); }/********************************************************************************* Est_T::regsGet_m - read IU registers on target.**/UINT32 Est_T::regsGet_m ( WDB_REG_READ_DESC * pRegRead, WDB_MEM_XFER * pMemXfer ) { int status; EST_AllRegisters estRegSet; char * pWrsRegSet; EST_OperatingMode oldState;#if 1// #ifndef WIN32// XXX - remove if this breaks under MSVC 4.2 static Est_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 (stateBKM_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 estRegBuf; // value of register read. uint32 estRegSize; EST_Register whichEstReg; // which register to read. // Convert WRS register identifier into an EST identifier. status = whichEstRegGet_m (pRegRead->memRegion.baseAddr, &whichEstReg, &estRegSize); if (status != WDB_OK) { return (status); } estRegBuf = 0x0; // GDB thinks the status register is 32-bits. // Consequently, we need to adjust the buffer // pointer for the EST API which uses 16-bits // for the SR. if ((whichEstReg == EST_REG_SR) && (pRegRead->memRegion.numBytes == 4)) { UINT8 * pEstRegBuf = (UINT8 *) &estRegBuf; pEstRegBuf += 2; // skip padding in WRS REG_SET. status = regGetOne_m (whichEstReg, pEstRegBuf); // Convert host-byte ordering of EST's API to // Opaque byte ordering used by Tornado. *(UINT16 *) pEstRegBuf = FIX_16 (*(UINT16 *) pEstRegBuf); } else { status = regGetOne_m (whichEstReg, &estRegBuf); // Convert host-byte ordering of EST's API to // Opaque byte ordering used by Tornado. estRegBuf = FIX_32 (estRegBuf); } if (status != WDB_OK) { return (status); } pMemXfer->numBytes = pRegRead->memRegion.numBytes; pMemXfer->source = (WDB_OPQ_DATA_T) &estRegBuf; 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 = ::EST_ReadAllTargetRegisters (emulator_, &estRegSet); if (status != EST_SUCCESS) { return (wdbErrFigure_m ("EST_ReadAllTargetRegisters ()", status, WDB_ERR_PROC_FAILED)); } // Force EST 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 EST's API to // Opaque byte ordering of Tornado. wrsRegSet.dataReg[0] = FIX_32 (estRegSet.Dx[0]); /* data registers */ wrsRegSet.dataReg[1] = FIX_32 (estRegSet.Dx[1]); wrsRegSet.dataReg[2] = FIX_32 (estRegSet.Dx[2]); wrsRegSet.dataReg[3] = FIX_32 (estRegSet.Dx[3]); wrsRegSet.dataReg[4] = FIX_32 (estRegSet.Dx[4]); wrsRegSet.dataReg[5] = FIX_32 (estRegSet.Dx[5]); wrsRegSet.dataReg[6] = FIX_32 (estRegSet.Dx[6]); wrsRegSet.dataReg[7] = FIX_32 (estRegSet.Dx[7]); wrsRegSet.addrReg[0] = FIX_32 (estRegSet.Ax[0]); /* address registers */ wrsRegSet.addrReg[1] = FIX_32 (estRegSet.Ax[1]); wrsRegSet.addrReg[2] = FIX_32 (estRegSet.Ax[2]); wrsRegSet.addrReg[3] = FIX_32 (estRegSet.Ax[3]); wrsRegSet.addrReg[4] = FIX_32 (estRegSet.Ax[4]); wrsRegSet.addrReg[5] = FIX_32 (estRegSet.Ax[5]); wrsRegSet.addrReg[6] = FIX_32 (estRegSet.Ax[6]); wrsRegSet.addrReg[7] = FIX_32 (estRegSet.Ax[7]); wrsRegSet.sr = FIX_16 (estRegSet.SR); wrsRegSet.pc = (INSTR *) FIX_32 (estRegSet.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)); }/********************************************************************************* Est_T::regsSet_m - write target registers.*/UINT32 Est_T::regsSet_m (WDB_REG_WRITE_DESC * pRegWrite) { EST_AllRegisters estRegSet; EST_OperatingMode oldState; int status; // EST 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 ("Est_T::regsSet_m () - attempt to set registers in " "exception state.\n"); } // Enter background mode if (stateBKM_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 estRegSize; EST_Register whichEstReg; // which register to read. status = whichEstRegGet_m (pRegWrite->memXfer.destination, &whichEstReg, &estRegSize); if (status != WDB_OK) { return (status); } // XXX - this assumes VxWorks is the target OS. // To modify A7, EST's API requires modification of SSP instead! if (whichEstReg == EST_REG_A7) { whichEstReg = EST_REG_SSP; } // GDB thinks the status register is 32-bits. // Adjust the buffer for EST's API which uses 16-bits. if ((whichEstReg == EST_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 // EST API expects this information in host byte // ordering, so we must convert the register value. *(UINT16 *) pRegWriteVal = FIX_16 (*(UINT16 *) pRegWriteVal); status = regSetOne_m (whichEstReg, pRegWriteVal); } else { // memXfer.source contains register information // in the same representation it would appear in // target memory (i.e., it is opaque). The // EST API expects this information in host byte // ordering, so we must convert the register value. UINT32 estRegBuf = FIX_32 (*(UINT32 *) pRegWrite->memXfer.source); status = regSetOne_m (whichEstReg, (UINT8 *) &estRegBuf); } if (status != WDB_OK) { return (status); } return (stateRestore_m (oldState)); } // End of writing only one register //////////////////////////////////////////////////////////////////////////// // Read all target registers status = ::EST_ReadAllTargetRegisters (emulator_, &estRegSet); if (status != EST_SUCCESS) { // resume old state (void) stateRestore_m (oldState); return (wdbErrFigure_m ("EST_ReadAllTargetRegisters ()", status, WDB_ERR_PROC_FAILED)); } // Force EST 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 // EST API expects this information in host byte // ordering, so we must convert the register value. wrsRegSet.dataReg[0] = FIX_32 (estRegSet.Dx[0]); /* data registers */ wrsRegSet.dataReg[1] = FIX_32 (estRegSet.Dx[1]); wrsRegSet.dataReg[2] = FIX_32 (estRegSet.Dx[2]); wrsRegSet.dataReg[3] = FIX_32 (estRegSet.Dx[3]); wrsRegSet.dataReg[4] = FIX_32 (estRegSet.Dx[4]); wrsRegSet.dataReg[5] = FIX_32 (estRegSet.Dx[5]); wrsRegSet.dataReg[6] = FIX_32 (estRegSet.Dx[6]); wrsRegSet.dataReg[7] = FIX_32 (estRegSet.Dx[7]); wrsRegSet.addrReg[0] = FIX_32 (estRegSet.Ax[0]); /* address registers */ wrsRegSet.addrReg[1] = FIX_32 (estRegSet.Ax[1]); wrsRegSet.addrReg[2] = FIX_32 (estRegSet.Ax[2]); wrsRegSet.addrReg[3] = FIX_32 (estRegSet.Ax[3]); wrsRegSet.addrReg[4] = FIX_32 (estRegSet.Ax[4]); wrsRegSet.addrReg[5] = FIX_32 (estRegSet.Ax[5]); wrsRegSet.addrReg[6] = FIX_32 (estRegSet.Ax[6]); wrsRegSet.addrReg[7] = FIX_32 (estRegSet.Ax[7]); wrsRegSet.sr = FIX_16 (estRegSet.SR); wrsRegSet.pc = (INSTR *) FIX_32 (estRegSet.PC); // Modify desired registers pWrsRegBuf = (char *) &wrsRegSet; ::memcpy ((void *) (pWrsRegBuf + pRegWrite->memXfer.destination), (void *) pRegWrite->memXfer.source, pRegWrite->memXfer.numBytes); // Store in EST's reg set. estRegSet.Dx[0] = FIX_32 (wrsRegSet.dataReg[0]); /* data registers */ estRegSet.Dx[1] = FIX_32 (wrsRegSet.dataReg[1]); estRegSet.Dx[2] = FIX_32 (wrsRegSet.dataReg[2]); estRegSet.Dx[3] = FIX_32 (wrsRegSet.dataReg[3]); estRegSet.Dx[4] = FIX_32 (wrsRegSet.dataReg[4]); estRegSet.Dx[5] = FIX_32 (wrsRegSet.dataReg[5]); estRegSet.Dx[6] = FIX_32 (wrsRegSet.dataReg[6]); estRegSet.Dx[7] = FIX_32 (wrsRegSet.dataReg[7]); estRegSet.Ax[0] = FIX_32 (wrsRegSet.addrReg[0]); /* address regs */ estRegSet.Ax[1] = FIX_32 (wrsRegSet.addrReg[1]); estRegSet.Ax[2] = FIX_32 (wrsRegSet.addrReg[2]); estRegSet.Ax[3] = FIX_32 (wrsRegSet.addrReg[3]); estRegSet.Ax[4] = FIX_32 (wrsRegSet.addrReg[4]); estRegSet.Ax[5] = FIX_32 (wrsRegSet.addrReg[5]); estRegSet.Ax[6] = FIX_32 (wrsRegSet.addrReg[6]); estRegSet.Ax[7] = FIX_32 (wrsRegSet.addrReg[7]); // Ignored in EST's API // Must set SSP instead estRegSet.SSP = FIX_32 (wrsRegSet.addrReg[7]); // This assumes the use // of vxWorks! estRegSet.SR = FIX_16 (wrsRegSet.sr); estRegSet.PC = FIX_32 ((uint32) wrsRegSet.pc); status = ::EST_WriteAllTargetRegisters (emulator_, &estRegSet); if (status != EST_SUCCESS) { (void) stateRestore_m (oldState); return (wdbErrFigure_m ("EST_WriteAllTargetRegisters ()", status, WDB_ERR_PROC_FAILED)); } else { return (stateRestore_m (oldState)); } }/********************************************************************************* Est_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 Est_T::contextSuspend_m (WDB_CTX * pContext) { int status; EST_OperatingMode oldState; if (pContext->contextType != WDB_CTX_SYSTEM) { return (WDB_ERR_AGENT_MODE); } // Enter background mode. if (stateBKM_m (oldState) != WDB_OK) { return (WDB_ERR_AGENT_MODE); } status = EST_StopTarget (emulator_); return (wdbErrFigure_m ("EST_StopTarget ()", status, WDB_ERR_PROC_FAILED)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -