Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / cpus / vonk / ss / api / sam / src / SS_SamTracer.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: SS_SamTracer.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21
22#include <strings.h>
23
24#include "SS_SamTracer.h"
25
26#include "SS_VirtualStrand.h"
27#include "SS_Tlb.h"
28#include "SS_Asi.h"
29
30
31
32SS_SamTracer::SS_SamTracer(SS_VirtualStrand *strand)
33 :
34 SS_Tracer()
35{
36 hook_exe_instr = ss_sam_exe_instr;
37 hook_reg_value = ss_sam_reg_value;
38 hook_trap = ss_sam_trap;
39 hook_end_instr = ss_sam_end_instr;
40 hook_mem_access = ss_sam_mem_acc;
41 hook_asi_access = ss_sam_asi_acc;
42 hook_tlb_update = ss_sam_tlb_update;
43 hook_hwop = ss_sam_hwop;
44
45 irec.nregs = 0;
46 irec.ld_num = 0;
47 irec.st_num = 0;
48 irec.itype = Sam::VCPU_UNKNOWN_ITYPE;
49 irec.exception = 0;
50
51 trec.is_async = 0;
52 atrec.is_async = 0;
53
54 vcpu = strand;
55}
56
57
58
59
60// Conditional Branch decoding tables
61
62// special case
63const int BN = 2; // special
64const int BA = 3; // case
65
66static uint8_t bpr_taken[8][4] =
67{
68 // 0 < 0 > 0
69 BN, BN, BN, BN,
70 BN, 1, 0, 0,
71 BN, 1, 1, 0,
72 BN, 0, 1, 0,
73
74 BN, BN, BN, BN,
75 BN, 0, 1, 1,
76 BN, 0, 0, 1,
77 BN, 1, 0, 1,
78};
79
80static uint8_t fbr_taken[16][4] =
81{
82
83// E L G U
84
85 BN, BN, BN, BN,
86 0, 1, 1, 1,
87 0, 1, 1, 0,
88 0, 1, 0, 1,
89 0, 1, 0, 0,
90 0, 0, 1, 1,
91 0, 0, 1, 0,
92 0, 0, 0, 1,
93
94 BA, BA, BA, BA,
95 1, 0, 0, 0,
96 1, 0, 0, 1,
97 1, 0, 1, 0,
98 1, 0, 1, 1,
99 1, 1, 0, 0,
100 1, 1, 0, 1,
101 1, 1, 1, 0,
102};
103
104static uint8_t br_taken [16][16] =
105{
106 BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN,
107
108 0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1,
109 0,0,1,1, 1,1,1,1, 1,1,0,0, 1,1,1,1,
110 0,0,1,1, 0,0,1,1, 1,1,0,0, 1,1,0,0,
111 0,1,0,1, 1,1,1,1, 0,1,0,1, 1,1,1,1,
112 0,1,0,1, 0,1,0,1, 0,1,0,1, 0,1,0,1,
113 0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1,
114 0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1,
115
116 BA, BA, BA, BA, BA, BA, BA, BA, BA, BA, BA, BA, BA, BA, BA, BA,
117
118 1,1,1,1, 0,0,0,0, 1,1,1,1, 0,0,0,0,
119 1,1,0,0, 0,0,0,0, 0,0,1,1, 0,0,0,0,
120 1,1,0,0, 1,1,0,0, 0,0,1,1, 0,0,1,1,
121 1,0,1,0, 0,0,0,0, 1,0,1,0, 0,0,0,0,
122 1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0,
123 1,1,1,1, 1,1,1,1, 0,0,0,0, 0,0,0,0,
124 1,1,0,0, 1,1,0,0, 1,1,0,0, 1,1,0,0,
125};
126
127void SS_SamTracer::ss_sam_exe_instr( SS_Tracer* trc, SS_Vaddr pc, SS_Tte* tte, SS_Instr* i )
128{
129 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
130 SS_Strand* strand = sam_trc->vcpu->strand;
131
132 uint32_t iw = i->opc();
133
134 // instruction record
135 if(sam_trc->vcpu->config.trace_on &&
136 sam_trc->vcpu->sys_intf.vtrace)
137 {
138 sam_trc->irec.cpuid = strand->strand_id();
139 sam_trc->irec.pid = tte->pid();
140 sam_trc->irec.icontext = tte->context();
141
142 if (tte->is_virt())
143 sam_trc->irec.pc_type = Sam::VCPU_VADDR;
144 else if (tte->is_real())
145 sam_trc->irec.pc_type = Sam::VCPU_RADDR;
146 else
147 sam_trc->irec.pc_type = Sam::VCPU_PADDR;
148
149 sam_trc->irec.pc_va = pc;
150 sam_trc->irec.pc_pa = tte->trans(pc);
151 int64_t npc = sam_trc->irec.npc_va = strand->npc();
152 sam_trc->irec.opcode = iw;
153
154 sam_trc->irec.pstate = strand->pstate();
155 sam_trc->irec.hpstate = strand->hpstate();
156
157 sam_trc->irec.immu_asi = strand->inst_dft_asi();
158 sam_trc->irec.dmmu_asi = i->is_lsu() ? i->asi : 0;
159
160 sam_trc->irec.ifetch_trap = !tte->valid();
161 sam_trc->irec.dmmu_trap = 0; // should be detected from trap type
162
163
164 // Check for cti instructions
165 // simple check for pc diff does not cover all cases
166 bool taken = false;
167 bool annul = false;
168 bool cti = false;
169
170 // check if it is CALL, BPcc, Bicc, BPr, FBPfcc or FBfcc instruction
171 SS_Opcode o;
172 o = iw;
173 uint32_t op = o.get_op();
174 uint32_t op2 = o.get_op2();
175
176 bool branch_on_cond = (op==0) && ((op2==1)||(op2==2)||(op2==5)||(op2==6));
177 bool branch_on_reg = (op==0) && (op2==3);
178
179 if (op==1) // CALL instruction
180 {
181 taken = true;
182 cti = true;
183 }
184 else if (branch_on_cond)
185 {
186 cti = true;
187
188
189 if(o.get_cond() == 8) // branch allways
190 {
191 taken = true;
192 sam_trc->irec.npc_va = pc;
193 }
194 else // check if conditional branch was taken
195 {
196 if (op2==1) // BPcc
197 {
198 uint8_t cc_iw = o.get_cc();
199
200 if (cc_iw == 0) // icc
201 taken = br_taken[o.get_cond()][strand->ccr.icc()]==1;
202 else if (cc_iw = 2) // xcc
203 taken = br_taken[o.get_cond()][strand->ccr.xcc()]==1;
204
205 }
206 else if (op2==2) //Bicc
207 {
208 taken = br_taken[o.get_cond()][strand->ccr.icc()]==1;
209 }
210 else if (op2==5) // FBPfcc
211 {
212 uint8_t fcc = 0;
213 strand->get_fsr();
214 switch (o.get_cc())
215 {
216 case 0: // fcc0
217 fcc = strand->fsr.fcc0();
218 break;
219 case 1: // fcc1
220 fcc = strand->fsr.fcc1();
221 break;
222 case 2: // fcc2
223 fcc = strand->fsr.fcc2();
224 break;
225 case 3: // fcc3
226 fcc = strand->fsr.fcc3();
227 break;
228 }
229 taken = fbr_taken[o.get_cond()][fcc]==1;
230 }
231 else if (op2==6) // FBfcc
232 {
233 strand->get_fsr();
234 uint8_t fcc0 = strand->fsr.fcc0();
235 taken = fbr_taken[o.get_cond()][fcc0]==1;
236 }
237
238 }
239 // delay slot instruction is annuled when annul bit is set and
240 // it is unconditional branch or conditional branch is not taken
241 annul = ((iw>>29)&1) && ( (o.get_cond() == 8 || o.get_cond() == 0) || !taken );
242
243 }
244 else if (branch_on_reg) // check if branch on reg value was taken
245 {
246 cti = true;
247
248 // get current reg[rs1] value
249 int64_t r1 = sam_trc->vcpu->strand->irf[o.get_rs1()];
250 uint8_t rv = 0;
251
252 if (r1 == 0) rv = 1;
253 else if (r1 < 0) rv = 2;
254 else if (r1 > 0) rv = 3;
255 taken = bpr_taken[o.get_cond()][rv]==1;
256
257 // delay slot instruction is annuled when annul bit is set and
258 // branch is not taken
259 annul = ((iw>>29)&1) && !taken ;
260 }
261
262
263 if ( !cti && (op == 2))
264 {
265 // check if it is DONE, RETRY, JPRIV, JMPL, RETURN instruction
266 uint32_t op3 = (iw>>19) & 0x3f;
267 if ((op3 == 0x3e) ||(op3 == 0x38)||(op3 == 0x39))
268 {
269 cti = true;
270 taken = true;
271 }
272 else if (op3 == 0x3a) // Tcc
273 {
274 cti = true;
275 }
276 }
277
278
279
280
281 if (cti)
282 {
283 sam_trc->irec.itype |= Sam::VCPU_BRANCH_ITYPE;
284 }
285
286 // sanity check if "taken" was calculated correctly
287 if ((npc != (strand->pc() + 4)) && !taken)
288 {
289 taken = true;
290 }
291 sam_trc->irec.annul = annul;
292 sam_trc->irec.taken = taken;
293
294
295
296 }
297 return;
298}
299
300void SS_SamTracer::ss_sam_hwop( SS_Tracer* trc, MemAccess type, SS_Paddr addr, uint_t size, uint64_t *value )
301{
302 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
303
304 if(sam_trc->vcpu->config.trace_on &&
305 sam_trc->vcpu->sys_intf.vtrace)
306 {
307 Sam::VCPU_HwOp hwop;
308
309 hwop.cpuid = sam_trc->vcpu->id();
310
311 hwop.op_type = !is_fetch(type);
312 hwop.addr = addr;
313 hwop.data[0] = value[0];
314 hwop.data[1] = value[1];
315
316 // call tracer
317 sam_trc->vcpu->sys_intf.vtrace->hwop(&hwop);
318 }
319}
320
321void SS_SamTracer::ss_sam_tlb_update( SS_Tracer* trc, bool insert, SS_Tlb* tlb, uint_t index, SS_Tte* tte )
322{
323 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
324
325 if( !sam_trc->vcpu->config.trace_on ||
326 !sam_trc->vcpu->sys_intf.vtrace)
327 return;
328
329
330
331 Sam::VCPU_TLB tlb_rec;
332
333 tlb_rec.format = 1; // sun4u
334 tlb_rec.cpuid = sam_trc->vcpu->id();
335 tlb_rec.demap = !insert;
336 tlb_rec.tlb_type = tlb->is_data_tlb();
337 tlb_rec.tlb_index = index;
338 tlb_rec.tlb_no = tlb->tlb_id();
339
340 tlb_rec.tte_tag = tte->tag();
341
342 // data: v:63 nfo:62 taddr: 55-13 ie:12 e:11 cp:10 cv:9 p:8 ep:7 w:6 sz:3-0
343 tlb_rec.tte_data = tte->taddr() & (0x7ffffffffull << 13);
344 if (tte->valid_bit()) tlb_rec.tte_data |= (1ull<<63);
345 if (tte->nfo()) tlb_rec.tte_data |= (1ull << 62);
346 if (tte->ie()) tlb_rec.tte_data |= (1ull << 12);
347 if (tte->e()) tlb_rec.tte_data |= (1ull << 11);
348 if (tte->cp()) tlb_rec.tte_data |= (1ull << 10);
349 if (tte->cv()) tlb_rec.tte_data |= (1ull << 9);
350 if (tte->p()) tlb_rec.tte_data |= (1ull << 8);
351 if (tte->x()) tlb_rec.tte_data |= (1ull << 7);
352 if (tte->w()) tlb_rec.tte_data |= (1ull << 6);
353 tlb_rec.tte_data |= tte->page_size();
354
355 tlb_rec.is_real = tte->real_bit();
356 tlb_rec.partid = tte->pid();
357
358 tlb_rec.tte_page_size = tte->page_size();
359 tlb_rec.tte_context = tte->context();
360
361 // call tracer
362 sam_trc->vcpu->sys_intf.vtrace->tlb(&tlb_rec);
363
364}
365
366void SS_SamTracer::ss_sam_reg_value( SS_Tracer* trc, SS_Registers::Index index, uint64_t value )
367{
368 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
369
370 // collect reg values
371 if(sam_trc->vcpu->config.trace_on &&
372 sam_trc->vcpu->sys_intf.vtrace)
373 {
374 int rid = sam_trc->irec.nregs;
375
376 if (rid >= (Sam::VCPU_MAX_DEST_REG_NUM-1))
377 {
378 //fprintf (stderr, "Tracer: too many dest regs\n");
379 return;
380 }
381
382 if (SS_Registers::is_irf(index))
383 {
384 sam_trc->irec.itype |= Sam::VCPU_ALU_ITYPE;
385 sam_trc->irec.dreg[rid].r.id = index - SS_Registers::IRF_OFS;
386 sam_trc->irec.dreg[rid].r.type = Sam::VCPU_INT_RTYPE;
387 sam_trc->irec.dval[rid] = value;
388 }
389 else if (SS_Registers::is_drf(index))
390 {
391 sam_trc->irec.itype |= Sam::VCPU_FP_ITYPE;
392 sam_trc->irec.dreg[rid].r.id = (index - SS_Registers::DRF_OFS)*2; // @@ note *2 !!!
393 sam_trc->irec.dreg[rid].r.type = Sam::VCPU_FP_DOUBLE_RTYPE;
394 sam_trc->irec.dval[rid] = value;
395 }
396 else if (SS_Registers::is_asr(index))
397 {
398 if ((index == SS_Registers::ASR_PC) &&
399 value == (sam_trc->irec.pc_va + 4))
400 {
401 // skip pc update
402 return;
403 }
404 sam_trc->irec.dreg[rid].r.id = index - SS_Registers::ASR_OFS;
405 sam_trc->irec.dreg[rid].r.type = Sam::VCPU_ASR_RTYPE;
406 sam_trc->irec.dval[rid] = value;
407 }
408 else if (SS_Registers::is_pr(index))
409 {
410 sam_trc->irec.dreg[rid].r.id = index - SS_Registers::PR_OFS;
411 sam_trc->irec.dreg[rid].r.type = Sam::VCPU_PR_RTYPE;
412 sam_trc->irec.dval[rid] = value;
413 }
414 else if (SS_Registers::is_hpr(index))
415 {
416 sam_trc->irec.dreg[rid].r.id = index - SS_Registers::HPR_OFS;
417 sam_trc->irec.dreg[rid].r.type = Sam::VCPU_HPR_RTYPE;
418 sam_trc->irec.dval[rid] = value;
419 }
420 else
421 {
422 return; // unknown reg, ignore
423 }
424
425 sam_trc->irec.nregs = rid + 1;
426 }
427
428}
429
430void SS_SamTracer::ss_sam_mem_acc ( SS_Tracer* trc, MemAccess type, SS_Vaddr va,
431 SS_Tte* tte, uint_t size, uint64_t* val )
432{
433 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
434
435 if( !sam_trc->vcpu->config.trace_on ||
436 !sam_trc->vcpu->sys_intf.vtrace)
437 return;
438
439 sam_trc->irec.dcontext = tte ? tte->context() : 0;
440
441 if (tte == 0)
442 sam_trc->irec.ea_type = Sam::VCPU_VADDR;
443 else if (tte->is_virt())
444 sam_trc->irec.ea_type = Sam::VCPU_VADDR;
445 else if (tte->is_real())
446 sam_trc->irec.ea_type = Sam::VCPU_RADDR;
447 else
448 sam_trc->irec.ea_type = Sam::VCPU_PADDR;
449
450 switch(type)
451 {
452 case PREFETCH:
453 sam_trc->irec.itype |= Sam::VCPU_LOAD_ITYPE;
454 sam_trc->irec.ea_va = va;
455 sam_trc->irec.ea_pa = tte ? tte->trans(va) : 0; // tte == 0 is TLB mis (no trap)
456 sam_trc->irec.ld_bitmask = 0; // zero size load == prefetch
457 break;
458
459 case FLUSH:
460 sam_trc->irec.itype |= Sam::VCPU_STORE_ITYPE;
461 sam_trc->irec.ea_va = va;
462 sam_trc->irec.ea_pa = tte ? tte->trans(va) : 0; // tte == 0 is TLB mis (no trap)
463 sam_trc->irec.st_bitmask = 0; // zero size store == flush
464 break;
465
466 case LD_DATA :
467 case LD_SWAP :
468 case LD_CAS :
469 case LD_LDST :
470
471 sam_trc->irec.itype |= Sam::VCPU_LOAD_ITYPE;
472 sam_trc->irec.ea_va = va;
473 sam_trc->irec.ea_pa = tte->trans(va);
474 sam_trc->irec.ld_bitmask = (size<8)?(uint64_t(1)<<(size*8))-uint64_t(1):~uint64_t(0);
475
476 switch(size)
477 {
478 case 1:
479 case 2:
480 case 4:
481 case 8:
482 if (sam_trc->irec.ld_num < Sam::VCPU_MAX_MEM_ACCESS_NUM)
483 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = *val;
484 break;
485 case 16:
486
487 if (sam_trc->irec.ld_num < Sam::VCPU_MAX_MEM_ACCESS_NUM-1)
488 {
489 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[0];
490 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[1];
491 }
492 break;
493 case 64:
494
495 if (sam_trc->irec.ld_num < Sam::VCPU_MAX_MEM_ACCESS_NUM-7)
496 {
497 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[0];
498 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[1];
499 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[2];
500 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[3];
501 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[4];
502 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[5];
503 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[6];
504 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = val[7];
505 }
506 break;
507 default:
508 break;
509
510 }
511 break;
512
513 case ST_DATA :
514 case ST_SWAP :
515 case ST_CAS :
516 case ST_LDST :
517
518 sam_trc->irec.itype |= Sam::VCPU_STORE_ITYPE;
519 sam_trc->irec.ea_va = va;
520 sam_trc->irec.ea_pa = tte->trans(va);
521 sam_trc->irec.st_bitmask = (size<8)?(uint64_t(1)<<(size*8))-uint64_t(1):~uint64_t(0);
522
523 switch(size)
524 {
525 case 1:
526 case 2:
527 case 4:
528 case 8:
529
530 if (sam_trc->irec.st_num < Sam::VCPU_MAX_MEM_ACCESS_NUM)
531 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = *val;
532 break;
533 case 64:
534
535 if (sam_trc->irec.st_num < Sam::VCPU_MAX_MEM_ACCESS_NUM-7)
536 {
537 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[0];
538 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[1];
539 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[2];
540 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[3];
541 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[4];
542 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[5];
543 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[6];
544 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[7];
545 }
546 break;
547 default:
548 break;
549 }
550 break;
551
552 case ST_PART :
553
554 sam_trc->irec.itype |= Sam::VCPU_STORE_ITYPE;
555 sam_trc->irec.ea_va = va;
556 sam_trc->irec.ea_pa = tte->trans(va);
557 sam_trc->irec.st_bitmask = val[1];
558 if (sam_trc->irec.st_num < Sam::VCPU_MAX_MEM_ACCESS_NUM)
559 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = val[0];
560 break;
561
562 default:
563 break;
564
565 }
566}
567
568void SS_SamTracer::ss_sam_asi_acc ( SS_Tracer* trc, MemAccess type, uint8_t asi, SS_Vaddr va, uint64_t* val )
569{
570 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
571
572 if( !sam_trc->vcpu->config.trace_on ||
573 !sam_trc->vcpu->sys_intf.vtrace)
574 return;
575
576 sam_trc->irec.dmmu_asi = asi;
577 sam_trc->irec.ea_va = va;
578 sam_trc->irec.ea_pa = va;
579 sam_trc->irec.ld_bitmask = ~uint64_t(0);
580 sam_trc->irec.ea_type = Sam::VCPU_VADDR;
581
582 switch(type)
583 {
584 case LD_DATA:
585 sam_trc->irec.itype |= Sam::VCPU_ASI_LOAD_ITYPE;
586 if (sam_trc->irec.ld_num < Sam::VCPU_MAX_MEM_ACCESS_NUM)
587 sam_trc->irec.ld_mem_value[sam_trc->irec.ld_num++] = *val;
588 break;
589
590 case ST_DATA :
591 sam_trc->irec.itype |= Sam::VCPU_ASI_STORE_ITYPE;
592 if (sam_trc->irec.st_num < Sam::VCPU_MAX_MEM_ACCESS_NUM)
593 sam_trc->irec.st_mem_value[sam_trc->irec.st_num++] = *val;
594 break;
595
596 default:
597 break;
598
599 }
600
601}
602
603void SS_SamTracer::ss_sam_trap( SS_Tracer* trc, SS_Trap::Type tt, TrapMode mode, SS_Vaddr ea )
604{
605 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
606 SS_Strand* strand = sam_trc->vcpu->strand;
607
608 // trap record
609 if(sam_trc->vcpu->config.trace_on &&
610 sam_trc->vcpu->sys_intf.vtrace)
611 {
612
613 Sam::VCPU_Trap *trap = &sam_trc->trec;
614 if (SS_Trap::table[tt].disrupting)
615 {
616 sam_trc->atrec.is_async = 1;
617 trap = &sam_trc->atrec;
618 }
619 else
620 {
621 sam_trc->irec.exception = 1;
622 }
623
624
625 // collect trap record
626 trap->cpuid = sam_trc->vcpu->id();
627
628 trap->nregs = 0;
629
630 uint64_t value=0;
631 trap->pc_va = strand->pc();
632 trap->npc_va = strand->npc();
633 trap->tno = tt;
634
635 if (mode == DATA_TRAP) {
636 sam_trc->irec.ea_va = ea;
637 sam_trc->irec.ea_pa = 0x0;
638 }
639 }
640 return;
641}
642
643void SS_SamTracer::ss_sam_end_instr( SS_Tracer* trc )
644{
645 SS_SamTracer* sam_trc = (SS_SamTracer*)trc;
646
647 if(sam_trc->vcpu->config.trace_on &&
648 sam_trc->vcpu->sys_intf.vtrace)
649 {
650 // call tracer - async trap record
651 if(sam_trc->atrec.is_async)
652 sam_trc->vcpu->sys_intf.vtrace->trap(&(sam_trc->atrec));
653
654 // instruction record
655 sam_trc->vcpu->sys_intf.vtrace->instr(&(sam_trc->irec));
656
657 // trap record
658 if(sam_trc->irec.exception)
659 sam_trc->vcpu->sys_intf.vtrace->trap(&(sam_trc->trec));
660
661 // reset the counters
662 bzero(&sam_trc->irec, sizeof(Sam::VCPU_Instruction));
663 bzero(&sam_trc->trec, sizeof(Sam::VCPU_Trap));
664 bzero(&sam_trc->atrec, sizeof(Sam::VCPU_Trap));
665 }
666}
667