📄 event.cpp
字号:
/* event.cpp - event handling library *//* Copyright 1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,18nov96,bss added BEDK_VERSION_1_0 for Tornado 1.0 compatibility.01j,13nov96,bss clean up.01i,03oct96,bss fixed byte-ordering problem with BDM_EXC_INFO.01i,03oct96,bss fixed clash between WRS's ERROR and MSVC's ERROR macros.01h,12jul96,bss Win32 port.01g,15may96,bss added exception state management.01f,02may96,bss added support for unexpected execution of 'bgnd'.01e,01may96,bss changed exception handling to use new ACE API support.01d,30apr96,bss changed wpwrLogMsg() to wpwrLogErr() where appropriate.01c,26apr96,bss coding convention cleanup.01b,23apr96,bss added support for target exceptions.01a,14mar96,bss written.*//*DESCRIPTIONThis library implements the Event_T class which is usedby the ACE back end to handle target events. All the work of Event_T is done by the constructor, whichtakes an ACE event and synthesizes a WDB style event.The Ace_T class manages the events.Note: to handle exceptions, vxWorks's _func_excBaseHook isutilized to capture information about the exception andnotify the emulator of the exception by executing the 'bgnd' instruction, which puts the target in background mode.*//* Includes */// Include windows.h first. Otherwise, Windows definitions// clash with WRS definitions.#ifdef WIN32#include <windows.h>/* fix clash between Wind River's ERROR and MSVC's ERROR macros. */#ifdef ERROR#undef ERROR#define ERROR (-1)#endif /* #ifdef ERROR */#endif /* #ifdef WIN32 */#include <memory.h>#include "rw/tooldefs.h"#include "rw/collect.h"#include "symLib.h"#include "wdb.h"#include "wpwrutil.h"#include "event.h"#include "backend.h"#include "acecpu32Backend.h"#include "bdmExcLib.h"/** RWDEFINE_COLLECTABLE - defines several methods needed by Event_T*/ RWDEFINE_COLLECTABLE (Event_T, eventClassID) // Required by Rogue Wave#if 0 RWDEFINE_COLLECTABLE (Event_T, EVENT_T_RW_CLASS_ID) // Required by RogueWave#endif////////////////////////////////////////////////////////////////////////////////// Constructors and Destructors/********************************************************************************* Event_T::Event_T - default constructor.*/Event_T::Event_T () : RWCollectable () { // This should never be called WPWR_LOG_ERR ("Event_T::Event_T() was called.\n"); }/********************************************************************************* Event_T::Event_T - constructs an event from an ACE event.** This construtor creates an Event_T object which Ace_T uses to* manage event information. The constructor uses ACE event* information to create Wind River's WDB event information.*/Event_T::Event_T (ACE_Event * pEvent) : RWCollectable () { // Transfer pEvent into WDB_EVT_DESC switch (pEvent->any.type) { case ACE_BREAKPOINT: bpEventMake_m (pEvent); break; case ACE_SIGNAL: signalEventMake_m (pEvent); break; case ACE_MODECHANGE: modeChangeEventMake_m (pEvent); break; default: wdbEvent_.evtType = WDB_EVT_NONE; WPWR_LOG_ERR ("Invalid ACE event type %#x.\n", pEvent->any.type); break; } }////////////////////////////////////////////////////////////////////////////////// Event_T Helper Methods./********************************************************************************* Event_T::signalEventMake_m - build a WDB_EVT_DATA for ACE_SIGNAL event.** ACE_SIGNAL events are either double bus faults or the execution* of the BGND instruction on the target. The later is used to notify* the host of exceptions on the target, so a WDB_EVT_EXC event is built.*/void Event_T::signalEventMake_m (ACE_Event * pEvent) { ACE_SignalEvent * pSigEvent = &pEvent->sig; // Handle the different signal types. switch (pSigEvent->cause) { case ACE_SIG_BGND_INSTRUCTION: // The 'bgnd' instruction was executed on the // target. excEventMake_m (pEvent); break; case ACE_SIG_DOUBLE_BUS: // Let the user know about the double bus fault, // so they can either examine the target or // restart everything. wdbEvent_.evtType = WDB_EVT_NONE; WPWR_LOG_WARN ("Event : ACE_SIGNAL - double bus fault!\n"); break; default: wdbEvent_.evtType = WDB_EVT_NONE; // unknown event. WPWR_LOG_ERR ("Event : ACE_SIGNAL - unknown cause %#x!\n", pSigEvent->cause); break; } }/********************************************************************************* Event_T::modeChangeEventMake_m - converts ACE_MODECHANGE event to WDB event.**/void Event_T::modeChangeEventMake_m (ACE_Event * pEvent) { // The target server does not care about target mode changes, // however, another tool might. This event type is mapped onto // the UNKNOWN event type by the target server. wdbEvent_.evtType = WDB_EVT_NONE; return; }/********************************************************************************* Event_T::bpEventMake_m - build a WDB_EVT_DATA for ACE_BREAKPOINT event.*/void Event_T::bpEventMake_m (ACE_Event * pEvent) { WDB_BP_INFO * pBpInfo = (WDB_BP_INFO *) &wdbEvent_.eventInfo; UINT32 status; uint32 aceRegBuf; // buffer for reading a register Ace_T * pBackend; wdbEvent_.evtType = WDB_EVT_BP; // XXX - Hardware breakpoints are // not supported by the ACE API. pBpInfo->numInts = 5; pBpInfo->context.contextType = WDB_CTX_SYSTEM; pBpInfo->context.contextId = 0xffffffff; pBpInfo->pc = (TGT_ADDR_T) pEvent->bp.address; // PC pBackend = Ace_T::pTheAceBkEnd_s (); status = pBackend->regGetOne_m (ACE_REG_A6, &aceRegBuf); if (status != WDB_OK) { aceRegBuf = 0xfefefefe; WPWR_LOG_ERR ("Ace_T::regGetOne_m () failed!\n"); } pBpInfo->fp = (TGT_ADDR_T) aceRegBuf; // A6 status = pBackend->regGetOne_m (ACE_REG_A7, &aceRegBuf); if (status != WDB_OK) { aceRegBuf = 0xfefefefe; WPWR_LOG_ERR ("Ace_T::regGetOne_m () failed!\n"); } pBpInfo->sp = (TGT_ADDR_T) aceRegBuf; // A7 }/********************************************************************************* Event_T::excEventMake_m - create an exception event.*/void Event_T::excEventMake_m ( ACE_Event * pEvent ) { WDB_EXC_INFO * pWdbExcInfo = (WDB_EXC_INFO *) &wdbEvent_.eventInfo; // Read information about the exception from the target. BDM_EXC_INFO * pTgtExcInfo = eventTypeGet_m (); if (pTgtExcInfo == NULL) { WPWR_LOG_ERR ("Event_T::eventTypeGet () failed.\n"); wdbEvent_.evtType = WDB_EVT_NONE; // dummy event return; } // Check if 'bgnd' instruction was not executed // because of the exception notification handler, i.e., // it is code written by the user. if (!pTgtExcInfo->bdmIsException) { WPWR_LOG_WARN ("Unexpected 'bgnd' instruction encountered.\n"); bpEventGen_m (); // Generate dummy breakpoint event. return; } // Enter exception state. UINT32 status; Ace_T * pBackend; pBackend = Ace_T::pTheAceBkEnd_s (); status = pBackend->excStateEnter_m (pTgtExcInfo); if (status != WDB_OK) { WPWR_LOG_ERR ("Ace_T::excStateEnter_m () failed!\n"); } // Record event information. wdbEvent_.evtType = WDB_EVT_EXC; pWdbExcInfo->numInts = 4; pWdbExcInfo->vec = pTgtExcInfo->excVector; pWdbExcInfo->pEsf = (TGT_ADDR_T) pTgtExcInfo->pESF; pWdbExcInfo->context.contextType = WDB_CTX_SYSTEM; pWdbExcInfo->context.contextId = 0xffffffff; }/********************************************************************************* Event_T::eventTypeGet_m - get BDM_EXC_INFO exception information.** This member function obtains information about an exception which* just occurred on the target. This information is obtained by* reading the data stored in a target-resident, global variable, bdmExcInfo.* When an exception occurs on the target, a special exception handling * hook captures the necessary information and stores it in a bdmExcInfo.* This special exception handling hook must be installed on the target, * as discussed in acecpu32Backend.h.*/BDM_EXC_INFO * Event_T::eventTypeGet_m () { TGT_ADDR_T bdmInfoAddr; SYM_TYPE symType; STATUS status; static BDM_EXC_INFO bdmExcInfo; // lookup "_bdmExcInfo" to find where it is stored in target memory Ace_T * pBackend = Ace_T::pTheAceBkEnd_s ();#ifndef BEDK_VERSION_1_0 if (SYM_FIND_BY_NAME_AND_TYPE (pBackend->tgtsvrSymTblIdGet_m (), "_bdmExcInfo", (char **) &bdmInfoAddr, &symType, SYM_GLOBAL | SYM_TEXT, SYM_GLOBAL | SYM_TEXT) != OK)#else if (symFindByNameAndType (tgtSymTbl, "_bdmExcInfo", (char **) &bdmInfoAddr, &symType, SYM_GLOBAL | SYM_TEXT, SYM_GLOBAL | SYM_TEXT) != OK)#endif /* #ifndef BEDK_VERSION_1_0 */ { WPWR_LOG_ERR ("symFindByNameAndType () failed.\n"); wdbEvent_.evtType = WDB_EVT_NONE; // dummy event return (NULL); } // Read information about the exception. status = Backend_T::tgtRead_s (bdmInfoAddr, &bdmExcInfo, sizeof (bdmExcInfo)); if (status != OK) { WPWR_LOG_ERR ("Backend_T::tgtRead_m () failed.\n"); wdbEvent_.evtType = WDB_EVT_NONE; // dummy event return (NULL); } // fix byte ordering. bdmExcInfo.excVector = FIX_32 (bdmExcInfo.excVector); bdmExcInfo.pESF = (UINT8 *) (FIX_32 ((TGT_ADDR_T) bdmExcInfo.pESF)); bdmExcInfo.pIuRegs = FIX_32 (bdmExcInfo.pIuRegs); bdmExcInfo.bdmIsException = FIX_32 (bdmExcInfo.bdmIsException); return (&bdmExcInfo); }/********************************************************************************* Event_T::bpEventGen_m - generate a dummy breakpoint event.** This function generates a dummy breakpoint event when* an unexpected 'bgnd' instruction is executed on the target.*/void Event_T::bpEventGen_m () { // Synthesize a breakpoint event. ACE_Event dummyEvent; UINT32 status; uint32 aceRegBuf; // buffer for reading a register Ace_T * pBackend; ::memset (&dummyEvent, 0x00, sizeof (dummyEvent)); // Create dummy ACE breakpoint event. dummyEvent.any.type = ACE_BREAKPOINT; // Read the PC for dummy ACE_Event. pBackend = Ace_T::pTheAceBkEnd_s (); status = pBackend->regGetOne_m (ACE_REG_PC, &aceRegBuf); if (status != WDB_OK) { aceRegBuf = 0xfefefefe; WPWR_LOG_ERR ("Ace_T::regGetOne_m () failed!\n"); } dummyEvent.bp.address = (TGT_ADDR_T) aceRegBuf; // PC // Create Event_T bpEventMake_m (&dummyEvent); // Fills in the rest of the WDB info. }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -