First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\kernel\arm\cscmdatasave.cpp
19 #define __INCLUDE_REG_OFFSETS__ // for SP_R13U in nk_plat.h
24 #include <scmdatatypes.h>
25 #include <scmdatasave.h>
29 * Reads the CPU registers at the time of the crash
30 * @param aRegs struct to store the resulting CPU registers
32 void SCMDataSave::ReadCPURegisters(SFullArmRegSet& aRegs)
34 aRegs =*(SFullArmRegSet*)iMonitor->iRegs;
38 * Reads the user registers for a given thread - may not be the current thread
39 * @param aThread thread whose registers we want to read
40 * @param aRegs registers will be written here if available
41 * @return KErrArgument if aThread is the current thread or any of the system wide error codes
43 TInt SCMDataSave::ReadUserRegisters(DThread* aThread, TArmRegSet& aRegs, TUint32& aAvailableRegs)
46 aThread->TraceAppendFullName(filename, EFalse);
48 //we retrieve the registers differently for the current thread
49 if(aThread == &Kern::CurrentThread())
54 TUint32* stackPointer = (TUint32*)aThread->iNThread.iSavedSP; //Still need to check pointer somehow
55 TUint32* stackTop = (TUint32*)((TUint32)aThread->iNThread.iStackBase +(TUint32)aThread->iNThread.iStackSize);
56 TArmReg* out = (TArmReg*)(&aRegs);
58 //Get a pointer to this threads context table
59 NThread::TUserContextType type = aThread->iNThread.UserContextType();
60 const TArmContextElement* table = aThread->iNThread.UserContextTables()[type];
63 for(TInt i = 0; i<KArmRegisterCount; ++i)
65 TInt value = table[i].iValue;
66 TInt type = table[i].iType;
68 if(type == TArmContextElement::EOffsetFromSp)
70 value = stackPointer[value];
71 aAvailableRegs |= (1<<i);
73 else if(type == TArmContextElement::EOffsetFromStackTop)
75 value = stackTop[-value];
76 aAvailableRegs |= (1<<i);
78 else if(type == TArmContextElement::ESpPlusOffset)
80 value = (TInt)(stackPointer + value);
81 aAvailableRegs |= (1<<i);
91 * Reads the system registers for a given thread
92 * Can not be used on the current thread
95 * @param aAvailableRegs
96 * @return KErrArgument if aThread is the current thread or any of the system wide error codes
98 TInt SCMDataSave::ReadSystemRegisters(DThread* aThread, TArmRegSet& aRegs, TUint32& aAvailableRegs)
100 if(aThread == &Kern::CurrentThread())
106 aThread->TraceAppendFullName(filename, EFalse);
108 TUint32* stackPointer = (TUint32*)aThread->iNThread.iSavedSP;
109 TUint32* stackTop = (TUint32*)((TUint32)aThread->iNThread.iStackBase +(TUint32)aThread->iNThread.iStackSize);
110 TArmReg* out = (TArmReg*)(&aRegs);
112 //Get a pointer to this threads context table
113 const TArmContextElement* table = aThread->iNThread.UserContextTables()[NThread::EContextKernel];
116 for(TInt i = 0; i<KArmRegisterCount; ++i)
118 TInt value = table[i].iValue;
119 TInt type = table[i].iType;
121 if(type == TArmContextElement::EOffsetFromSp)
123 //ensure we are still on the stack
124 if(stackPointer + value >= stackTop)
127 value = stackPointer[value];
128 aAvailableRegs |= (1<<i);
130 else if(type == TArmContextElement::EOffsetFromStackTop)
132 //ensure we are still on the stack
133 if(stackTop - value < (TUint32*)aThread->iNThread.iStackBase)
136 value = stackTop[-value];
137 aAvailableRegs |= (1<<i);
139 else if(type == TArmContextElement::ESpPlusOffset)
141 value = (TInt)(stackPointer + value);
142 aAvailableRegs |= (1<<i);