1 /* $OpenBSD: isapnpdebug.c,v 1.4 2022/01/03 09:48:41 jsg Exp $ */ 2 /* $NetBSD: isapnpdebug.c,v 1.4 1997/08/03 08:12:23 mikel Exp $ */ 3 4 /* 5 * Copyright (c) 1996 Christos Zoulas. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Christos Zoulas. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 #ifdef DEBUG_ISAPNP 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/device.h> 38 39 #include <machine/bus.h> 40 41 #include <dev/isa/isapnpreg.h> 42 43 #include <dev/isa/isavar.h> 44 45 /* isapnp_print_mem(): 46 * Print a memory tag 47 */ 48 void 49 isapnp_print_mem(const char *str, const struct isapnp_region *mem) 50 { 51 printf("%sMemory: %s,%sshadowable,decode-%s,%scacheable,%s", str, 52 (mem->flags & ISAPNP_MEMATTR_ROM) ? "ROM," : "RAM,", 53 (mem->flags & ISAPNP_MEMATTR_SHADOWABLE) ? "" : "non-", 54 (mem->flags & ISAPNP_MEMATTR_HIGH_ADDR) ? 55 "high-addr," : "range-len,", 56 (mem->flags & ISAPNP_MEMATTR_CACHEABLE) ? "" : "non-", 57 (mem->flags & ISAPNP_MEMATTR_WRITEABLE) ? 58 "writable," : "read-only,"); 59 60 switch (mem->flags & ISAPNP_MEMWIDTH_MASK) { 61 case ISAPNP_MEMWIDTH_8: 62 printf("8-bit "); 63 break; 64 case ISAPNP_MEMWIDTH_16: 65 printf("16-bit "); 66 break; 67 case ISAPNP_MEMWIDTH_8_16: 68 printf("8/16-bit "); 69 break; 70 case ISAPNP_MEMWIDTH_32: 71 printf("32-bit "); 72 break; 73 } 74 75 printf("min 0x%x, max 0x%x, ", mem->minbase, mem->maxbase); 76 printf("align 0x%x, length 0x%x\n", mem->align, mem->length); 77 } 78 79 80 /* isapnp_print_io(): 81 * Print an io tag 82 */ 83 void 84 isapnp_print_io(const char *str, const struct isapnp_region *io) 85 { 86 printf("%d %sIO Ports: %d address bits, alignment %d ", 87 io->length, str, (io->flags & ISAPNP_IOFLAGS_16) ? 16 : 10, 88 io->align); 89 90 printf("min 0x%x, max 0x%x\n", io->minbase, io->maxbase); 91 } 92 93 94 /* isapnp_print_irq(): 95 * Print an irq tag 96 */ 97 void 98 isapnp_print_irq(const char *str, const struct isapnp_pin *irq) 99 { 100 int i; 101 102 printf("%sIRQ's supported: ", str); 103 for (i = 0; i < 16; i++) 104 if (irq->bits & (1 << i)) 105 printf("%d ", i); 106 107 if (irq->flags & ISAPNP_IRQTYPE_EDGE_PLUS) 108 printf("E+"); 109 if (irq->flags & ISAPNP_IRQTYPE_EDGE_MINUS) 110 printf("E-"); 111 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_PLUS) 112 printf("L+"); 113 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_MINUS) 114 printf("L-"); 115 printf("\n"); 116 } 117 118 /* isapnp_print_drq(): 119 * Print a drq tag 120 */ 121 void 122 isapnp_print_drq(const char *str, const struct isapnp_pin *drq) 123 { 124 int i; 125 u_char flags = drq->flags; 126 127 printf("%sDRQ's supported: ", str); 128 for (i = 0; i < 8; i++) 129 if (drq->bits & (1 << i)) 130 printf("%d ", i); 131 132 printf("Width: "); 133 switch (flags & ISAPNP_DMAWIDTH_MASK) { 134 case ISAPNP_DMAWIDTH_8: 135 printf("8-bit "); 136 break; 137 case ISAPNP_DMAWIDTH_8_16: 138 printf("8/16-bit "); 139 break; 140 case ISAPNP_DMAWIDTH_16: 141 printf("16-bit "); 142 break; 143 case ISAPNP_DMAWIDTH_RESERVED: 144 printf("Reserved "); 145 break; 146 } 147 148 printf("Speed: "); 149 switch (flags & ISAPNP_DMASPEED_MASK) { 150 case ISAPNP_DMASPEED_COMPAT: 151 printf("compat "); 152 break; 153 case ISAPNP_DMASPEED_A: 154 printf("A "); 155 break; 156 case ISAPNP_DMASPEED_B: 157 printf("B "); 158 break; 159 case ISAPNP_DMASPEED_F: 160 printf("F "); 161 break; 162 } 163 164 if (flags & ISAPNP_DMAATTR_MASK) 165 printf("Attributes: %s%s%s", 166 (flags & ISAPNP_DMAATTR_BUS_MASTER) ? "bus master " : "", 167 (flags & ISAPNP_DMAATTR_INCR_8) ? "incr 8 " : "", 168 (flags & ISAPNP_DMAATTR_INCR_16) ? "incr 16 " : ""); 169 printf("\n"); 170 } 171 172 173 /* isapnp_print_dep_start(): 174 * Print a start dependencies tag 175 */ 176 void 177 isapnp_print_dep_start(const char *str, const u_char pref) 178 { 179 180 printf("%sconfig: ", str); 181 switch (pref) { 182 case ISAPNP_DEP_PREFERRED: 183 printf("preferred\n"); 184 break; 185 186 case ISAPNP_DEP_ACCEPTABLE: 187 printf("acceptable\n"); 188 break; 189 190 case ISAPNP_DEP_FUNCTIONAL: 191 printf("functional\n"); 192 break; 193 194 case ISAPNP_DEP_UNSET: /* Used internally */ 195 printf("unset\n"); 196 break; 197 198 case ISAPNP_DEP_CONFLICTING: /* Used internally */ 199 printf("conflicting\n"); 200 break; 201 202 default: 203 printf("invalid\n"); 204 break; 205 } 206 } 207 208 void 209 isapnp_print_attach(const struct isa_attach_args *pa) 210 { 211 int i; 212 213 printf("Found <%s, %s, %s, %s> ", pa->ipa_devident, 214 pa->ipa_devlogic, pa->ipa_devcompat, pa->ipa_devclass); 215 isapnp_print_dep_start("", pa->ipa_pref); 216 217 for (i = 0; i < pa->ipa_nio; i++) 218 isapnp_print_io("", &pa->ipa_io[i]); 219 220 for (i = 0; i < pa->ipa_nmem; i++) 221 isapnp_print_mem("", &pa->ipa_mem[i]); 222 223 for (i = 0; i < pa->ipa_nirq; i++) 224 isapnp_print_irq("", &pa->ipa_irq[i]); 225 226 for (i = 0; i < pa->ipa_ndrq; i++) 227 isapnp_print_drq("", &pa->ipa_drq[i]); 228 229 for (i = 0; i < pa->ipa_nmem32; i++) 230 isapnp_print_mem("", &pa->ipa_mem32[i]); 231 } 232 233 234 /* isapnp_get_config(): 235 * Get the current configuration of the card 236 */ 237 void 238 isapnp_get_config(struct isapnp_softc *sc, struct isa_attach_args *pa) 239 { 240 int i; 241 u_char v0, v1, v2, v3; 242 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC; 243 static u_char isapnp_io_range[] = ISAPNP_IO_DESC; 244 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC; 245 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC; 246 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC; 247 struct isapnp_region *r; 248 struct isapnp_pin *p; 249 250 bzero(pa, sizeof(*pa)); 251 252 for (i = 0; i < sizeof(isapnp_io_range); i++) { 253 r = &pa->ipa_io[i]; 254 v0 = isapnp_read_reg(sc, 255 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8); 256 v1 = isapnp_read_reg(sc, 257 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0); 258 r->base = (v0 << 8) | v1; 259 if (r->base == 0) 260 break; 261 } 262 pa->ipa_nio = i; 263 264 for (i = 0; i < sizeof(isapnp_mem_range); i++) { 265 r = &pa->ipa_mem[i]; 266 v0 = isapnp_read_reg(sc, 267 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16); 268 v1 = isapnp_read_reg(sc, 269 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8); 270 r->base = (v0 << 16) | (v1 << 8); 271 if (r->base == 0) 272 break; 273 274 v0 = isapnp_read_reg(sc, 275 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16); 276 v1 = isapnp_read_reg(sc, 277 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8); 278 r->length = (v0 << 16) | (v1 << 8); 279 v0 = isapnp_read_reg(sc, 280 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 281 r->flags = 0; 282 if (v0 & ISAPNP_MEM_CONTROL_LIMIT) 283 r->flags |= ISAPNP_MEMATTR_HIGH_ADDR; 284 if (v0 & ISAPNP_MEM_CONTROL_16) 285 r->flags |= ISAPNP_MEMWIDTH_16; 286 } 287 pa->ipa_nmem = i; 288 289 for (i = 0; i < sizeof(isapnp_irq_range); i++) { 290 v0 = isapnp_read_reg(sc, 291 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER); 292 p = &pa->ipa_irq[i]; 293 p->num = v0 & 0xf; 294 if (p->num == 0) 295 break; 296 297 switch (v0 & (ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH)) { 298 case ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH: 299 p->flags = ISAPNP_IRQTYPE_LEVEL_PLUS; 300 break; 301 case ISAPNP_IRQ_HIGH: 302 p->flags = ISAPNP_IRQTYPE_EDGE_PLUS; 303 break; 304 case ISAPNP_IRQ_LEVEL: 305 p->flags = ISAPNP_IRQTYPE_LEVEL_MINUS; 306 break; 307 default: 308 p->flags = ISAPNP_IRQTYPE_EDGE_MINUS; 309 break; 310 } 311 } 312 pa->ipa_nirq = i; 313 314 for (i = 0; i < sizeof(isapnp_drq_range); i++) { 315 v0 = isapnp_read_reg(sc, isapnp_drq_range[i]); 316 p = &pa->ipa_drq[i]; 317 p->num = v0 & 0xf; 318 if (p->num == 4) 319 break; 320 } 321 pa->ipa_ndrq = i; 322 323 for (i = 0; i < sizeof(isapnp_mem32_range); i++) { 324 r = &pa->ipa_mem32[i]; 325 v0 = isapnp_read_reg(sc, 326 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24); 327 v1 = isapnp_read_reg(sc, 328 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16); 329 v2 = isapnp_read_reg(sc, 330 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8); 331 v3 = isapnp_read_reg(sc, 332 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0); 333 r->base = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 334 if (r->base == 0) 335 break; 336 337 v0 = isapnp_read_reg(sc, 338 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24); 339 v1 = isapnp_read_reg(sc, 340 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16); 341 v2 = isapnp_read_reg(sc, 342 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8); 343 v3 = isapnp_read_reg(sc, 344 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0); 345 r->length = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 346 v0 = isapnp_read_reg(sc, 347 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 348 r->flags = v0; 349 } 350 pa->ipa_nmem32 = i; 351 } 352 353 354 /* isapnp_print_config(): 355 * Print the current configuration of the card 356 */ 357 void 358 isapnp_print_config(const struct isa_attach_args *pa) 359 { 360 int i; 361 const struct isapnp_region *r; 362 const struct isapnp_pin *p; 363 364 printf("Register configuration:\n"); 365 if (pa->ipa_nio) 366 for (i = 0; i < pa->ipa_nio; i++) { 367 r = &pa->ipa_io[i]; 368 printf("io[%d]: 0x%x/%d\n", i, r->base, r->length); 369 } 370 371 if (pa->ipa_nmem) 372 for (i = 0; i < pa->ipa_nmem; i++) { 373 r = &pa->ipa_mem[i]; 374 printf("mem[%d]: 0x%x/%d\n", i, r->base, r->length); 375 } 376 377 if (pa->ipa_nirq) 378 for (i = 0; i < pa->ipa_nirq; i++) { 379 p = &pa->ipa_irq[i]; 380 printf("irq[%d]: %d\n", i, p->num); 381 } 382 383 if (pa->ipa_ndrq) 384 for (i = 0; i < pa->ipa_ndrq; i++) { 385 p = &pa->ipa_drq[i]; 386 printf("drq[%d]: %d\n", i, p->num); 387 } 388 389 if (pa->ipa_nmem32) 390 for (i = 0; i < pa->ipa_nmem32; i++) { 391 r = &pa->ipa_mem32[i]; 392 printf("mem32[%d]: 0x%x/%d\n", i, r->base, r->length); 393 } 394 } 395 396 #endif 397