📄 acecpu32backend.cpp
字号:
/* acecpu32Backend.cpp - implements back end for ACE's SuperBDM emulator *//* Copyright 1984-1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01w,10oct96,bss updated agent version to Tornado 1.0.1.01v,23oct96,bss added Ace_T::cacheTxtUpdate_m().01u,17oct96,bss clean-up.01t,03oct96,bss fixed clash between WRS's ERROR and MSVC's ERROR macros.01s,23aug96,bss fixed byte ordering problems on little Endian hosts.01r,26jul96,bss removed WPWR_SHUTDOWN().01q,23jul96,bss added support for constructor failure.01p,22jul96,bss removed warning on out of bounds memory accesses.01o,11jul96,bss WIN32 port. Added EXT_FUNC support.01n,15may96,bss added exception state management.01m,02may96,bss added warning message to Ace_T::memWrite_m().01l,30apr96,bss changed wpwrLogMsg() to wpwrLogErr() where appropriate. moved the back end connect/disconnect functionality into Ace_T.01k,29apr96,bss changed memWrite_m() method to handle large requests.01j,26apr96,bss coding convention cleanup.01i,17apr96,bss upgraded for version 1.1 of ACE's API. removed intLock_m () and intUnlock_m ().01h,16apr96,bss implemented Colin's god-like hack to contextStep_m ().01g,16apr96,bss changed stateMon_m () and stateRet_m () to halt_m () and unhalt_m ().01f,10apr96,bss Changed wdbErrFigure_m () to handle unkown ACE error.01e,26mar96,bss Added intLock_m ()/intUnlock_m () to fix single step bug. Added reg1Set_m ().01d,25mar96,bss Added bpEventGen_m ().01d,17mar96,bss Added stateMon_m() and stateRet_m ().01c,15mar96,bss added event handling, single-stepping, context resume/stop.01b,11mar96,bss added memory and register read/write.01a,07mar96,bss written.*/////////////////////////////////////////////////////////////////////////////////// Description//// This module implements the vendor-specific methods used by the Ace_T// back end class./* includes */// Include windows.h first to avoid clash with Wind River definitions.#ifdef WIN32#include <windows.h>#endif /* #ifdef WIN32 */#include <memory.h>#include <sys/types.h>#ifndef WIN32#include <sys/time.h>#endif/* fix clash between Wind River's ERROR and MSVC's ERROR macros. */#ifdef ERROR#undef ERROR#define ERROR (-1)#endif /* #ifdef ERROR */#include "host.h"#include "windll.h"#include "wpwrutil.h"#include "wdb.h"#include "backend.h"#include "acecpu32Backend.h"#include "event.h"/* prototypes */// The Wind River Makefiles define the host type macro// SUN4_SUNOS4.// Prototypes needed, but missing in SunOS header files ...#ifdef SUN4_SUNOS4extern "C" {IMPORT int select (int, struct fd_set *, struct fd_set*, struct fd_set *, struct timeval *);IMPORT void bzero (char *, int);};#endif // #ifdef SUN4_SUNOS4/* locals */Ace_T * Ace_T::pTheAceBkEnd_;////////////////////////////////////////////////////////////////////////////////// Ace_T Constructors and Destructors/********************************************************************************* Ace_T::Ace_T - create logical ACE SuperBDM back end.** This constructor opens a connection to the SuperBDM emulator,* installs an event call back to handle events, and* initializes TGT_OPS information.*/Ace_T::Ace_T ( char * tgtName, u_int timeout, u_int retryNum, char * devName, u_int param, TGT_OPS * pTgtOps, EXT_FUNCS * pExtFuncs ) : Backend_T (tgtName, timeout, retryNum, devName, param, pTgtOps, pExtFuncs), oldTgtState_ (ACE_MODE_NOCONNECT), isEvent_ (FALSE), eventQueue_ (), pExcRegSet_ (0), excCount_ (0) { int status; // Store pointer to the back end so that we do not // need to pass 'this' around. if (pTheAceBkEnd_ != NULL) // Sanity check { WPWR_LOG_ERR ("Ace_T::pTheAceBkEnd_ != NULL.\n"); isNotValid_m (); return; } // Store the Ace_T version of the back end pointer. // It should be the same as the Backend_T version. Backend_T * pTheBackend = Backend_T::pTheBkEnd_s(); if (pTheBackend != this) { WPWR_LOG_WARN ("Ace_T::this != Backend_T::this!\n"); } // Downcast the Backend_T pointer to an Ace_T pointer. // The Ace_T this pointer should always equal the // Backend_T this pointer, unless something strange has // occurred because of multiple inheritance. pTheAceBkEnd_ = (Ace_T *) pTheBackend; // Open ACE connection to emulator. status = ::ACE_OpenConnection (&emulator_, tgtName); if (status != ACE_SUCCESS) { WPWR_LOG_ERR ("ACE_OpenConnection () failed: %s!\n", ::ACE_ErrorImage (status)); isNotValid_m (); return; } // Store ACE event fd in eventFd_. eventFd_ = ::ACE_FileDescriptor (emulator_); // Initialize Ace_T's TGT_OPS information, which // the target server needs to operate the back end. // // Note: Backend_T::Backend_T () has already initialized // the back end methods in the TGT_OPS structure. pTgtOps->tgtConnected = FALSE; pTgtOps->tgtEventFd = fdGet_m (); // Record event file descriptor. pTgtOps->tgtLink.name = "ACE SuperBDM BDM Mode"; pTgtOps->tgtLink.type = TGT_LINK_BDM_ACE; pTgtOps->tgtLink.speed = param; // Register event call backs to handle asynchronous events. // // Ace_T::eventCallBack() will be called by the ACE API // whenever a target event occurs. status = ::ACE_AddEventHandler (emulator_, ACE_MODECHANGE, eventCallBack, NULL); if (status != ACE_SUCCESS) { WPWR_LOG_ERR ("Ace_T::Ace_T () - can not install event handlers!\n"); isNotValid_m (); return; } status = ::ACE_AddEventHandler (emulator_, ACE_SIGNAL, eventCallBack, NULL); if (status != ACE_SUCCESS) { WPWR_LOG_ERR ("Ace_T::Ace_T () - can not install event handlers!\n"); isNotValid_m (); return; } status = ::ACE_AddEventHandler (emulator_, ACE_BREAKPOINT, eventCallBack, NULL); if (status != ACE_SUCCESS) { WPWR_LOG_ERR ("Ace_T::Ace_T () - can not install event handlers!\n"); isNotValid_m (); return; } // Allocate space for exception task's REG_SET. pExcRegSet_ = new REG_SET_68K; if (pExcRegSet_ == NULL) { WPWR_LOG_ERR ("new () failed!\n"); isNotValid_m (); return; } }/********************************************************************************* Ace_T::~Ace_T - destroys logical ACE SuperBDM back end.**/Ace_T::~Ace_T () { // Close connection if (::ACE_CloseConnection (emulator_) != ACE_SUCCESS) { WPWR_LOG_ERR ("ACE_CloseConnection () failed!\n"); } // Free other resources delete pExcRegSet_; }////////////////////////////////////////////////////////////////////////////////// SOMA functions//// These "SOMA" functions provide a convenient way of// failing all unsupported back end requests.// An unimplemented back end method should initially be // implemented as://// UINT32 Ace_T::<backendMethod> (...)// {// return (somaUINT32 ("<backendMethod>"));// }//// where <backendMethod> is the name of the unimplemented// method. A method should use the SOMA function with// the same return type as the method.//// When first developing a vendor-specific back end,// every method called an appropriate SOMA function.// To intially test the validity of the back end framework, // a developer should use wtxtcl to send WTX requests to the // back end via the target server. (WTX is the Wind River Tool // Exchange protocol which is used by tools to send requests // to the target server.) Most requests map directly onto a // back end method. The target server should// then invoke the corresponding back end method.//// As methods are implemented, the SOMA functions// will no longer be needed. The SOMA functions// are preserved here as an example for future// developers./********************************************************************************* somaUINT32 - fail a request which returns a UINT32.*/LOCAL UINT32 somaUINT32 (const char * pMethod) { WPWR_LOG_ERR ("Ace_T: - unsupported method %s.\n", pMethod); return (WDB_ERR_NO_AGENT_PROC); }#if 0// somaBOOL() and somaVOID() are no longer needed, but// are preserved to illustrate a useful technique// for developing a back end./********************************************************************************* somaBOOL - fail a request which returns a BOOL.*/LOCAL BOOL somaBOOL (const char * pMethod) { WPWR_LOG_ERR ("Ace_T: - unsupported method %s.\n", pMethod); return (FALSE); }/********************************************************************************* somaVOID - fail a request which returns a VOID.*/LOCAL void somaVOID (const char * pMethod) { WPWR_LOG_ERR ("Ace_T: - unsupported method %s.\n", pMethod); }#endif////////////////////////////////////////////////////////////////////////////////// Supported Backend methods/********************************************************************************* Ace_T::tgtConnect_m - establish connection with emulator.** Because the connection with the emulator was established in the* Ace_T constructor, this function merely records information* about the target's configuration.*/UINT32 Ace_T::tgtConnect_m (WDB_TGT_INFO * pWdbTgtInfo) { WPWR_LOG_MSG ("Establishing ACE SuperBDM connection... "); // XXX - this information should be read from the $WIND_TGT_INFO // file. Using hard-coded literals for now. pWdbTgtInfo->agentInfo.agentVersion = "ACE SuperBDM BDM 1.0.1"; pWdbTgtInfo->agentInfo.mtu = Ace_T::MaxMtu; // XXX pWdbTgtInfo->agentInfo.mode = WDB_MODE_EXTERN; pWdbTgtInfo->rtInfo.rtType = WDB_RT_VXWORKS; pWdbTgtInfo->rtInfo.rtVersion = "5.3"; pWdbTgtInfo->rtInfo.cpuType = CPU32; pWdbTgtInfo->rtInfo.hasFpp = FALSE; pWdbTgtInfo->rtInfo.hasWriteProtect = 0; pWdbTgtInfo->rtInfo.pageSize = 0xffffffff; /* The CPU32 target is always Big Endian */ pWdbTgtInfo->rtInfo.endian = 1234; pWdbTgtInfo->rtInfo.bspName = "ACE SuperBDM BDM Emulator"; pWdbTgtInfo->rtInfo.bootline = NULL; // Always invoke Backend_T::tgtConnect_m() to parse the // $WIND_TGT_INFO file with target configuration information. if (Backend_T::tgtConnect_m (pWdbTgtInfo) != WDB_OK) { WPWR_LOG_ERR ("Backend_T::tgtConnect_m () failed.\n"); return (WDB_ERR_PROC_FAILED); } WPWR_LOG_MSG ("succeeded.\n"); return (WDB_OK); }/********************************************************************************* Ace_T::tgtDisconnect_m - disconnect back end from emulator.** No clean up of the Ace_T emulator is needed, so this function* just returns WDB_OK.*/UINT32 Ace_T::tgtDisconnect_m (void) { return (WDB_OK); }/********************************************************************************* Ace_T::tgtPing_m - check if the "agent" is alive.*/UINT32 Ace_T::tgtPing_m (void) { ACE_OperatingMode tgtState; UINT32 status; tgtState = (ACE_OperatingMode) ::ACE_GetOperatingMode (emulator_); switch (tgtState) { case ACE_MODE_BDM: /* Background mode */ case ACE_MODE_RUN: /* Running */ case ACE_MODE_TRC: /* Non-realtime trace */ status = WDB_OK; break; case ACE_MODE_NOCONNECT: /* Not connected... */ status = WDB_ERR_NO_CONNECTION; break; case ACE_MODE_ERR: /* Error */ case ACE_MODE_SIM: /* Simulation mode */ case ACE_MODE_PFA: /* Performance */ default: status = WDB_ERR_COMMUNICATION; break; } return (status); }/********************************************************************************* Ace_T::memRead_m - read a chunk of target memory.** This function reads 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::memRead_m ( WDB_MEM_REGION * pMemRegion, WDB_MEM_XFER * pMemXfer ) { int status; ACE_OperatingMode oldState;// XXX - misleading because there maybe valid values outside// the range of addresses checked.#if 1 // Check that memory access is valid UINT32 aceMemBase = wdbTgtInfo_.rtInfo.memBase; UINT32 aceMemSize = wdbTgtInfo_.rtInfo.memSize; if ( ((UINT32) pMemRegion->baseAddr < aceMemBase) || ((UINT32) pMemRegion->baseAddr + pMemRegion->numBytes) > (aceMemBase + aceMemSize) ) { WPWR_LOG_WARN ("Invalid memory access of %#x bytes at %#x.\n", pMemRegion->numBytes, pMemRegion->baseAddr); return (WDB_ERR_MEM_ACCES); }#endif // Enter background mode. if (stateBDM_m (oldState) != WDB_OK) { return (WDB_ERR_AGENT_MODE); } // Book keeping for WTX protocol pMemXfer->source = (WDB_OPQ_DATA_T) pMemRegion->baseAddr; pMemXfer->numBytes = pMemRegion->numBytes; pMemXfer->destination = (TGT_ADDR_T) pMemRegion->param; // 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 read. TGT_INT_T numToRead; // num bytes to read in this iteration. UINT8 * pTgtAddr; // address to start next read. UINT8 * pDestAddr; // where to put result of read. pTgtAddr = (UINT8 *) pMemRegion->baseAddr; pDestAddr = (UINT8 *) pMemRegion->param; for ( numLeft = pMemRegion->numBytes; numLeft > 0; numLeft -= Ace_T::MaxMtu ) { numToRead = ((numLeft > Ace_T::MaxMtu) ? (TGT_INT_T) Ace_T::MaxMtu : numLeft);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -