xref: /openbsd/sys/dev/isa/isapnpdebug.c (revision f790b53d)
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
isapnp_print_mem(const char * str,const struct isapnp_region * mem)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
isapnp_print_io(const char * str,const struct isapnp_region * io)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
isapnp_print_irq(const char * str,const struct isapnp_pin * irq)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
isapnp_print_drq(const char * str,const struct isapnp_pin * drq)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
isapnp_print_dep_start(const char * str,const u_char pref)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
isapnp_print_attach(const struct isa_attach_args * pa)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
isapnp_get_config(struct isapnp_softc * sc,struct isa_attach_args * pa)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
isapnp_print_config(const struct isa_attach_args * pa)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