|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #ifndef PROFILER_GFC_SAMPLER_H |
|
20 #define PROFILER_GFC_SAMPLER_H |
|
21 |
|
22 |
|
23 #include "GeneralsConfig.h" |
|
24 |
|
25 #include <kern_priv.h> |
|
26 |
|
27 #include <piprofiler/ProfilerGenericClassesKrn.h> |
|
28 #include <piprofiler/ProfilerTraces.h> |
|
29 #include "GppSamplerImpl.h" |
|
30 |
|
31 extern void UsrModLr(TUint32*); |
|
32 |
|
33 |
|
34 /* |
|
35 * |
|
36 * GFC sampler definition |
|
37 * |
|
38 */ |
|
39 |
|
40 template <int BufferSize> |
|
41 class DProfilerGfcSampler : public DProfilerGenericSampler<BufferSize> |
|
42 { |
|
43 public: |
|
44 DProfilerGfcSampler(struct TProfilerGppSamplerData* ); |
|
45 ~DProfilerGfcSampler(); |
|
46 |
|
47 void Sample(); |
|
48 TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset); |
|
49 private: |
|
50 struct TProfilerGppSamplerData* gppSamplerData; |
|
51 TUint32 gfcSample[3]; |
|
52 |
|
53 TUint8 encodedSample[15]; |
|
54 TUint32 repeat; |
|
55 }; |
|
56 |
|
57 /* |
|
58 * |
|
59 * GFC sampler implementation |
|
60 * |
|
61 */ |
|
62 |
|
63 template <int BufferSize> |
|
64 DProfilerGfcSampler<BufferSize>::DProfilerGfcSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) : |
|
65 DProfilerGenericSampler<BufferSize>(PROFILER_GFC_SAMPLER_ID) |
|
66 { |
|
67 this->gppSamplerData = gppSamplerDataIn; |
|
68 LOGSTRING2("CProfilerGfcSampler<%d>::CProfilerGfcSampler",BufferSize); |
|
69 } |
|
70 |
|
71 template <int BufferSize> |
|
72 TInt DProfilerGfcSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset) |
|
73 { |
|
74 LOGSTRING2("CProfilerGfcSampler<BufferSize> - entry",BufferSize); |
|
75 |
|
76 this->repeat = 0; |
|
77 for(TInt i(0);i<3;i++) |
|
78 { |
|
79 this->gfcSample[i] = 0; |
|
80 } |
|
81 |
|
82 LOGSTRING2("CProfilerGfcSampler<%d>::Reset - calling superclass reset",BufferSize); |
|
83 DProfilerGenericSampler<BufferSize>::Reset(aStream); |
|
84 LOGSTRING2("CProfilerGfcSampler<%d>::Reset - called superclass reset",BufferSize); |
|
85 |
|
86 // add the first sample, indicating the gfc trace version |
|
87 TUint8 firstSample[33]; |
|
88 TPtr8 firstSampleDesc(&(firstSample[1]),32); |
|
89 firstSampleDesc.Zero(); |
|
90 |
|
91 firstSampleDesc.Append(_L8("Bappea_V")); |
|
92 firstSampleDesc.Append(PROFILER_GFC_SAMPLER_VERSION); |
|
93 firstSampleDesc.Append(_L8("_GFC")); |
|
94 firstSample[0] = firstSampleDesc.Size(); |
|
95 |
|
96 this->iSampleBuffer->AddSample(firstSample,(firstSample[0]+1)); |
|
97 |
|
98 LOGSTRING2("CProfilerGfcSampler<BufferSize> - exit",BufferSize); |
|
99 |
|
100 return KErrNone; |
|
101 } |
|
102 |
|
103 template <int BufferSize> |
|
104 void DProfilerGfcSampler<BufferSize>::Sample() |
|
105 { |
|
106 LOGSTRING2("CProfilerGfcSampler<%d>::Sample",BufferSize); |
|
107 |
|
108 TUint32 usr_mod_link_reg; |
|
109 |
|
110 UsrModLr(&usr_mod_link_reg); |
|
111 |
|
112 TUint32 pc(gppSamplerData->lastPcValue); |
|
113 TUint32 lr(usr_mod_link_reg); |
|
114 TUint32 sa(gppSamplerData->sampleNumber); |
|
115 |
|
116 if(pc == gfcSample[0] && lr == gfcSample[1] && sa == gfcSample[2]+1) |
|
117 { |
|
118 // encode repeat |
|
119 repeat++; |
|
120 gfcSample[2] = sa; |
|
121 LOGSTRING2("CProfilerGfcSampler<%d>::Sample - repeat",BufferSize); |
|
122 return; |
|
123 } |
|
124 else if(repeat > 0) |
|
125 { |
|
126 TUint8 repeatSample[3]; |
|
127 repeatSample[0] = 0xff; |
|
128 repeatSample[1] = (TUint8)(repeat>>8); |
|
129 repeatSample[2] = (TUint8)repeat; |
|
130 this->iSampleBuffer->AddSample(repeatSample,3); |
|
131 |
|
132 LOGSTRING3("CProfilerGfcSampler<%d>::Sample - Encoded repeat %d",BufferSize,repeat); |
|
133 |
|
134 repeat = 0; |
|
135 } |
|
136 |
|
137 TInt ptr(3); |
|
138 |
|
139 // encode program counter value |
|
140 if(pc>=gfcSample[0]) |
|
141 { |
|
142 pc = (pc-gfcSample[0]); |
|
143 encodedSample[0] = 0x80; |
|
144 } |
|
145 else |
|
146 { |
|
147 pc = (gfcSample[0]-pc); |
|
148 encodedSample[0] = 0x00; |
|
149 } |
|
150 |
|
151 if(pc <= (TUint32)0xff) |
|
152 { |
|
153 encodedSample[0] |= 1; |
|
154 encodedSample[ptr] = (TUint8)pc;ptr++; |
|
155 } |
|
156 else if(pc <= (TUint32)0xffff) |
|
157 { |
|
158 encodedSample[0] |= 2; |
|
159 encodedSample[ptr] = (TUint8)pc;ptr++; |
|
160 encodedSample[ptr] = (TUint8)(pc>>8);ptr++; |
|
161 } |
|
162 else if(pc <= (TUint32)0xffffff) |
|
163 { |
|
164 encodedSample[0] |= 3; |
|
165 encodedSample[ptr] = (TUint8)pc;ptr++; |
|
166 encodedSample[ptr] = (TUint8)(pc>>8);ptr++; |
|
167 encodedSample[ptr] = (TUint8)(pc>>16);ptr++; |
|
168 } |
|
169 else |
|
170 { |
|
171 encodedSample[0] |= 4; |
|
172 encodedSample[ptr] = (TUint8)pc;ptr++; |
|
173 encodedSample[ptr] = (TUint8)(pc>>8);ptr++; |
|
174 encodedSample[ptr] = (TUint8)(pc>>16);ptr++; |
|
175 encodedSample[ptr] = (TUint8)(pc>>24);ptr++; |
|
176 } |
|
177 |
|
178 // encode link register value |
|
179 if(lr>=gfcSample[1]) |
|
180 { |
|
181 lr = (lr-gfcSample[1]); |
|
182 encodedSample[1] = 0x80; |
|
183 } |
|
184 else |
|
185 { |
|
186 lr = (gfcSample[1]-lr); |
|
187 encodedSample[1] = 0x00; |
|
188 } |
|
189 |
|
190 if(lr <= (TUint32)0xff) |
|
191 { |
|
192 encodedSample[1] |= 1; |
|
193 encodedSample[ptr] = (TUint8)lr;ptr++; |
|
194 } |
|
195 else if(lr <= (TUint32)0xffff) |
|
196 { |
|
197 encodedSample[1] |= 2; |
|
198 encodedSample[ptr] = (TUint8)lr;ptr++; |
|
199 encodedSample[ptr] = (TUint8)(lr>>8);ptr++; |
|
200 } |
|
201 else if(lr <= (TUint32)0xffffff) |
|
202 { |
|
203 encodedSample[1] |= 3; |
|
204 encodedSample[ptr] = (TUint8)lr;ptr++; |
|
205 encodedSample[ptr] = (TUint8)(lr>>8);ptr++; |
|
206 encodedSample[ptr] = (TUint8)(lr>>16);ptr++; |
|
207 } |
|
208 else |
|
209 { |
|
210 encodedSample[1] |= 4; |
|
211 encodedSample[ptr] = (TUint8)lr;ptr++; |
|
212 encodedSample[ptr] = (TUint8)(lr>>8);ptr++; |
|
213 encodedSample[ptr] = (TUint8)(lr>>16);ptr++; |
|
214 encodedSample[ptr] = (TUint8)(lr>>24);ptr++; |
|
215 } |
|
216 |
|
217 // endcode sample number difference |
|
218 if( (sa - gfcSample[2]) < (TUint8)0xff) |
|
219 { |
|
220 encodedSample[2] = (sa-gfcSample[2]); |
|
221 } |
|
222 else |
|
223 { |
|
224 encodedSample[2] = 0xff; |
|
225 encodedSample[ptr] = (TUint8)sa;ptr++; |
|
226 encodedSample[ptr] = (TUint8)(sa>>8);ptr++; |
|
227 encodedSample[ptr] = (TUint8)(sa>>16);ptr++; |
|
228 encodedSample[ptr] = (TUint8)(sa>>24);ptr++; |
|
229 } |
|
230 |
|
231 // store the values for the next sample |
|
232 gfcSample[0] = gppSamplerData->lastPcValue; |
|
233 gfcSample[1] = usr_mod_link_reg; |
|
234 gfcSample[2] = gppSamplerData->sampleNumber; |
|
235 |
|
236 this->iSampleBuffer->AddSample(encodedSample,ptr); |
|
237 |
|
238 LOGSTRING3("CProfilerGfcSampler<%d>::Sample Size %d",BufferSize,ptr); |
|
239 |
|
240 return; |
|
241 |
|
242 } |
|
243 |
|
244 template <int BufferSize> |
|
245 DProfilerGfcSampler<BufferSize>::~DProfilerGfcSampler() |
|
246 { |
|
247 LOGSTRING2("CProfilerGfcSampler<%d>::~CProfilerGfcSampler",BufferSize); |
|
248 } |
|
249 #endif |