xref: /openbsd/sys/dev/isa/isapnpdebug.c (revision 0ee6d9ec)
1 /*	$OpenBSD: isapnpdebug.c,v 1.2 1997/12/25 09:22:40 downsj 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 		"writeable," : "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