// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// Definition of the stop-mode debug interface.
//
/**
@file
@publishedPartner
@prototype
*/
#ifndef D_STOP_MODE_API_H
#define D_STOP_MODE_API_H
#include <rm_debug_api.h>
#include <plat_priv.h>
namespace Debug
{
/**
* The stop-mode debug interface is a stateless interface which may be called at any point
* except user mode, provided the rest of the OS is not going to run or pre-empt it.
* For example, for stop-mode debugging, the ICE may run the stop_mode_api routine to
* collect information about the system so long as no exceptions are enabled, and all
* registers/stack are preserved and restored after the call completes. Note that in an SMP environment
* it is expected that ALL the CPU's have been stopped
*/
/** Stop Mode Debug API Version Numbers */
const TUint KStopModeMajorVersionNumber=0;
const TUint KStopModeMinorVersionNumber=0;
const TUint KStopModePatchVersionNumber=2;
/**
* Enumerators used to identify the buffers created for use with the Stop-Mode Debug API.
*/
enum TBufferType
{
EBuffersFunctionality = 0, /**< Enumerator corresponding to the buffer created to store the debug functionality block. */
EBuffersRequest = 1, /**< Enumerator corresponding to the request buffer. */
EBuffersResponse = 2, /**< Enumerator corresponding to the response buffer. */
/**
* @internalTechnology
* A user should find the number of buffer tags from the DFBlock rather than this enumerator.
*/
EBuffersLast
};
/**
* Enumerators used to identify the functions for use with the Stop-Mode Debug API.
*/
enum TFunctionalityStopModeFunctions
{
EStopModeFunctionsExitPoint = 0, /**< Enumerator corresponding to the Debug::GetList() function. */
EStopModeFunctionsGetList = 1, /**< Enumerator corresponding to the Debug::ExitPoint() function. */
EStopModeFunctionsTestAPI = 2, /**< Enumerator corresponding to the Debug::TestAPI() function. */
/**
* @internalTechnology
* A user should find the number of supported functions from the DFBlock rather than this enumerator.
*/
EStopModeFunctionsLast
};
/**
* This structure defines the start elements of a stop-mode debug functionality block.
* It is assumed that the rest of the functionality block will extend past the end of
* the structure and will be accessed according to the documented format of the
* stop-mode functionality block.
*/
struct DFunctionalityBlock
{
TUint32 iSize; /**< Size of the functionality block in bytes. */
TVersion iStopModeVersion; /** Version of the stop-mode debug API. */
TTagHeader iFirstHeader; /** The header for the first sub-block in the functionality block. */
};
/**
* This structure used for extracting static data using the Stop Mode Extension API
* StopModeDebug::GetList using TListId::EStaticInfo
* as the first argument.
*/
class TStaticListEntry
{
public:
/** Build time of ROM in microseconds */
TUint64 iTime;
/** Number of CPUs */
TInt iCpuNumbers;
/** ROM build number */
TUint16 iBuildNumber;
/** Major Version of ROM build */
TUint8 iMajorVersion;
/** Minor Version of ROM build */
TUint8 iMinorVersion;
/** Currently unused element. May be used in future to aid maintaining compatibility. */
TUint32 iSpare[10];
};
/**
* This structure represents a request to return a list via the SM API
*/
struct TListItem
{
/** Size of this TListItem */
TUint32 iSize;
/** The type of list to return */
TListId iListId;
/** The scope of the list to return */
TListScope iListScope;
/**
* Data corresponding to the list scope, for example if iListScope specifies a thread
* specific listing then iScopeData should contain the thread ID to return the list for.
* If iListScope = EGlobalScope then iScopeData is ignored.
*/
TUint64 iScopeData;
/**
* The first element in the target list to return data for. For example if a thread list is being
* requested then specifying iStartElement = 100 indicates that the first thread to be returned should
* be the first thread with thread ID >= 100.
*/
TUint64 iStartElement;
/** Memory address of where the data should be written */
TAny* iBufferAddress;
/** Size of the buffer available for writing the data into */
TUint32 iBufferSize;
};
/**
* Structure that describes a list being returned
*/
struct TListReturn
{
/** List that is being returned */
TUint32 iReqNo;
/** Number of items in the returned list */
TUint32 iNumberItems;
/** Size occupied by data */
TUint32 iDataSize;
};
/**
* Class used to add extended functionality to DDebuggerInfo class.
*
* @publishedPartner
* @prototype
*/
class DStopModeExtension
{
public:
DStopModeExtension()
:iFunctionalityBlock(NULL),
iSpare1(0),
iSpare2(0),
iSpare3(0),
iSpare4(0),
iSpare5(0),
iSpare6(0),
iSpare7(0)
{};
static void Install(DStopModeExtension* aExt);
public:
Debug::DFunctionalityBlock* iFunctionalityBlock;
TUint32 iSpare1;
TUint32 iSpare2;
TUint32 iSpare3;
TUint32 iSpare4;
TUint32 iSpare5;
TUint32 iSpare6;
TUint32 iSpare7;
};
/**
* This is the interface to the stop mode debug API. The ROM resident address of these functions can be found
* from the Debug Functionality block via the superpage. It may be assumed that all of these functions
* will exit via the function ExitPoint and thus setting a breakpoint there will capture the end of execution.
* For more detailed information, see the stop mode guide.
*/
class StopModeDebug
{
public:
/**
* Stop mode debug API. Call this to action any request for information, or to manipulate
* debug data.
*
* This is a stateless interface - it does not record information about previous invocations. It
* does not take any OS locks, wait on any synchronisation objects, allocate/deallocate heap memory or call
* ANY OS routines (unless documented as doing so). It will not cause any exceptions due to page faults,
* but will report that it encountered such problems where appropriate.
*
* @pre This must be called with a valid stack in supervisor mode. There are no exceptions/interrupts
* enabled which will cause the OS state to change during the execution of this routine.
* @args aItem Structure describing the list we want to retrieve
* @args aCheckConsistent If true, this will honour any locks the system holds and return KErrNotReady
* @return KErrNone on success or one of the other system wide error codes.
*/
IMPORT_C static TInt GetList(const TListItem* aItem, TBool aCheckConsistent);
/**
* Stop mode debug API
*
* This is a test function that allows us to test our communications with the hardware debugger
*
* @pre This must be called with a valid stack in supervisor mode. There are no exceptions/interrupts
* enabled which will cause the OS state to change during the execution of this routine.
* @args aItem Structure describing the list we want to retrieve
* @return KErrNone on success or one of the other system wide error codes.
*/
IMPORT_C static TInt TestAPI(const TListItem* aItem);
public:
IMPORT_C static TInt ExitPoint(const TInt aReturnValue);
private:
/** Code segment list routines */
static TInt ProcessCodeSeg(TUint8*& aBuffer, TUint32& aBufferSize, DEpocCodeSeg* aCodeSeg);
//TODO: Horrible signature. Structify it
static TInt AppendCodeSegData(TUint8*& aBuffer, TUint32& aBufferSize, const TModuleMemoryInfo& aMemoryInfo, const TBool aIsXip, const TCodeSegType aCodeSegType, const TDesC8& aFileName, DEpocCodeSeg* aCodeSeg);
static TInt GetCodeSegList(const TListItem* aItem, bool aCheckConsistent);
static DEpocCodeSeg* GetNextCodeSeg(const TUint32 aStart, const Debug::TListScope aListScope, const TUint64 aScopeData);
static DEpocCodeSeg* GetNextGlobalCodeSeg(const TUint32 aStart);
static DEpocCodeSeg* GetNextThreadSpecificCodeSeg(const TUint32 aStart, const TUint64 aThreadId);
/** Process list routines */
static TInt GetProcessList(const TListItem* aItem, bool aCheckConsistent);
static TInt AppendProcessToBuffer(DProcess* aProc, TUint8* aBuffer, TUint8* aBufferEnd, TUint32& aProcSize);
/** Static Info Retrieval routines */
static TInt GetStaticInfo(const TListItem* aItem, bool aCheckConsistent);
static void GetObjectFullName(const DObject* aObj, TFullName& aName);
/** Utility functions */
static TInt CopyAndExpandDes(const TDesC& aSrc, TDes& aDest);
};
};
#endif // D_STOP_MODE_API_H
// End of file sm_debug_api.h