xref: /kvm-unit-tests/lib/s390x/css_dump.c (revision 1b53866b0b494277ab41c7c0cec4ee00969dd32e)
1 /*
2  * Channel subsystem structures dumping
3  *
4  * Copyright (c) 2020 IBM Corp.
5  *
6  * Authors:
7  *  Pierre Morel <pmorel@linux.ibm.com>
8  *
9  * This code is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License version 2.
11  *
12  * Description:
13  * Provides the dumping functions for various structures used by subchannels:
14  * - ORB  : Operation request block, describes the I/O operation and points to
15  *          a CCW chain
16  * - CCW  : Channel Command Word, describes the command, data and flow control
17  * - IRB  : Interuption response Block, describes the result of an operation;
18  *          holds a SCSW and model-dependent data.
19  * - SCHIB: SubCHannel Information Block composed of:
20  *   - SCSW: SubChannel Status Word, status of the channel.
21  *   - PMCW: Path Management Control Word
22  * You need the QEMU ccw-pong device in QEMU to answer the I/O transfers.
23  */
24 
25 #include <libcflat.h>
26 #include <stdint.h>
27 #include <string.h>
28 
29 #include <css.h>
30 
31 /*
32  * Try to have a more human representation of the SCSW flags:
33  * each letter in the two strings represents the first
34  * letter of the associated bit in the flag fields.
35  */
36 static const char *scsw_str = "kkkkslccfpixuzen";
37 static const char *scsw_str2 = "1SHCrshcsdsAIPSs";
38 static char scsw_line[64] = {};
39 
40 char *dump_scsw_flags(uint32_t f)
41 {
42 	int i;
43 
44 	for (i = 0; i < 16; i++) {
45 		if ((f << i) & 0x80000000)
46 			scsw_line[i] = scsw_str[i];
47 		else
48 			scsw_line[i] = '_';
49 	}
50 	scsw_line[i] = ' ';
51 	for (; i < 32; i++) {
52 		if ((f << i) & 0x80000000)
53 			scsw_line[i + 1] = scsw_str2[i - 16];
54 		else
55 			scsw_line[i + 1] = '_';
56 	}
57 	return scsw_line;
58 }
59 
60 /*
61  * Try to have a more human representation of the PMCW flags
62  * each letter in the string represents the first
63  * letter of the associated bit in the flag fields.
64  */
65 static const char *pmcw_str = "11iii111ellmmdtv";
66 static char pcmw_line[32] = {};
67 char *dump_pmcw_flags(uint16_t f)
68 {
69 	int i;
70 
71 	for (i = 0; i < 16; i++) {
72 		if ((f << i) & 0x8000)
73 			pcmw_line[i] = pmcw_str[i];
74 		else
75 			pcmw_line[i] = '_';
76 	}
77 	return pcmw_line;
78 }
79 
80 void dump_scsw(struct scsw *s)
81 {
82 	dump_scsw_flags(s->ctrl);
83 	printf("scsw->flags: %s\n", scsw_line);
84 	printf("scsw->addr : %08x\n", s->ccw_addr);
85 	printf("scsw->devs : %02x\n", s->dev_stat);
86 	printf("scsw->schs : %02x\n", s->sch_stat);
87 	printf("scsw->count: %04x\n", s->count);
88 }
89 
90 void dump_irb(struct irb *irbp)
91 {
92 	int i;
93 	uint32_t *p = (uint32_t *)irbp;
94 
95 	dump_scsw(&irbp->scsw);
96 	for (i = 0; i < sizeof(*irbp)/sizeof(*p); i++, p++)
97 		printf("irb[%02x] : %08x\n", i, *p);
98 }
99 
100 void dump_pmcw(struct pmcw *p)
101 {
102 	int i;
103 
104 	printf("pmcw->intparm  : %08x\n", p->intparm);
105 	printf("pmcw->flags    : %04x\n", p->flags);
106 	dump_pmcw_flags(p->flags);
107 	printf("pmcw->devnum   : %04x\n", p->devnum);
108 	printf("pmcw->lpm      : %02x\n", p->lpm);
109 	printf("pmcw->pnom     : %02x\n", p->pnom);
110 	printf("pmcw->lpum     : %02x\n", p->lpum);
111 	printf("pmcw->pim      : %02x\n", p->pim);
112 	printf("pmcw->mbi      : %04x\n", p->mbi);
113 	printf("pmcw->pom      : %02x\n", p->pom);
114 	printf("pmcw->pam      : %02x\n", p->pam);
115 	printf("pmcw->mbi      : %04x\n", p->mbi);
116 	for (i = 0; i < 8; i++)
117 		printf("pmcw->chpid[%d]: %02x\n", i, p->chpid[i]);
118 	printf("pmcw->flags2  : %08x\n", p->flags2);
119 }
120 
121 void dump_schib(struct schib *sch)
122 {
123 	struct pmcw *p = &sch->pmcw;
124 	struct scsw *s = &sch->scsw;
125 
126 	printf("--SCHIB--\n");
127 	dump_pmcw(p);
128 	dump_scsw(s);
129 }
130 
131 struct ccw1 *dump_ccw(struct ccw1 *cp)
132 {
133 	printf("CCW: code: %02x flags: %02x count: %04x data: %08x\n", cp->code,
134 	    cp->flags, cp->count, cp->data_address);
135 
136 	if (cp->code == CCW_C_TIC)
137 		return (struct ccw1 *)(long)cp->data_address;
138 
139 	return (cp->flags & CCW_F_CC) ? cp + 1 : NULL;
140 }
141 
142 void dump_orb(struct orb *op)
143 {
144 	struct ccw1 *cp;
145 
146 	printf("ORB: intparm : %08x\n", op->intparm);
147 	printf("ORB: ctrl    : %08x\n", op->ctrl);
148 	printf("ORB: prio    : %08x\n", op->prio);
149 	cp = (struct ccw1 *)(long) (op->cpa);
150 	while (cp)
151 		cp = dump_ccw(cp);
152 }
153