1 /* $OpenBSD: isapnpdebug.c,v 1.3 2002/12/15 13:17:04 henning 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(str, mem) 50 const char *str; 51 const struct isapnp_region *mem; 52 { 53 printf("%sMemory: %s,%sshadowable,decode-%s,%scacheable,%s", str, 54 (mem->flags & ISAPNP_MEMATTR_ROM) ? "ROM," : "RAM,", 55 (mem->flags & ISAPNP_MEMATTR_SHADOWABLE) ? "" : "non-", 56 (mem->flags & ISAPNP_MEMATTR_HIGH_ADDR) ? 57 "high-addr," : "range-len,", 58 (mem->flags & ISAPNP_MEMATTR_CACHEABLE) ? "" : "non-", 59 (mem->flags & ISAPNP_MEMATTR_WRITEABLE) ? 60 "writable," : "read-only,"); 61 62 switch (mem->flags & ISAPNP_MEMWIDTH_MASK) { 63 case ISAPNP_MEMWIDTH_8: 64 printf("8-bit "); 65 break; 66 case ISAPNP_MEMWIDTH_16: 67 printf("16-bit "); 68 break; 69 case ISAPNP_MEMWIDTH_8_16: 70 printf("8/16-bit "); 71 break; 72 case ISAPNP_MEMWIDTH_32: 73 printf("32-bit "); 74 break; 75 } 76 77 printf("min 0x%x, max 0x%x, ", mem->minbase, mem->maxbase); 78 printf("align 0x%x, length 0x%x\n", mem->align, mem->length); 79 } 80 81 82 /* isapnp_print_io(): 83 * Print an io tag 84 */ 85 void 86 isapnp_print_io(str, io) 87 const char *str; 88 const struct isapnp_region *io; 89 { 90 printf("%d %sIO Ports: %d address bits, alignment %d ", 91 io->length, str, (io->flags & ISAPNP_IOFLAGS_16) ? 16 : 10, 92 io->align); 93 94 printf("min 0x%x, max 0x%x\n", io->minbase, io->maxbase); 95 } 96 97 98 /* isapnp_print_irq(): 99 * Print an irq tag 100 */ 101 void 102 isapnp_print_irq(str, irq) 103 const char *str; 104 const struct isapnp_pin *irq; 105 { 106 int i; 107 108 printf("%sIRQ's supported: ", str); 109 for (i = 0; i < 16; i++) 110 if (irq->bits & (1 << i)) 111 printf("%d ", i); 112 113 if (irq->flags & ISAPNP_IRQTYPE_EDGE_PLUS) 114 printf("E+"); 115 if (irq->flags & ISAPNP_IRQTYPE_EDGE_MINUS) 116 printf("E-"); 117 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_PLUS) 118 printf("L+"); 119 if (irq->flags & ISAPNP_IRQTYPE_LEVEL_MINUS) 120 printf("L-"); 121 printf("\n"); 122 } 123 124 /* isapnp_print_drq(): 125 * Print a drq tag 126 */ 127 void 128 isapnp_print_drq(str, drq) 129 const char *str; 130 const struct isapnp_pin *drq; 131 { 132 int i; 133 u_char flags = drq->flags; 134 135 printf("%sDRQ's supported: ", str); 136 for (i = 0; i < 8; i++) 137 if (drq->bits & (1 << i)) 138 printf("%d ", i); 139 140 printf("Width: "); 141 switch (flags & ISAPNP_DMAWIDTH_MASK) { 142 case ISAPNP_DMAWIDTH_8: 143 printf("8-bit "); 144 break; 145 case ISAPNP_DMAWIDTH_8_16: 146 printf("8/16-bit "); 147 break; 148 case ISAPNP_DMAWIDTH_16: 149 printf("16-bit "); 150 break; 151 case ISAPNP_DMAWIDTH_RESERVED: 152 printf("Reserved "); 153 break; 154 } 155 156 printf("Speed: "); 157 switch (flags & ISAPNP_DMASPEED_MASK) { 158 case ISAPNP_DMASPEED_COMPAT: 159 printf("compat "); 160 break; 161 case ISAPNP_DMASPEED_A: 162 printf("A "); 163 break; 164 case ISAPNP_DMASPEED_B: 165 printf("B "); 166 break; 167 case ISAPNP_DMASPEED_F: 168 printf("F "); 169 break; 170 } 171 172 if (flags & ISAPNP_DMAATTR_MASK) 173 printf("Attributes: %s%s%s", 174 (flags & ISAPNP_DMAATTR_BUS_MASTER) ? "bus master " : "", 175 (flags & ISAPNP_DMAATTR_INCR_8) ? "incr 8 " : "", 176 (flags & ISAPNP_DMAATTR_INCR_16) ? "incr 16 " : ""); 177 printf("\n"); 178 } 179 180 181 /* isapnp_print_dep_start(): 182 * Print a start dependencies tag 183 */ 184 void 185 isapnp_print_dep_start(str, pref) 186 const char *str; 187 const u_char pref; 188 { 189 190 printf("%sconfig: ", str); 191 switch (pref) { 192 case ISAPNP_DEP_PREFERRED: 193 printf("preferred\n"); 194 break; 195 196 case ISAPNP_DEP_ACCEPTABLE: 197 printf("acceptable\n"); 198 break; 199 200 case ISAPNP_DEP_FUNCTIONAL: 201 printf("functional\n"); 202 break; 203 204 case ISAPNP_DEP_UNSET: /* Used internally */ 205 printf("unset\n"); 206 break; 207 208 case ISAPNP_DEP_CONFLICTING: /* Used internally */ 209 printf("conflicting\n"); 210 break; 211 212 default: 213 printf("invalid\n"); 214 break; 215 } 216 } 217 218 void 219 isapnp_print_attach(pa) 220 const struct isa_attach_args *pa; 221 { 222 int i; 223 224 printf("Found <%s, %s, %s, %s> ", pa->ipa_devident, 225 pa->ipa_devlogic, pa->ipa_devcompat, pa->ipa_devclass); 226 isapnp_print_dep_start("", pa->ipa_pref); 227 228 for (i = 0; i < pa->ipa_nio; i++) 229 isapnp_print_io("", &pa->ipa_io[i]); 230 231 for (i = 0; i < pa->ipa_nmem; i++) 232 isapnp_print_mem("", &pa->ipa_mem[i]); 233 234 for (i = 0; i < pa->ipa_nirq; i++) 235 isapnp_print_irq("", &pa->ipa_irq[i]); 236 237 for (i = 0; i < pa->ipa_ndrq; i++) 238 isapnp_print_drq("", &pa->ipa_drq[i]); 239 240 for (i = 0; i < pa->ipa_nmem32; i++) 241 isapnp_print_mem("", &pa->ipa_mem32[i]); 242 } 243 244 245 /* isapnp_get_config(): 246 * Get the current configuration of the card 247 */ 248 void 249 isapnp_get_config(sc, pa) 250 struct isapnp_softc *sc; 251 struct isa_attach_args *pa; 252 { 253 int i; 254 u_char v0, v1, v2, v3; 255 static u_char isapnp_mem_range[] = ISAPNP_MEM_DESC; 256 static u_char isapnp_io_range[] = ISAPNP_IO_DESC; 257 static u_char isapnp_irq_range[] = ISAPNP_IRQ_DESC; 258 static u_char isapnp_drq_range[] = ISAPNP_DRQ_DESC; 259 static u_char isapnp_mem32_range[] = ISAPNP_MEM32_DESC; 260 struct isapnp_region *r; 261 struct isapnp_pin *p; 262 263 bzero(pa, sizeof(*pa)); 264 265 for (i = 0; i < sizeof(isapnp_io_range); i++) { 266 r = &pa->ipa_io[i]; 267 v0 = isapnp_read_reg(sc, 268 isapnp_io_range[i] + ISAPNP_IO_BASE_15_8); 269 v1 = isapnp_read_reg(sc, 270 isapnp_io_range[i] + ISAPNP_IO_BASE_7_0); 271 r->base = (v0 << 8) | v1; 272 if (r->base == 0) 273 break; 274 } 275 pa->ipa_nio = i; 276 277 for (i = 0; i < sizeof(isapnp_mem_range); i++) { 278 r = &pa->ipa_mem[i]; 279 v0 = isapnp_read_reg(sc, 280 isapnp_mem_range[i] + ISAPNP_MEM_BASE_23_16); 281 v1 = isapnp_read_reg(sc, 282 isapnp_mem_range[i] + ISAPNP_MEM_BASE_15_8); 283 r->base = (v0 << 16) | (v1 << 8); 284 if (r->base == 0) 285 break; 286 287 v0 = isapnp_read_reg(sc, 288 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_23_16); 289 v1 = isapnp_read_reg(sc, 290 isapnp_mem_range[i] + ISAPNP_MEM_LRANGE_15_8); 291 r->length = (v0 << 16) | (v1 << 8); 292 v0 = isapnp_read_reg(sc, 293 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 294 r->flags = 0; 295 if (v0 & ISAPNP_MEM_CONTROL_LIMIT) 296 r->flags |= ISAPNP_MEMATTR_HIGH_ADDR; 297 if (v0 & ISAPNP_MEM_CONTROL_16) 298 r->flags |= ISAPNP_MEMWIDTH_16; 299 } 300 pa->ipa_nmem = i; 301 302 for (i = 0; i < sizeof(isapnp_irq_range); i++) { 303 v0 = isapnp_read_reg(sc, 304 isapnp_irq_range[i] + ISAPNP_IRQ_NUMBER); 305 p = &pa->ipa_irq[i]; 306 p->num = v0 & 0xf; 307 if (p->num == 0) 308 break; 309 310 switch (v0 & (ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH)) { 311 case ISAPNP_IRQ_LEVEL|ISAPNP_IRQ_HIGH: 312 p->flags = ISAPNP_IRQTYPE_LEVEL_PLUS; 313 break; 314 case ISAPNP_IRQ_HIGH: 315 p->flags = ISAPNP_IRQTYPE_EDGE_PLUS; 316 break; 317 case ISAPNP_IRQ_LEVEL: 318 p->flags = ISAPNP_IRQTYPE_LEVEL_MINUS; 319 break; 320 default: 321 p->flags = ISAPNP_IRQTYPE_EDGE_MINUS; 322 break; 323 } 324 } 325 pa->ipa_nirq = i; 326 327 for (i = 0; i < sizeof(isapnp_drq_range); i++) { 328 v0 = isapnp_read_reg(sc, isapnp_drq_range[i]); 329 p = &pa->ipa_drq[i]; 330 p->num = v0 & 0xf; 331 if (p->num == 4) 332 break; 333 } 334 pa->ipa_ndrq = i; 335 336 for (i = 0; i < sizeof(isapnp_mem32_range); i++) { 337 r = &pa->ipa_mem32[i]; 338 v0 = isapnp_read_reg(sc, 339 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_31_24); 340 v1 = isapnp_read_reg(sc, 341 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_23_16); 342 v2 = isapnp_read_reg(sc, 343 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_15_8); 344 v3 = isapnp_read_reg(sc, 345 isapnp_mem32_range[i] + ISAPNP_MEM32_BASE_7_0); 346 r->base = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 347 if (r->base == 0) 348 break; 349 350 v0 = isapnp_read_reg(sc, 351 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_31_24); 352 v1 = isapnp_read_reg(sc, 353 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_23_16); 354 v2 = isapnp_read_reg(sc, 355 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_15_8); 356 v3 = isapnp_read_reg(sc, 357 isapnp_mem32_range[i] + ISAPNP_MEM32_LRANGE_7_0); 358 r->length = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3; 359 v0 = isapnp_read_reg(sc, 360 isapnp_mem_range[i] + ISAPNP_MEM_CONTROL); 361 r->flags = v0; 362 } 363 pa->ipa_nmem32 = i; 364 } 365 366 367 /* isapnp_print_config(): 368 * Print the current configuration of the card 369 */ 370 void 371 isapnp_print_config(pa) 372 const struct isa_attach_args *pa; 373 { 374 int i; 375 const struct isapnp_region *r; 376 const struct isapnp_pin *p; 377 378 printf("Register configuration:\n"); 379 if (pa->ipa_nio) 380 for (i = 0; i < pa->ipa_nio; i++) { 381 r = &pa->ipa_io[i]; 382 printf("io[%d]: 0x%x/%d\n", i, r->base, r->length); 383 } 384 385 if (pa->ipa_nmem) 386 for (i = 0; i < pa->ipa_nmem; i++) { 387 r = &pa->ipa_mem[i]; 388 printf("mem[%d]: 0x%x/%d\n", i, r->base, r->length); 389 } 390 391 if (pa->ipa_nirq) 392 for (i = 0; i < pa->ipa_nirq; i++) { 393 p = &pa->ipa_irq[i]; 394 printf("irq[%d]: %d\n", i, p->num); 395 } 396 397 if (pa->ipa_ndrq) 398 for (i = 0; i < pa->ipa_ndrq; i++) { 399 p = &pa->ipa_drq[i]; 400 printf("drq[%d]: %d\n", i, p->num); 401 } 402 403 if (pa->ipa_nmem32) 404 for (i = 0; i < pa->ipa_nmem32; i++) { 405 r = &pa->ipa_mem32[i]; 406 printf("mem32[%d]: 0x%x/%d\n", i, r->base, r->length); 407 } 408 } 409 410 #endif 411