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