sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Defines the DebugFunctionality class. This is responsible for sl@0: // providing configuration data needed by a host debugger to be able sl@0: // to correctly use the functionality provided by the run-mode debug subsystem. sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "d_rmd_breakpoints.h" sl@0: #include "rm_debug_kerneldriver.h" sl@0: #include "d_debug_functionality.h" sl@0: #include "d_buffer_manager.h" sl@0: sl@0: using namespace Debug; sl@0: sl@0: // Core sl@0: const TTag DebugFunctionalityCoreInfo[] = sl@0: { sl@0: {ECoreEvents,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreStartStop,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreMemory,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreRegister,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreBreakpoint,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreStepping,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreLists,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreLogging,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreHardware,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreApiConstants,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreKillObjects,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreSecurity,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreStopModeFunctions,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreStopModeBuffers,ETagTypeBoolean,0,EFalse}, sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityCore[] = sl@0: { sl@0: ETagHeaderIdCore,ECoreLast, sl@0: (TTag*)DebugFunctionalityCoreInfo sl@0: }; sl@0: sl@0: // Core sl@0: const TTag StopModeFunctionalityCoreInfo[] = sl@0: { sl@0: {ECoreEvents,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreStartStop,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreMemory,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreRegister,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreBreakpoint,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreStepping,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreLists,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreLogging,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreHardware,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreApiConstants,ETagTypeBoolean,0,EFalse}, sl@0: {ECoreKillObjects, ETagTypeBoolean,0, EFalse}, sl@0: {ECoreSecurity, ETagTypeBoolean,0,EFalse}, sl@0: {ECoreStopModeFunctions,ETagTypeBoolean,0,ETrue}, sl@0: {ECoreStopModeBuffers,ETagTypeBoolean,0,ETrue}, sl@0: }; sl@0: sl@0: const TSubBlock StopModeFunctionalityCore[] = sl@0: { sl@0: ETagHeaderIdCore,ECoreLast, sl@0: (TTag*)StopModeFunctionalityCoreInfo sl@0: }; sl@0: sl@0: const TSubBlock StopModeFunctionalityBuffers[]= sl@0: { sl@0: ETagHeaderIdBuffers,EBuffersLast, sl@0: (TTag*)NULL sl@0: }; sl@0: sl@0: const TTag StopModeFunctionalityFunctionsInfo[] = sl@0: { sl@0: #ifdef __LAUNCH_AS_EXTENSION__ sl@0: {EStopModeFunctionsExitPoint,ETagTypePointer,0,(TUint32)&StopModeDebug::ExitPoint}, sl@0: {EStopModeFunctionsGetList,ETagTypePointer,0,(TUint32)&StopModeDebug::GetList}, sl@0: {EStopModeFunctionsTestAPI,ETagTypePointer,0,(TUint32)&StopModeDebug::TestAPI} sl@0: #else sl@0: {EStopModeFunctionsExitPoint,ETagTypePointer,0,NULL}, sl@0: {EStopModeFunctionsGetList,ETagTypePointer,0,NULL}, sl@0: {EStopModeFunctionsTestAPI,ETagTypePointer,0,NULL} sl@0: #endif sl@0: }; sl@0: sl@0: const TSubBlock StopModeFunctionalityFunctions[]= sl@0: { sl@0: ETagHeaderIdStopModeFunctions,EStopModeFunctionsLast, sl@0: (TTag*)StopModeFunctionalityFunctionsInfo sl@0: }; sl@0: sl@0: sl@0: // Memory sl@0: const TTag DebugFunctionalityMemoryInfo[] = sl@0: { sl@0: {EMemoryRead,ETagTypeBoolean,0,ETrue}, sl@0: {EMemoryWrite,ETagTypeBoolean,0,ETrue}, sl@0: {EMemoryAccess64,ETagTypeBoolean,0,EFalse}, sl@0: {EMemoryAccess32,ETagTypeBoolean,0,ETrue}, sl@0: {EMemoryAccess16,ETagTypeBoolean,0,EFalse}, sl@0: {EMemoryAccess8,ETagTypeBoolean,0,EFalse}, sl@0: {EMemoryBE8,ETagTypeBoolean,0,EFalse}, sl@0: {EMemoryBE32,ETagTypeBoolean,0,EFalse}, sl@0: {EMemoryLE8,ETagTypeBoolean,0,ETrue}, sl@0: {EMemoryMaxBlockSize,ETagTypeTUint32,0,16 * KKilo /* 16Kbytes */} // binaryMax size of memory requests in bytes sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityMemory[]= sl@0: { sl@0: ETagHeaderIdMemory,EMemoryLast, sl@0: (TTag*)DebugFunctionalityMemoryInfo sl@0: }; sl@0: sl@0: // Kill Objects sl@0: const TTag DebugFunctionalityKillObjectsInfo[] = sl@0: { sl@0: {EFunctionalityKillThread,ETagTypeBoolean,0,EFalse}, sl@0: {EFunctionalityKillProcess,ETagTypeBoolean,0,ETrue} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityKillObjects[]= sl@0: { sl@0: ETagHeaderIdKillObjects,EFunctionalityKillObjectLast, sl@0: (TTag*)DebugFunctionalityKillObjectsInfo sl@0: }; sl@0: sl@0: // Core Registers sl@0: const TTag DebugFunctionalityRegistersCoreInfo[] = sl@0: { sl@0: {ERegisterR0,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR1,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR2,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR3,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR4,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR5,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR6,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR7,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR8,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR9,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR10,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR11,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR12,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR13,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR14,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR15,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterCpsr,ETagTypeEnum, 4,EAccessReadWrite}, sl@0: {ERegisterR13Svc,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR14Svc,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterSpsrSvc,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR13Abt,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR14Abt,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterSpsrAbt,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR13Und,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR14Und,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterSpsrUnd,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR13Irq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR14Irq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterSpsrIrq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR8Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR9Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR10Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR11Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR12Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR13Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterR14Fiq,ETagTypeEnum, 4,EAccessNone}, sl@0: {ERegisterSpsrFiq, ETagTypeEnum, 4,EAccessNone} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityRegistersCore[] = sl@0: { sl@0: ETagHeaderIdRegistersCore, ERegisterLast, sl@0: (TTag*)DebugFunctionalityRegistersCoreInfo sl@0: }; sl@0: sl@0: // Co-processor registers sl@0: const TTag DebugFunctionalityRegistersCoProInfo[]= sl@0: { sl@0: //this is the DACR register sl@0: {0x00300f01, ETagTypeTUint32, 4, EAccessReadWrite} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityRegistersCoPro[]= sl@0: { sl@0: ETagHeaderIdCoProRegisters,1, sl@0: (TTag*)DebugFunctionalityRegistersCoProInfo sl@0: }; sl@0: sl@0: // Breakpoints sl@0: const TTag DebugFunctionalityBreakpointsInfo[]= sl@0: { sl@0: {EBreakpointThread,ETagTypeBoolean,0,ETrue}, sl@0: {EBreakpointProcess,ETagTypeBoolean,0,ETrue}, sl@0: {EBreakpointSystem,ETagTypeBoolean,0,EFalse}, sl@0: {EBreakpointArm,ETagTypeBoolean,0,ETrue}, sl@0: {EBreakpointThumb,ETagTypeBoolean,0,ETrue}, sl@0: {EBreakpointT2EE,ETagTypeBoolean,0,ETrue}, sl@0: {EBreakpointArmInst,ETagTypeBoolean,0,EFalse}, sl@0: {EBreakpointThumbInst,ETagTypeBoolean,0,EFalse}, sl@0: {EBreakpointT2EEInst,ETagTypeBoolean,0,ETrue}, sl@0: {EBreakpointSetArmInst,ETagTypeBoolean,0,EFalse}, sl@0: {EBreakpointSetThumbInst,ETagTypeBoolean,0,EFalse}, sl@0: {EBreakpointSetT2EEInst,ETagTypeBoolean,0,ETrue} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityBreakpoints[] = sl@0: { sl@0: ETagHeaderIdBreakpoints, EBreakpointLast, sl@0: (TTag*)DebugFunctionalityBreakpointsInfo sl@0: }; sl@0: sl@0: // Stepping sl@0: const TTag DebugFunctionalitySteppingInfo[]= sl@0: { sl@0: {EStep,ETagTypeBoolean,0,ETrue} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityStepping[] = sl@0: { sl@0: ETagHeaderIdStepping, EStepLast, sl@0: (TTag*)DebugFunctionalitySteppingInfo sl@0: }; sl@0: sl@0: // Execution Control sl@0: const TTag DebugFunctionalityExecutionInfo[]= sl@0: { sl@0: {EExecThreadSuspendResume,ETagTypeBoolean,0,ETrue}, sl@0: {EExecProcessSuspendResume,ETagTypeBoolean,0,EFalse}, sl@0: {EExecSystemSuspendResume,ETagTypeBoolean,0,EFalse}, sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityExecution[]= sl@0: { sl@0: ETagHeaderIdExecution, EExecLast, sl@0: (TTag*)DebugFunctionalityExecutionInfo sl@0: }; sl@0: sl@0: // Events sl@0: const TTag DebugFunctionalityEventsInfo[]= sl@0: { sl@0: {EEventsBreakPoint,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsProcessBreakPoint,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsSwExc,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsHwExc,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsKillThread,ETagTypeEnum,0,EActionContinue}, sl@0: {EEventsAddLibrary,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsRemoveLibrary,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsUserTrace,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsStartThread,ETagTypeEnum,0,EActionSuspend}, sl@0: {EEventsBufferFull,ETagTypeEnum,0,EActionContinue}, sl@0: {EEventsUnknown,ETagTypeEnum,0,EActionContinue}, sl@0: {EEventsUserTracesLost, ETagTypeEnum, 0, EActionContinue}, sl@0: {EEventsAddProcess,ETagTypeEnum,0,EActionContinue}, sl@0: {EEventsRemoveProcess,ETagTypeEnum,0,EActionContinue} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityEvents[] = sl@0: { sl@0: ETagHeaderIdEvents, EEventsLast, sl@0: (TTag*)DebugFunctionalityEventsInfo sl@0: }; sl@0: sl@0: // API Constants sl@0: const TTag DebugFunctionalityApiConstantsInfo[]= sl@0: { sl@0: {EApiConstantsTEventInfoSize,ETagTypeTUint32,0,sizeof(TEventInfo)}, sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityApiConstants[] = sl@0: { sl@0: ETagHeaderIdApiConstants, EApiConstantsLast, sl@0: (TTag*)DebugFunctionalityApiConstantsInfo sl@0: }; sl@0: sl@0: // Listings sl@0: const TTag DebugFunctionalityListInfo[] = sl@0: { sl@0: {EProcesses,ETagTypeBitField,0,EScopeGlobal}, sl@0: {EThreads,ETagTypeBitField,0,EScopeGlobal|EScopeProcessSpecific|EScopeThreadSpecific}, sl@0: {ECodeSegs,ETagTypeBitField,0,EScopeGlobal|EScopeProcessSpecific|EScopeThreadSpecific}, sl@0: {EXipLibraries,ETagTypeBitField,0,EScopeGlobal}, sl@0: {EExecutables,ETagTypeBitField,0,EScopeGlobal}, sl@0: {ELogicalDevices,ETagTypeBitField,0,EScopeNone}, sl@0: {EMutexes,ETagTypeBitField,0,EScopeNone}, sl@0: {EServers,ETagTypeBitField,0,EScopeNone}, sl@0: {ESessions,ETagTypeBitField,0,EScopeNone}, sl@0: {ESemaphores,ETagTypeBitField,0,EScopeNone}, sl@0: {EChunks,ETagTypeBitField,0,EScopeNone}, sl@0: {EBreakpoints,ETagTypeBitField,0,EScopeNone}, sl@0: {ESetBreak,ETagTypeBitField,0,EScopeNone}, sl@0: {ERemoveBreak,ETagTypeBitField,0,EScopeNone}, sl@0: {EModifyBreak,ETagTypeBitField,0,EScopeNone}, sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalityList[] = sl@0: { sl@0: ETagHeaderList, EListLast, sl@0: (TTag*)DebugFunctionalityListInfo sl@0: }; sl@0: sl@0: // Listings sl@0: const TTag StopModeFunctionalityListInfo[] = sl@0: { sl@0: {EProcesses,ETagTypeBitField,0,EScopeNone}, sl@0: {EThreads,ETagTypeBitField,0,EScopeNone}, sl@0: {ECodeSegs,ETagTypeBitField,0,EScopeGlobal|EScopeThreadSpecific}, sl@0: {EXipLibraries,ETagTypeBitField,0,EScopeNone}, sl@0: {EExecutables,ETagTypeBitField,0,EScopeNone}, sl@0: {ELogicalDevices,ETagTypeBitField,0,EScopeNone}, sl@0: {EMutexes,ETagTypeBitField,0,EScopeNone}, sl@0: {EServers,ETagTypeBitField,0,EScopeNone}, sl@0: {ESessions,ETagTypeBitField,0,EScopeNone}, sl@0: {ESemaphores,ETagTypeBitField,0,EScopeNone}, sl@0: {EChunks,ETagTypeBitField,0,EScopeNone}, sl@0: {EBreakpoints,ETagTypeBitField,0,EScopeNone}, sl@0: {ESetBreak,ETagTypeBitField,0,EScopeNone}, sl@0: {ERemoveBreak,ETagTypeBitField,0,EScopeNone}, sl@0: {EModifyBreak,ETagTypeBitField,0,EScopeNone}, sl@0: }; sl@0: sl@0: const TSubBlock StopModeFunctionalityList[] = sl@0: { sl@0: ETagHeaderList, EListLast, sl@0: (TTag*)StopModeFunctionalityListInfo sl@0: }; sl@0: // not implemented sl@0: sl@0: // actionpoints sl@0: // not implemented sl@0: sl@0: // codeapplets sl@0: // not implemented sl@0: sl@0: // BTrace/UTrace sl@0: // not implemented sl@0: sl@0: // Security sl@0: const TTag DebugFunctionalitySecurityInfo[]= sl@0: { sl@0: {ESecurityOEMDebugToken,ETagTypeBoolean,0,ETrue} sl@0: }; sl@0: sl@0: const TSubBlock DebugFunctionalitySecurity[] = sl@0: { sl@0: ETagHeaderIdSecurity, ESecurityLast, sl@0: (TTag*)DebugFunctionalitySecurityInfo sl@0: }; sl@0: sl@0: TUint32 TDebugFunctionality::GetDebugFunctionalityBufSize(void) sl@0: { sl@0: TUint32 df_size = 0; sl@0: sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityCore); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityMemory); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityRegistersCore); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityRegistersCoPro); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityBreakpoints); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityStepping); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityExecution); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityEvents); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityApiConstants); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityList); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalityKillObjects); sl@0: df_size += ComputeBlockSize((const TSubBlock&)DebugFunctionalitySecurity); sl@0: sl@0: return df_size; sl@0: } sl@0: sl@0: TUint32 TDebugFunctionality::GetStopModeFunctionalityBufSize(void) sl@0: { sl@0: TUint32 bytes = 0; sl@0: sl@0: // First four bytes are length field sl@0: // Next four are version sl@0: // Last four bytes will be the checksum sl@0: bytes = 12 + sl@0: ComputeBlockSize((const TSubBlock&)StopModeFunctionalityCore) + sl@0: ComputeBlockSize((const TSubBlock&)StopModeFunctionalityBuffers) + sl@0: ComputeBlockSize((const TSubBlock&)StopModeFunctionalityFunctions) + sl@0: ComputeBlockSize((const TSubBlock&)StopModeFunctionalityList); sl@0: sl@0: return bytes; sl@0: } sl@0: sl@0: TBool TDebugFunctionality::GetStopModeFunctionality(TDes8& aDFBlock) sl@0: { sl@0: TUint32 size = GetStopModeFunctionalityBufSize(); sl@0: if (aDFBlock.MaxLength() < size) sl@0: { sl@0: // Insufficient space to contain the debug functionality block sl@0: return EFalse; sl@0: } sl@0: sl@0: TUint8* ptr = (TUint8*)&size; sl@0: aDFBlock.SetLength(0); sl@0: aDFBlock.Append(ptr, 4); sl@0: TVersion version = TVersion(KStopModeMajorVersionNumber, KStopModeMinorVersionNumber, KStopModePatchVersionNumber); sl@0: ptr = (TUint8*)&version; sl@0: aDFBlock.Append(ptr, sizeof(TVersion)); sl@0: sl@0: AppendBlock((const TSubBlock&)StopModeFunctionalityCore,aDFBlock); sl@0: AppendBlock((const TSubBlock&)StopModeFunctionalityFunctions,aDFBlock); sl@0: AppendBlock((const TSubBlock&)StopModeFunctionalityList,aDFBlock); sl@0: sl@0: const TTagHeader& header = StopModeFunctionalityBuffers->iHeader; sl@0: aDFBlock.Append((TUint8*)&header, sizeof(TTagHeader)); sl@0: sl@0: for(TInt i=0; i