1 /* TRACE.C (c) Copyright Jan Jaeger, 2000-2009 */
2 /* Implicit tracing functions */
3
4 /* Interpretive Execution - (c) Copyright Jan Jaeger, 1999-2009 */
5 /* z/Architecture support - (c) Copyright Jan Jaeger, 1999-2009 */
6
7 /*-------------------------------------------------------------------*/
8 /* This module contains procedures for creating entries in the */
9 /* system trace table as described in the manuals: */
10 /* SA22-7201 ESA/390 Principles of Operation */
11 /* SA22-7832 z/Architecture Principles of Operation */
12 /*-------------------------------------------------------------------*/
13
14 /*-------------------------------------------------------------------*/
15 /* Additional credits: */
16 /* ASN-and-LX-reuse facility - Roger Bowler July 2004*/
17 /*-------------------------------------------------------------------*/
18
19 #include "hstdinc.h"
20
21 #if !defined(_HENGINE_DLL_)
22 #define _HENGINE_DLL_
23 #endif
24
25 #if !defined(_TRACE_C_)
26 #define _TRACE_C_
27 #endif
28
29 #include "hercules.h"
30
31 #include "opcode.h"
32
33 #include "inline.h"
34
35 #if defined(FEATURE_TRACING)
36
37 #if !defined(_TRACE_H)
38 #define _TRACE_H
39
40 /*-------------------------------------------------------------------*/
41 /* Format definitions for trace table entries */
42 /*-------------------------------------------------------------------*/
43 typedef struct _TRACE_F1_BR {
44 FWORD newia24; /* Bits 0-7 are zeros */
45 } TRACE_F1_BR;
46
47 typedef struct _TRACE_F2_BR {
48 FWORD newia31; /* Bit 0 is one */
49 } TRACE_F2_BR;
50
51 typedef struct _TRACE_F3_BR {
52 BYTE format; /* B'01010010' */
53 #define TRACE_F3_BR_FMT 0x52
54 BYTE fmt2; /* B'1100' B'0000' */
55 #define TRACE_F3_BR_FM2 0xC0
56 HWORD resv;
57 DBLWRD newia64;
58 } TRACE_F3_BR;
59
60 typedef struct _TRACE_F1_BSG {
61 BYTE format; /* B'01000001' */
62 #define TRACE_F1_BSG_FMT 0x41
63 BYTE alet[3];
64 FWORD newia;
65 } TRACE_F1_BSG;
66
67 typedef struct _TRACE_F2_BSG {
68 BYTE format; /* B'01000010' */
69 #define TRACE_F2_BSG_FMT 0x42
70 BYTE alet[3];
71 DBLWRD newia;
72 } TRACE_F2_BSG;
73
74 typedef struct _TRACE_F1_MS {
75 BYTE format;
76 #define TRACE_F1_MS_FMT 0x51
77 BYTE fmt2;
78 #define TRACE_F1_MS_FM2 0x30
79 HWORD resv;
80 FWORD newia;
81 } TRACE_F1_MS;
82
83 typedef struct _TRACE_F2_MS {
84 BYTE format;
85 #define TRACE_F2_MS_FMT 0x51
86 BYTE fmt2;
87 #define TRACE_F2_MS_FM2 0x20
88 HWORD resv;
89 FWORD newia;
90 } TRACE_F2_MS;
91
92 typedef struct _TRACE_F3_MS {
93 BYTE format;
94 #define TRACE_F3_MS_FMT 0x52
95 BYTE fmt2;
96 #define TRACE_F3_MS_FM2 0x60
97 HWORD resv;
98 DBLWRD newia;
99 } TRACE_F3_MS;
100
101
102 typedef struct _TRACE_F1_MSB {
103 BYTE format;
104 #define TRACE_F1_MSB_FMT 0x51
105 BYTE fmt2;
106 #define TRACE_F1_MSB_FM2 0xA0
107 HWORD resv;
108 FWORD newia;
109 } TRACE_F1_MSB;
110
111 typedef struct _TRACE_F2_MSB {
112 BYTE format;
113 #define TRACE_F2_MSB_FMT 0x51
114 BYTE fmt2;
115 #define TRACE_F2_MSB_FM2 0xB0
116 HWORD resv;
117 FWORD newia;
118 } TRACE_F2_MSB;
119
120 typedef struct _TRACE_F3_MSB {
121 BYTE format;
122 #define TRACE_F3_MSB_FMT 0x52
123 BYTE fmt2;
124 #define TRACE_F3_MSB_FM2 0xF0
125 HWORD resv;
126 DBLWRD newia;
127 } TRACE_F3_MSB;
128
129 typedef struct _TRACE_F1_PT {
130 BYTE format;
131 #define TRACE_F1_PT_FMT 0x31
132 BYTE pswkey;
133 #define TRACE_F1_PT_FM2 0x00
134 HWORD newpasn;
135 FWORD r2;
136 } TRACE_F1_PT;
137
138 typedef struct _TRACE_F2_PT {
139 BYTE format;
140 #define TRACE_F2_PT_FMT 0x31
141 BYTE pswkey;
142 #define TRACE_F2_PT_FM2 0x08
143 HWORD newpasn;
144 FWORD r2;
145 } TRACE_F2_PT;
146
147 typedef struct _TRACE_F3_PT {
148 BYTE format;
149 #define TRACE_F3_PT_FMT 0x32
150 BYTE pswkey;
151 #define TRACE_F3_PT_FM2 0x0C
152 HWORD newpasn;
153 DBLWRD r2;
154 } TRACE_F3_PT;
155
156 typedef struct _TRACE_F1_SSAR {
157 BYTE format;
158 #define TRACE_F1_SSAR_FMT 0x10
159 BYTE extfmt;
160 HWORD newsasn;
161 } TRACE_F1_SSAR;
162
163 typedef struct _TRACE_F1_TRACE {
164 BYTE format;
165 BYTE zero;
166 HWORD tod1631;
167 FWORD tod3263;
168 FWORD operand;
169 FWORD regs[16];
170 } TRACE_F1_TRACE;
171
172 typedef struct _TRACE_F2_TRACE {
173 BYTE format;
174 BYTE extfmt;
175 HWORD tod1631;
176 DBLWRD tod3279;
177 FWORD operand;
178 DBLWRD regs[16];
179 } TRACE_F2_TRACE;
180
181 typedef struct _TRACE_F1_PR {
182 BYTE format;
183 #define TRACE_F1_PR_FMT 0x32
184 BYTE pswkey;
185 #define TRACE_F1_PR_FM2 0x00
186 HWORD newpasn;
187 FWORD retna;
188 FWORD newia;
189 } TRACE_F1_PR;
190
191 typedef struct _TRACE_F2_PR {
192 BYTE format;
193 #define TRACE_F2_PR_FMT 0x32
194 BYTE pswkey;
195 #define TRACE_F2_PR_FM2 0x02
196 HWORD newpasn;
197 FWORD retna;
198 FWORD newia;
199 } TRACE_F2_PR;
200
201 typedef struct _TRACE_F3_PR {
202 BYTE format;
203 #define TRACE_F3_PR_FMT 0x33
204 BYTE pswkey;
205 #define TRACE_F3_PR_FM2 0x03
206 HWORD newpasn;
207 FWORD retna;
208 DBLWRD newia;
209 } TRACE_F3_PR;
210
211 typedef struct _TRACE_F4_PR {
212 BYTE format;
213 #define TRACE_F4_PR_FMT 0x32
214 BYTE pswkey;
215 #define TRACE_F4_PR_FM2 0x08
216 HWORD newpasn;
217 FWORD retna;
218 FWORD newia;
219 } TRACE_F4_PR;
220
221 typedef struct _TRACE_F5_PR {
222 BYTE format;
223 #define TRACE_F5_PR_FMT 0x32
224 BYTE pswkey;
225 #define TRACE_F5_PR_FM2 0x0A
226 HWORD newpasn;
227 FWORD retna;
228 FWORD newia;
229 } TRACE_F5_PR;
230
231 typedef struct _TRACE_F6_PR {
232 BYTE format;
233 #define TRACE_F6_PR_FMT 0x33
234 BYTE pswkey;
235 #define TRACE_F6_PR_FM2 0x0B
236 HWORD newpasn;
237 FWORD retna;
238 DBLWRD newia;
239 } TRACE_F6_PR;
240
241 typedef struct _TRACE_F7_PR {
242 BYTE format;
243 #define TRACE_F7_PR_FMT 0x33
244 BYTE pswkey;
245 #define TRACE_F7_PR_FM2 0x0C
246 HWORD newpasn;
247 DBLWRD retna;
248 FWORD newia;
249 } TRACE_F7_PR;
250
251 typedef struct _TRACE_F8_PR {
252 BYTE format;
253 #define TRACE_F8_PR_FMT 0x33
254 BYTE pswkey;
255 #define TRACE_F8_PR_FM2 0x0E
256 HWORD newpasn;
257 DBLWRD retna;
258 FWORD newia;
259 } TRACE_F8_PR;
260
261 typedef struct _TRACE_F9_PR {
262 BYTE format;
263 #define TRACE_F9_PR_FMT 0x34
264 BYTE pswkey;
265 #define TRACE_F9_PR_FM2 0x0F
266 HWORD newpasn;
267 DBLWRD retna;
268 DBLWRD newia;
269 } TRACE_F9_PR;
270
271 typedef struct _TRACE_F1_PC {
272 BYTE format;
273 #define TRACE_F1_PC_FMT 0x21
274 BYTE pswkey_pcnum_hi;
275 HWORD pcnum_lo;
276 FWORD retna;
277 } TRACE_F1_PC;
278
279 typedef struct _TRACE_F2_PC {
280 BYTE format;
281 #define TRACE_F2_PC_FMT 0x22
282 BYTE pswkey_pcnum_hi;
283 HWORD pcnum_lo;
284 DBLWRD retna;
285 } TRACE_F2_PC;
286
287 typedef struct _TRACE_F3_PC {
288 BYTE format;
289 #define TRACE_F3_PC_FMT 0x21
290 BYTE pswkey_pcnum_hi;
291 HWORD pcnum_lo;
292 FWORD retna;
293 } TRACE_F3_PC;
294
295 typedef struct _TRACE_F4_PC {
296 BYTE format;
297 #define TRACE_F4_PC_FMT 0x22
298 BYTE pswkey_pcnum_hi;
299 HWORD pcnum_lo;
300 DBLWRD retna;
301 } TRACE_F4_PC;
302
303 typedef struct _TRACE_F5_PC {
304 BYTE format;
305 #define TRACE_F5_PC_FMT 0x22
306 BYTE pswkey;
307 #define TRACE_F5_PC_FM2 0x08
308 HWORD resv;
309 FWORD retna;
310 FWORD pcnum;
311 } TRACE_F5_PC;
312
313 typedef struct _TRACE_F6_PC {
314 BYTE format;
315 #define TRACE_F6_PC_FMT 0x22
316 BYTE pswkey;
317 #define TRACE_F6_PC_FM2 0x0A
318 HWORD resv;
319 FWORD retna;
320 FWORD pcnum;
321 } TRACE_F6_PC;
322
323 typedef struct _TRACE_F7_PC {
324 BYTE format;
325 #define TRACE_F7_PC_FMT 0x23
326 BYTE pswkey;
327 #define TRACE_F7_PC_FM2 0x0E
328 HWORD resv;
329 DBLWRD retna;
330 FWORD pcnum;
331 } TRACE_F7_PC;
332
333
334 typedef struct _TRACE_F1_TR {
335 BYTE format;
336 #define TRACE_F1_TR_FMT 0x70
337 BYTE fmt2;
338 #define TRACE_F1_TR_FM2 0x00
339 HWORD clk16;
340 FWORD clk32;
341 FWORD operand;
342 FWORD reg[16];
343 } TRACE_F1_TR;
344
345 typedef struct _TRACE_F2_TR {
346 BYTE format;
347 #define TRACE_F2_TR_FMT 0x70
348 BYTE fmt2;
349 #define TRACE_F2_TR_FM2 0x80
350 HWORD clk0;
351 FWORD clk16;
352 FWORD clk48;
353 FWORD operand;
354 DBLWRD reg[16];
355 } TRACE_F2_TR;
356
357 #endif /*!defined(_TRACE_H)*/
358
359 /*-------------------------------------------------------------------*/
360 /* Reserve space for a new trace entry */
361 /* */
362 /* Input: */
363 /* size Number of bytes required for trace entry */
364 /* regs Pointer to the CPU register context */
365 /* Output: */
366 /* abs_guest Guest absolute address of trace entry (if SIE) */
367 /* Return value: */
368 /* Absolute address of new trace entry */
369 /* */
370 /* This function does not return if a program check occurs. */
371 /*-------------------------------------------------------------------*/
ARCH_DEP(get_trace_entry)372 static inline RADR ARCH_DEP(get_trace_entry) (RADR *abs_guest, int size, REGS *regs)
373 {
374 RADR n; /* Addr of trace table entry */
375
376 /* Obtain the trace entry address from control register 12 */
377 n = regs->CR(12) & CR12_TRACEEA;
378
379 /* Apply low-address protection to trace entry address */
380 if (ARCH_DEP(is_low_address_protected) (n, regs))
381 {
382 #ifdef FEATURE_SUPPRESSION_ON_PROTECTION
383 regs->TEA = (n & STORAGE_KEY_PAGEMASK);
384 regs->excarid = 0;
385 #endif /*FEATURE_SUPPRESSION_ON_PROTECTION*/
386 ARCH_DEP(program_interrupt) (regs, PGM_PROTECTION_EXCEPTION);
387 }
388
389 /* Program check if trace entry is outside main storage */
390 if ( n > regs->mainlim )
391 ARCH_DEP(program_interrupt) (regs, PGM_ADDRESSING_EXCEPTION);
392
393 /* Program check if storing would overflow a 4K page boundary */
394 if ( ((n + size) & PAGEFRAME_PAGEMASK) != (n & PAGEFRAME_PAGEMASK) )
395 ARCH_DEP(program_interrupt) (regs, PGM_TRACE_TABLE_EXCEPTION);
396
397 /* Convert trace entry real address to absolute address */
398 n = APPLY_PREFIXING (n, regs->PX);
399
400 #if defined(_FEATURE_SIE)
401 *abs_guest = n;
402
403 SIE_TRANSLATE(&n, ACCTYPE_WRITE, regs);
404
405 #endif /*defined(_FEATURE_SIE)*/
406
407 return n;
408
409 } /* end function ARCH_DEP(get_trace_entry) */
410
411
412 /*-------------------------------------------------------------------*/
413 /* Commit a new trace entry */
414 /* */
415 /* Input: */
416 /* abs_guest Guest absolute address of trace entry (if SIE) */
417 /* raddr Absolute address of trace entry */
418 /* size Number of bytes reserved for trace entry */
419 /* regs Pointer to the CPU register context */
420 /* Return value: */
421 /* Updated value for CR12 after committing the trace entry */
422 /*-------------------------------------------------------------------*/
ARCH_DEP(set_trace_entry)423 static inline CREG ARCH_DEP(set_trace_entry) (RADR abs_guest, RADR raddr, int size, REGS *regs)
424 {
425 #if defined(_FEATURE_SIE)
426 RADR abs_host;
427
428 abs_host = raddr;
429 #endif /*defined(_FEATURE_SIE)*/
430
431 raddr += size;
432
433 #if defined(_FEATURE_SIE)
434 /* Recalculate the Guest absolute address */
435 raddr = abs_guest + (raddr - abs_host);
436 #endif /*defined(_FEATURE_SIE)*/
437
438 /* Convert trace entry absolute address back to real address */
439 raddr = APPLY_PREFIXING (raddr, regs->PX);
440
441 /* Return updated value of control register 12 */
442 return (regs->CR(12) & ~CR12_TRACEEA) | raddr;
443
444 } /* end function ARCH_DEP(set_trace_entry) */
445
446
447 /*-------------------------------------------------------------------*/
448 /* Form implicit branch trace entry */
449 /* */
450 /* Input: */
451 /* amode Non-zero if branch destination is a 31-bit address */
452 /* or a 64 bit address */
453 /* ia Branch destination address */
454 /* regs Pointer to the CPU register context */
455 /* Return value: */
456 /* Updated value for CR12 after adding new trace entry */
457 /* */
458 /* This function does not return if a program check occurs. */
459 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_br)460 CREG ARCH_DEP(trace_br) (int amode, VADR ia, REGS *regs)
461 {
462 RADR raddr;
463 RADR ag;
464 int size;
465
466 #if defined(FEATURE_ESAME)
467 if(amode && ia > 0xFFFFFFFFULL)
468 {
469 TRACE_F3_BR *tte;
470 size = sizeof(TRACE_F3_BR);
471 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
472 tte = (void*)(regs->mainstor + raddr);
473 tte->format = TRACE_F3_BR_FMT;
474 tte->fmt2 = TRACE_F3_BR_FM2;
475 STORE_HW(tte->resv,0);
476 STORE_DW(tte->newia64,ia);
477 }
478 else
479 #endif /*defined(FEATURE_ESAME)*/
480 if(amode)
481 {
482 TRACE_F2_BR *tte;
483 size = sizeof(TRACE_F2_BR);
484 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
485 tte = (void*)(regs->mainstor + raddr);
486 STORE_FW(tte->newia31,ia | 0x80000000);
487 }
488 else
489 {
490 TRACE_F1_BR *tte;
491 size = sizeof(TRACE_F1_BR);
492 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
493 tte = (void*)(regs->mainstor + raddr);
494 STORE_FW(tte->newia24,ia & 0x00FFFFFF);
495 }
496
497 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
498
499 } /* end function ARCH_DEP(trace_br) */
500
501
502 #if defined(FEATURE_SUBSPACE_GROUP)
503 /*-------------------------------------------------------------------*/
504 /* Form implicit BSG trace entry */
505 /* */
506 /* Input: */
507 /* alet Destination address space ALET */
508 /* ia Branch destination address */
509 /* regs Pointer to the CPU register context */
510 /* Return value: */
511 /* Updated value for CR12 after adding new trace entry */
512 /* */
513 /* This function does not return if a program check occurs. */
514 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_bsg)515 CREG ARCH_DEP(trace_bsg) (U32 alet, VADR ia, REGS *regs)
516 {
517 RADR raddr;
518 RADR ag;
519 int size;
520
521 #if defined(FEATURE_ESAME)
522 if(regs->psw.amode64)
523 {
524 TRACE_F2_BSG *tte;
525 size = sizeof(TRACE_F2_BSG);
526 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
527 tte = (void*)(regs->mainstor + raddr);
528 tte->format = TRACE_F2_BSG_FMT;
529 tte->alet[0] = (alet >> 16) & 0xFF;
530 tte->alet[1] = (alet >> 8) & 0xFF;
531 tte->alet[2] = alet & 0xFF;
532 STORE_DW(tte->newia,ia);
533 }
534 else
535 #endif /*defined(FEATURE_ESAME)*/
536 {
537 TRACE_F1_BSG *tte;
538 size = sizeof(TRACE_F1_BSG);
539 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
540 tte = (void*)(regs->mainstor + raddr);
541 tte->format = TRACE_F1_BSG_FMT;
542 tte->alet[0] = ((alet >> 17) & 0x80) | ((alet >> 16) & 0x7F);
543 tte->alet[1] = (alet >> 8) & 0xFF;
544 tte->alet[2] = alet & 0xFF;
545 if ((ia & 0x80000000) == 0)
546 ia &=0x00FFFFFF;
547 STORE_FW(tte->newia,ia);
548 }
549
550 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
551
552 } /* end function ARCH_DEP(trace_bsg) */
553 #endif /*defined(FEATURE_SUBSPACE_GROUP)*/
554
555
556 /*-------------------------------------------------------------------*/
557 /* Form implicit SSAR/SSAIR trace entry */
558 /* */
559 /* Input: */
560 /* ssair 1=SSAIR instruction, 0=SSAR instruction */
561 /* sasn Secondary address space number */
562 /* regs Pointer to the CPU register context */
563 /* Return value: */
564 /* Updated value for CR12 after adding new trace entry */
565 /* */
566 /* This function does not return if a program check occurs. */
567 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_ssar)568 CREG ARCH_DEP(trace_ssar) (int ssair, U16 sasn, REGS *regs)
569 {
570 RADR raddr;
571 RADR ag;
572 int size;
573 BYTE nbit = (ssair ? 1 : 0);
574
575 {
576 TRACE_F1_SSAR *tte;
577 size = sizeof(TRACE_F1_SSAR);
578 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
579 tte = (void*)(regs->mainstor + raddr);
580 tte->format = TRACE_F1_SSAR_FMT;
581 tte->extfmt = 0 | nbit;
582 STORE_HW(tte->newsasn,sasn);
583 }
584
585 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
586
587 } /* end function ARCH_DEP(trace_ssar) */
588
589
590 /*-------------------------------------------------------------------*/
591 /* Form implicit PC trace entry */
592 /* */
593 /* Input: */
594 /* pcea PC instruction effective address (20 or 32 bits) */
595 /* regs Pointer to the CPU register context */
596 /* Return value: */
597 /* Updated value for CR12 after adding new trace entry */
598 /* */
599 /* This function does not return if a program check occurs. */
600 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_pc)601 CREG ARCH_DEP(trace_pc) (U32 pcea, REGS *regs)
602 {
603 RADR raddr;
604 RADR ag;
605 int size;
606 int eamode;
607
608 SET_PSW_IA(regs);
609 eamode = regs->psw.amode64;
610
611 #if defined(FEATURE_ESAME)
612 if (ASN_AND_LX_REUSE_ENABLED(regs))
613 {
614 if ((pcea & PC_BIT44) && regs->psw.amode64 && regs->psw.IA_H)
615 {
616 /* In 64-bit mode, regardless of resulting mode, when
617 ASN-and-LX-reuse is enabled, 32-bit PC number is used,
618 and bits 0-31 of return address are not all zeros */
619 TRACE_F7_PC *tte;
620 size = sizeof(TRACE_F7_PC);
621 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
622 tte = (void*)(regs->mainstor + raddr);
623 tte->format = TRACE_F7_PC_FMT;
624 tte->pswkey = regs->psw.pkey | TRACE_F7_PC_FM2 | eamode;
625 STORE_HW(tte->resv, 0x0000);
626 STORE_DW(tte->retna, regs->psw.IA_G | PROBSTATE(®s->psw));
627 STORE_FW(tte->pcnum, pcea);
628 }
629 else
630 if ((pcea & PC_BIT44) && regs->psw.amode64)
631 {
632 /* In 64-bit mode, regardless of resulting mode, when
633 ASN-and-LX-reuse is enabled, 32-bit PC number is used,
634 and bits 0-31 of return address are all zeros */
635 TRACE_F6_PC *tte;
636 size = sizeof(TRACE_F6_PC);
637 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
638 tte = (void*)(regs->mainstor + raddr);
639 tte->format = TRACE_F6_PC_FMT;
640 tte->pswkey = regs->psw.pkey | TRACE_F6_PC_FM2 | eamode;
641 STORE_HW(tte->resv, 0x0000);
642 STORE_FW(tte->retna, regs->psw.IA_L | PROBSTATE(®s->psw));
643 STORE_FW(tte->pcnum, pcea);
644 }
645 else
646 if ((pcea & PC_BIT44))
647 {
648 /* In 24-bit or 31-bit mode, regardless of resulting mode, when
649 ASN-and-LX-reuse is enabled and 32-bit PC number is used */
650 TRACE_F5_PC *tte;
651 size = sizeof(TRACE_F5_PC);
652 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
653 tte = (void*)(regs->mainstor + raddr);
654 tte->format = TRACE_F5_PC_FMT;
655 tte->pswkey = regs->psw.pkey | TRACE_F5_PC_FM2 | eamode;
656 STORE_HW(tte->resv, 0x0000);
657 STORE_FW(tte->retna, (regs->psw.amode << 31) | regs->psw.IA_L | PROBSTATE(®s->psw));
658 STORE_FW(tte->pcnum, pcea);
659 }
660 else
661 if(regs->psw.amode64)
662 {
663 /* In 64-bit mode, regardless of resulting mode, when
664 ASN-and-LX-reuse is enabled and 20-bit PC number is used */
665 TRACE_F4_PC *tte;
666 size = sizeof(TRACE_F4_PC);
667 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
668 tte = (void*)(regs->mainstor + raddr);
669 tte->format = TRACE_F4_PC_FMT;
670 tte->pswkey_pcnum_hi = regs->psw.pkey | ((pcea & 0xF0000) >> 16);
671 STORE_HW(tte->pcnum_lo, pcea & 0x0FFFF);
672 STORE_DW(tte->retna, regs->psw.IA_G | PROBSTATE(®s->psw));
673 }
674 else
675 {
676 /* In 24-bit or 31-bit mode, regardless of resulting mode, when
677 ASN-and-LX-reuse is enabled and 20-bit PC number is used */
678 TRACE_F3_PC *tte;
679 size = sizeof(TRACE_F3_PC);
680 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
681 tte = (void*)(regs->mainstor + raddr);
682 tte->format = TRACE_F3_PC_FMT;
683 tte->pswkey_pcnum_hi = regs->psw.pkey | ((pcea & 0xF0000) >> 16);
684 STORE_HW(tte->pcnum_lo, pcea & 0x0FFFF);
685 STORE_FW(tte->retna, (regs->psw.amode << 31) | regs->psw.IA_L | PROBSTATE(®s->psw));
686 }
687 } /* end ASN_AND_LX_REUSE_ENABLED */
688 else
689 if(regs->psw.amode64)
690 {
691 /* In 64-bit mode, regardless of resulting mode,
692 when ASN-and-LX-reuse is not enabled */
693 TRACE_F2_PC *tte;
694 size = sizeof(TRACE_F2_PC);
695 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
696 tte = (void*)(regs->mainstor + raddr);
697 tte->format = TRACE_F2_PC_FMT;
698 tte->pswkey_pcnum_hi = regs->psw.pkey | ((pcea & 0xF0000) >> 16);
699 STORE_HW(tte->pcnum_lo, pcea & 0x0FFFF);
700 STORE_DW(tte->retna, regs->psw.IA_G | PROBSTATE(®s->psw));
701 }
702 else
703 #endif /*defined(FEATURE_ESAME)*/
704 {
705 /* In 24-bit or 31-bit mode, regardless of resulting mode,
706 when ASN-and-LX-reuse is not enabled */
707 TRACE_F1_PC *tte;
708 size = sizeof(TRACE_F1_PC);
709 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
710 tte = (void*)(regs->mainstor + raddr);
711 tte->format = TRACE_F1_PC_FMT;
712 tte->pswkey_pcnum_hi = regs->psw.pkey | ((pcea & 0xF0000) >> 16);
713 STORE_HW(tte->pcnum_lo, pcea & 0x0FFFF);
714 STORE_FW(tte->retna, (regs->psw.amode << 31) | regs->psw.IA_L | PROBSTATE(®s->psw));
715 }
716
717 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
718
719 } /* end function ARCH_DEP(trace_pc) */
720
721 #if defined(_MSVC_)
722 /* Workaround for "fatal error C1001: INTERNAL COMPILER ERROR" in MSVC */
723 #pragma optimize("",off)
724 #endif /*defined(_MSVC_)*/
725
726 #if defined(FEATURE_LINKAGE_STACK)
727 /*-------------------------------------------------------------------*/
728 /* Form implicit PR trace entry */
729 /* */
730 /* Input: */
731 /* newregs Pointer to registers after PR instruction */
732 /* regs Pointer to registers before PR instruction */
733 /* Return value: */
734 /* Updated value for CR12 after adding new trace entry */
735 /* */
736 /* This function does not return if a program check occurs. */
737 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_pr)738 CREG ARCH_DEP(trace_pr) (REGS *newregs, REGS *regs)
739 {
740 RADR raddr;
741 RADR ag;
742 int size;
743
744 SET_PSW_IA(regs);
745 SET_PSW_IA(newregs);
746
747 #if defined(FEATURE_ESAME)
748 if(!regs->psw.amode64 && !newregs->psw.amode64)
749 #endif /*defined(FEATURE_ESAME)*/
750 {
751 TRACE_F1_PR *tte;
752 size = sizeof(TRACE_F1_PR);
753 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
754 tte = (void*)(regs->mainstor + raddr);
755 tte->format = TRACE_F1_PR_FMT;
756 tte->pswkey = regs->psw.pkey | TRACE_F1_PR_FM2;
757 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
758 STORE_FW(tte->retna, (newregs->psw.amode << 31)
759 | newregs->psw.IA_L | PROBSTATE(&newregs->psw));
760 STORE_FW(tte->newia, (regs->psw.amode << 31)
761 | regs->psw.IA_L);
762 }
763 #if defined(FEATURE_ESAME)
764 else
765 if(regs->psw.amode64 && regs->psw.IA_H == 0 && !newregs->psw.amode64)
766 {
767 TRACE_F2_PR *tte;
768 size = sizeof(TRACE_F2_PR);
769 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
770 tte = (void*)(regs->mainstor + raddr);
771 tte->format = TRACE_F2_PR_FMT;
772 tte->pswkey = regs->psw.pkey | TRACE_F2_PR_FM2;
773 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
774 STORE_FW(tte->retna, (newregs->psw.amode << 31)
775 | newregs->psw.IA_L | PROBSTATE(&newregs->psw));
776 STORE_FW(tte->newia, regs->psw.IA_L);
777 }
778 else
779 if(regs->psw.amode64 && regs->psw.IA_H != 0 && !newregs->psw.amode64)
780 {
781 TRACE_F3_PR *tte;
782 size = sizeof(TRACE_F3_PR);
783 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
784 tte = (void*)(regs->mainstor + raddr);
785 tte->format = TRACE_F3_PR_FMT;
786 tte->pswkey = regs->psw.pkey | TRACE_F3_PR_FM2;
787 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
788 STORE_FW(tte->retna, (newregs->psw.amode << 31)
789 | newregs->psw.IA_L | PROBSTATE(&newregs->psw));
790 STORE_DW(tte->newia, regs->psw.IA_G);
791 }
792 else
793 if(!regs->psw.amode64 && newregs->psw.amode64 && newregs->psw.IA_H == 0)
794 {
795 TRACE_F4_PR *tte;
796 size = sizeof(TRACE_F4_PR);
797 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
798 tte = (void*)(regs->mainstor + raddr);
799 tte->format = TRACE_F4_PR_FMT;
800 tte->pswkey = regs->psw.pkey | TRACE_F4_PR_FM2;
801 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
802 STORE_FW(tte->retna, newregs->psw.IA_L | PROBSTATE(&newregs->psw));
803 STORE_FW(tte->newia, (regs->psw.amode << 31)
804 | regs->psw.IA_L);
805 }
806 else
807 if(regs->psw.amode64 && regs->psw.IA_H == 0 && newregs->psw.amode64 && newregs->psw.IA_H == 0)
808 {
809 TRACE_F5_PR *tte;
810 size = sizeof(TRACE_F5_PR);
811 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
812 tte = (void*)(regs->mainstor + raddr);
813 tte->format = TRACE_F5_PR_FMT;
814 tte->pswkey = regs->psw.pkey | TRACE_F5_PR_FM2;
815 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
816 STORE_FW(tte->retna, newregs->psw.IA_L | PROBSTATE(&newregs->psw));
817 STORE_FW(tte->newia, regs->psw.IA_L);
818 }
819 else
820 if(regs->psw.amode64 && regs->psw.IA_H != 0 && newregs->psw.amode64 && newregs->psw.IA_H == 0)
821 {
822 TRACE_F6_PR *tte;
823 size = sizeof(TRACE_F6_PR);
824 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
825 tte = (void*)(regs->mainstor + raddr);
826 tte->format = TRACE_F6_PR_FMT;
827 tte->pswkey = regs->psw.pkey | TRACE_F6_PR_FM2;
828 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
829 STORE_FW(tte->retna, newregs->psw.IA_L | PROBSTATE(&newregs->psw));
830 STORE_DW(tte->newia, regs->psw.IA_G);
831 }
832 else
833 if(!regs->psw.amode64 && newregs->psw.amode64 && newregs->psw.IA_H != 0)
834 {
835 TRACE_F7_PR *tte;
836 size = sizeof(TRACE_F7_PR);
837 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
838 tte = (void*)(regs->mainstor + raddr);
839 tte->format = TRACE_F7_PR_FMT;
840 tte->pswkey = regs->psw.pkey | TRACE_F7_PR_FM2;
841 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
842 STORE_DW(tte->retna, newregs->psw.IA_G | PROBSTATE(&newregs->psw));
843 STORE_FW(tte->newia, (regs->psw.amode << 31)
844 | regs->psw.IA_L);
845 }
846 else
847 if(regs->psw.amode64 && regs->psw.IA_H == 0 && newregs->psw.amode64 && newregs->psw.IA_H != 0)
848 {
849 TRACE_F8_PR *tte;
850 size = sizeof(TRACE_F8_PR);
851 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
852 tte = (void*)(regs->mainstor + raddr);
853 tte->format = TRACE_F8_PR_FMT;
854 tte->pswkey = regs->psw.pkey | TRACE_F8_PR_FM2;
855 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
856 STORE_DW(tte->retna, newregs->psw.IA_G | PROBSTATE(&newregs->psw));
857 STORE_FW(tte->newia, regs->psw.IA_L);
858 }
859 else
860 /* if(regs->psw.amode64 && regs->psw.IA_H != 0 && newregs->psw.amode64 && newregs->psw.IA_H != 0) */
861 {
862 TRACE_F9_PR *tte;
863 size = sizeof(TRACE_F9_PR);
864 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
865 tte = (void*)(regs->mainstor + raddr);
866 tte->format = TRACE_F9_PR_FMT;
867 tte->pswkey = regs->psw.pkey | TRACE_F9_PR_FM2;
868 STORE_HW(tte->newpasn, newregs->CR_LHL(4));
869 STORE_DW(tte->retna, newregs->psw.IA_G | PROBSTATE(&newregs->psw));
870 STORE_DW(tte->newia, regs->psw.IA_G);
871 }
872 #endif /*defined(FEATURE_ESAME)*/
873
874 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
875
876 } /* end function ARCH_DEP(trace_pr) */
877 #endif /*defined(FEATURE_LINKAGE_STACK)*/
878
879 #if defined(_MSVC_)
880 /* Workaround for "fatal error C1001: INTERNAL COMPILER ERROR" in MSVC */
881 #pragma optimize("",on)
882 #endif /*defined(_MSVC_)*/
883
884 /*-------------------------------------------------------------------*/
885 /* Form implicit PT/PTI trace entry */
886 /* */
887 /* Input: */
888 /* pti 1=PTI instruction, 0=PT instruction */
889 /* pasn Primary address space number */
890 /* gpr2 Contents of PT second operand register */
891 /* regs Pointer to the CPU register context */
892 /* Return value: */
893 /* Updated value for CR12 after adding new trace entry */
894 /* */
895 /* This function does not return if a program check occurs. */
896 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_pt)897 CREG ARCH_DEP(trace_pt) (int pti, U16 pasn, GREG gpr2, REGS *regs)
898 {
899 RADR raddr;
900 RADR ag;
901 int size;
902 BYTE nbit = (pti ? 1 : 0);
903
904 #if defined(FEATURE_ESAME)
905 if(regs->psw.amode64 && gpr2 > 0xFFFFFFFFULL)
906 {
907 TRACE_F3_PT *tte;
908 size = sizeof(TRACE_F3_PT);
909 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
910 tte = (void*)(regs->mainstor + raddr);
911 tte->format = TRACE_F3_PT_FMT;
912 tte->pswkey = regs->psw.pkey | TRACE_F3_PT_FM2 | nbit;
913 STORE_HW(tte->newpasn, pasn);
914 STORE_DW(tte->r2, gpr2);
915 }
916 else
917 if(regs->psw.amode64)
918 {
919 TRACE_F2_PT *tte;
920 size = sizeof(TRACE_F2_PT);
921 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
922 tte = (void*)(regs->mainstor + raddr);
923 tte->format = TRACE_F2_PT_FMT;
924 tte->pswkey = regs->psw.pkey | TRACE_F2_PT_FM2 | nbit;
925 STORE_HW(tte->newpasn, pasn);
926 STORE_FW(tte->r2, gpr2 & 0xFFFFFFFF);
927 }
928 else
929 #endif /*defined(FEATURE_ESAME)*/
930 {
931 TRACE_F1_PT *tte;
932 size = sizeof(TRACE_F1_PT);
933 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
934 tte = (void*)(regs->mainstor + raddr);
935 tte->format = TRACE_F1_PT_FMT;
936 tte->pswkey = regs->psw.pkey | TRACE_F1_PT_FM2 | nbit;
937 STORE_HW(tte->newpasn, pasn);
938 STORE_FW(tte->r2, gpr2 & 0xFFFFFFFF);
939 }
940
941 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
942
943 } /* end function ARCH_DEP(trace_pt) */
944
945
946 #if defined(FEATURE_ESAME)
947 /*-------------------------------------------------------------------*/
948 /* Form implicit MS trace entry */
949 /* */
950 /* Input: */
951 /* br Mode switch branch indicator */
952 /* baddr Branch address for mode switch branch */
953 /* regs Pointer to the CPU register context */
954 /* Return value: */
955 /* Updated value for CR12 after adding new trace entry */
956 /* */
957 /* This function does not return if a program check occurs. */
958 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_ms)959 CREG ARCH_DEP(trace_ms) (int br, VADR baddr, REGS *regs)
960 {
961 RADR raddr;
962 RADR ag;
963 int size;
964
965 SET_PSW_IA(regs);
966
967 if(!br)
968 {
969 if(!regs->psw.amode64)
970 {
971 TRACE_F1_MS *tte;
972 size = sizeof(TRACE_F1_MS);
973 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
974 tte = (void*)(regs->mainstor + raddr);
975 tte->format = TRACE_F1_MS_FMT;
976 tte->fmt2 = TRACE_F1_MS_FM2;
977 STORE_HW(tte->resv, 0);
978 STORE_FW(tte->newia, regs->psw.IA | (regs->psw.amode << 31));
979 }
980 else
981 if(regs->psw.amode64 && regs->psw.IA <= 0x7FFFFFFF)
982 {
983 TRACE_F2_MS *tte;
984 size = sizeof(TRACE_F2_MS);
985 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
986 tte = (void*)(regs->mainstor + raddr);
987 tte->format = TRACE_F2_MS_FMT;
988 tte->fmt2 = TRACE_F2_MS_FM2;
989 STORE_HW(tte->resv, 0);
990 STORE_FW(tte->newia, regs->psw.IA);
991 }
992 else
993 {
994 TRACE_F3_MS *tte;
995 size = sizeof(TRACE_F3_MS);
996 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
997 tte = (void*)(regs->mainstor + raddr);
998 tte->format = TRACE_F3_MS_FMT;
999 tte->fmt2 = TRACE_F3_MS_FM2;
1000 STORE_HW(tte->resv, 0);
1001 STORE_DW(tte->newia, regs->psw.IA);
1002 }
1003 }
1004 else
1005 {
1006 /* if currently in 64-bit, we are switching out */
1007 if(regs->psw.amode64)
1008 {
1009 TRACE_F1_MSB *tte;
1010 size = sizeof(TRACE_F1_MSB);
1011 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
1012 tte = (void*)(regs->mainstor + raddr);
1013 tte->format = TRACE_F1_MSB_FMT;
1014 tte->fmt2 = TRACE_F1_MSB_FM2;
1015 STORE_HW(tte->resv, 0);
1016 STORE_FW(tte->newia, baddr);
1017 }
1018 else
1019 if(!regs->psw.amode64 && baddr <= 0x7FFFFFFF)
1020 {
1021 TRACE_F2_MSB *tte;
1022 size = sizeof(TRACE_F2_MSB);
1023 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
1024 tte = (void*)(regs->mainstor + raddr);
1025 tte->format = TRACE_F2_MSB_FMT;
1026 tte->fmt2 = TRACE_F2_MSB_FM2;
1027 STORE_HW(tte->resv, 0);
1028 STORE_FW(tte->newia, baddr);
1029 }
1030 else
1031 {
1032 TRACE_F3_MSB *tte;
1033 size = sizeof(TRACE_F3_MSB);
1034 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
1035 tte = (void*)(regs->mainstor + raddr);
1036 tte->format = TRACE_F3_MSB_FMT;
1037 tte->fmt2 = TRACE_F3_MSB_FM2;
1038 STORE_HW(tte->resv, 0);
1039 STORE_DW(tte->newia, baddr);
1040 }
1041 }
1042
1043 return ARCH_DEP(set_trace_entry) (ag, raddr, size, regs);
1044
1045 } /* end function ARCH_DEP(trace_ms) */
1046 #endif /*defined(FEATURE_ESAME)*/
1047
1048
1049 /*-------------------------------------------------------------------*/
1050 /* Form explicit TRACE trace entry */
1051 /* */
1052 /* Input: */
1053 /* r1, r3 registers identifying register space to be written */
1054 /* op Trace operand */
1055 /* regs Pointer to the CPU register context */
1056 /* Return value: */
1057 /* Updated value for CR12 after adding new trace entry */
1058 /* */
1059 /* This function does not return if a program check occurs. */
1060 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_tr)1061 CREG ARCH_DEP(trace_tr) (int r1, int r3, U32 op, REGS *regs)
1062 {
1063 RADR raddr;
1064 RADR ag;
1065 int size;
1066 int i, j, n;
1067 U64 dreg;
1068
1069 {
1070 TRACE_F1_TR *tte;
1071 size = sizeof(TRACE_F1_TR);
1072 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
1073 tte = (void*)(regs->mainstor + raddr);
1074
1075 /* Calculate the number of registers to be traced, minus 1 */
1076 n = ( r3 < r1 ) ? r3 + 16 - r1 : r3 - r1;
1077
1078 /* Retrieve the TOD clock value and shift out the epoch */
1079 dreg = (tod_clock(regs) << 8) | regs->cpuad;
1080
1081 tte->format = TRACE_F1_TR_FMT | n;
1082 tte->fmt2 = TRACE_F1_TR_FM2;
1083
1084 STORE_HW(tte->clk16, (dreg >> 32) & 0xFFFF);
1085 STORE_FW(tte->clk32, dreg & 0xFFFFFFFF);
1086 STORE_FW(tte->operand, op);
1087
1088 for(i = r1, j = 0; ; )
1089 {
1090 STORE_FW(tte->reg[j++], regs->GR_L(i));
1091
1092 /* Regdump is complete when r3 is done */
1093 if(r3 == i) break;
1094
1095 /* Update register number and wrap */
1096 i++; i &= 15;
1097 }
1098
1099 }
1100
1101 return ARCH_DEP(set_trace_entry) (ag, raddr, size - (4 * (15 - n)), regs);
1102
1103 } /* end function ARCH_DEP(trace_tr) */
1104
1105
1106 #if defined(FEATURE_ESAME)
1107 /*-------------------------------------------------------------------*/
1108 /* Form explicit TRACG trace entry */
1109 /* */
1110 /* Input: */
1111 /* r1, r3 registers identifying register space to be written */
1112 /* op Trace operand */
1113 /* regs Pointer to the CPU register context */
1114 /* Return value: */
1115 /* Updated value for CR12 after adding new trace entry */
1116 /* */
1117 /* This function does not return if a program check occurs. */
1118 /*-------------------------------------------------------------------*/
ARCH_DEP(trace_tg)1119 CREG ARCH_DEP(trace_tg) (int r1, int r3, U32 op, REGS *regs)
1120 {
1121 RADR raddr;
1122 RADR ag;
1123 int size;
1124 int i, j, n;
1125 U64 dreg;
1126
1127 {
1128 TRACE_F2_TR *tte;
1129 size = sizeof(TRACE_F2_TR);
1130 raddr = ARCH_DEP(get_trace_entry) (&ag, size, regs);
1131 tte = (void*)(regs->mainstor + raddr);
1132
1133 /* Calculate the number of registers to be traced, minus 1 */
1134 n = ( r3 < r1 ) ? r3 + 16 - r1 : r3 - r1;
1135
1136 /* Retrieve the TOD clock value including the epoch */
1137 dreg = tod_clock(regs);
1138
1139 tte->format = TRACE_F2_TR_FMT | n;
1140 tte->fmt2 = TRACE_F2_TR_FM2;
1141
1142 STORE_HW(tte->clk0, (dreg >> 48) & 0xFFFF);
1143 /* shift out the epoch */
1144 dreg = (dreg << 8) | regs->cpuad;
1145 STORE_FW(tte->clk16, (dreg >> 32) & 0xFFFFFFFF);
1146 STORE_FW(tte->clk48, dreg & 0xFFFFFFFF);
1147 STORE_FW(tte->operand, op);
1148
1149 for(i = r1, j = 0; ; )
1150 {
1151 STORE_DW(tte->reg[j++], regs->GR_G(i));
1152
1153 /* Regdump is complete when r3 is done */
1154 if(r3 == i) break;
1155
1156 /* Update register number and wrap */
1157 i++; i &= 15;
1158 }
1159
1160 }
1161
1162 return ARCH_DEP(set_trace_entry) (ag, raddr, size - (8 * (15 - n)), regs);
1163
1164 } /* end function ARCH_DEP(trace_tg) */
1165 #endif /*defined(FEATURE_ESAME)*/
1166
1167 #endif /*defined(FEATURE_TRACING)*/
1168
1169
1170 #if !defined(_GEN_ARCH)
1171
1172 #if defined(_ARCHMODE2)
1173 #define _GEN_ARCH _ARCHMODE2
1174 #include "trace.c"
1175 #endif
1176
1177 #if defined(_ARCHMODE3)
1178 #undef _GEN_ARCH
1179 #define _GEN_ARCH _ARCHMODE3
1180 #include "trace.c"
1181 #endif
1182
1183 #endif /*!defined(_GEN_ARCH)*/
1184