1 /*-
2 * Copyright (c) 2000,2001 Jonathan Chen.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 /*
31 * CIS Handling for the Cardbus Bus
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38
39 #include <sys/bus.h>
40 #include <machine/bus.h>
41 #include <machine/resource.h>
42 #include <sys/rman.h>
43 #include <sys/endian.h>
44
45 #include <sys/pciio.h>
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcireg.h>
48
49 #include <dev/pccard/pccardvar.h>
50 #include <dev/pccard/pccard_cis.h>
51
52 #include <dev/cardbus/cardbusreg.h>
53 #include <dev/cardbus/cardbusvar.h>
54 #include <dev/cardbus/cardbus_cis.h>
55
56 extern int cardbus_cis_debug;
57
58 #define DPRINTF(a) if (cardbus_cis_debug) printf a
59 #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x
60
61 struct tuple_callbacks;
62
63 typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len,
64 uint8_t *tupledata, uint32_t start, uint32_t *off,
65 struct tuple_callbacks *info);
66
67 struct tuple_callbacks {
68 int id;
69 char *name;
70 tuple_cb *func;
71 };
72
73 static int decode_tuple_generic(device_t cbdev, device_t child, int id,
74 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
75 struct tuple_callbacks *info);
76 static int decode_tuple_linktarget(device_t cbdev, device_t child, int id,
77 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
78 struct tuple_callbacks *info);
79 static int decode_tuple_vers_1(device_t cbdev, device_t child, int id,
80 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
81 struct tuple_callbacks *info);
82 static int decode_tuple_funcid(device_t cbdev, device_t child, int id,
83 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
84 struct tuple_callbacks *info);
85 static int decode_tuple_manfid(device_t cbdev, device_t child, int id,
86 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
87 struct tuple_callbacks *info);
88 static int decode_tuple_funce(device_t cbdev, device_t child, int id,
89 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
90 struct tuple_callbacks *info);
91 static int decode_tuple_bar(device_t cbdev, device_t child, int id,
92 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
93 struct tuple_callbacks *info);
94 static int decode_tuple_unhandled(device_t cbdev, device_t child, int id,
95 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
96 struct tuple_callbacks *info);
97 static int decode_tuple_end(device_t cbdev, device_t child, int id,
98 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
99 struct tuple_callbacks *info);
100
101 static int cardbus_read_tuple_conf(device_t cbdev, device_t child,
102 uint32_t start, uint32_t *off, int *tupleid, int *len,
103 uint8_t *tupledata);
104 static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res,
105 uint32_t start, uint32_t *off, int *tupleid, int *len,
106 uint8_t *tupledata);
107 static int cardbus_read_tuple(device_t cbdev, device_t child,
108 struct resource *res, uint32_t start, uint32_t *off,
109 int *tupleid, int *len, uint8_t *tupledata);
110 static void cardbus_read_tuple_finish(device_t cbdev, device_t child,
111 int rid, struct resource *res);
112 static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child,
113 uint32_t *start, int *rid);
114 static int decode_tuple(device_t cbdev, device_t child, int tupleid,
115 int len, uint8_t *tupledata, uint32_t start,
116 uint32_t *off, struct tuple_callbacks *callbacks);
117 static int cardbus_parse_cis(device_t cbdev, device_t child,
118 struct tuple_callbacks *callbacks);
119 static int barsort(const void *a, const void *b);
120 static int cardbus_alloc_resources(device_t cbdev, device_t child);
121 static void cardbus_add_map(device_t cbdev, device_t child, int reg);
122 static void cardbus_pickup_maps(device_t cbdev, device_t child);
123
124
125 #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC }
126
127 static char *funcnames[] = {
128 "Multi-Functioned",
129 "Memory",
130 "Serial Port",
131 "Parallel Port",
132 "Fixed Disk",
133 "Video Adaptor",
134 "Network Adaptor",
135 "AIMS",
136 "SCSI",
137 "Security"
138 };
139
140 /*
141 * Handler functions for various CIS tuples
142 */
143
144 static int
145 decode_tuple_generic(device_t cbdev, device_t child, int id,
146 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
147 struct tuple_callbacks *info)
148 {
149 int i;
150
151 if (cardbus_cis_debug) {
152 if (info)
153 printf("TUPLE: %s [%d]:", info->name, len);
154 else
155 printf("TUPLE: Unknown(0x%02x) [%d]:", id, len);
156
157 for (i = 0; i < len; i++) {
158 if (i % 0x10 == 0 && len > 0x10)
159 printf("\n 0x%02x:", i);
160 printf(" %02x", tupledata[i]);
161 }
162 printf("\n");
163 }
164 return (0);
165 }
166
167 static int
168 decode_tuple_linktarget(device_t cbdev, device_t child, int id,
169 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
170 struct tuple_callbacks *info)
171 {
172 int i;
173
174 if (cardbus_cis_debug) {
175 printf("TUPLE: %s [%d]:", info->name, len);
176
177 for (i = 0; i < len; i++) {
178 if (i % 0x10 == 0 && len > 0x10)
179 printf("\n 0x%02x:", i);
180 printf(" %02x", tupledata[i]);
181 }
182 printf("\n");
183 }
184 if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' ||
185 tupledata[2] != 'S') {
186 printf("Invalid data for CIS Link Target!\n");
187 decode_tuple_generic(cbdev, child, id, len, tupledata,
188 start, off, info);
189 return (EINVAL);
190 }
191 return (0);
192 }
193
194 static int
195 decode_tuple_vers_1(device_t cbdev, device_t child, int id,
196 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
197 struct tuple_callbacks *info)
198 {
199 int i;
200
201 if (cardbus_cis_debug) {
202 printf("Product version: %d.%d\n", tupledata[0], tupledata[1]);
203 printf("Product name: ");
204 for (i = 2; i < len; i++) {
205 if (tupledata[i] == '\0')
206 printf(" | ");
207 else if (tupledata[i] == 0xff)
208 break;
209 else
210 printf("%c", tupledata[i]);
211 }
212 printf("\n");
213 }
214 return (0);
215 }
216
217 static int
218 decode_tuple_funcid(device_t cbdev, device_t child, int id,
219 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
220 struct tuple_callbacks *info)
221 {
222 struct cardbus_devinfo *dinfo = device_get_ivars(child);
223 int numnames = sizeof(funcnames) / sizeof(funcnames[0]);
224 int i;
225
226 if (cardbus_cis_debug) {
227 printf("Functions: ");
228 for (i = 0; i < len; i++) {
229 if (tupledata[i] < numnames)
230 printf("%s", funcnames[tupledata[i]]);
231 else
232 printf("Unknown(%d)", tupledata[i]);
233 if (i < len-1)
234 printf(", ");
235 }
236 printf("\n");
237 }
238 if (len > 0)
239 dinfo->funcid = tupledata[0]; /* use first in list */
240 return (0);
241 }
242
243 static int
244 decode_tuple_manfid(device_t cbdev, device_t child, int id,
245 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
246 struct tuple_callbacks *info)
247 {
248 struct cardbus_devinfo *dinfo = device_get_ivars(child);
249 int i;
250
251 if (cardbus_cis_debug) {
252 printf("Manufacturer ID: ");
253 for (i = 0; i < len; i++)
254 printf("%02x", tupledata[i]);
255 printf("\n");
256 }
257
258 if (len == 5) {
259 dinfo->mfrid = tupledata[1] | (tupledata[2] << 8);
260 dinfo->prodid = tupledata[3] | (tupledata[4] << 8);
261 }
262 return (0);
263 }
264
265 static int
266 decode_tuple_funce(device_t cbdev, device_t child, int id,
267 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
268 struct tuple_callbacks *info)
269 {
270 struct cardbus_devinfo *dinfo = device_get_ivars(child);
271 int type, i;
272
273 if (cardbus_cis_debug) {
274 printf("Function Extension: ");
275 for (i = 0; i < len; i++)
276 printf("%02x", tupledata[i]);
277 printf("\n");
278 }
279 if (len < 2) /* too short */
280 return (0);
281 type = tupledata[0]; /* XXX <32 always? */
282 switch (dinfo->funcid) {
283 case TPL_FUNC_SERIAL:
284 if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */
285 dinfo->funce.sio.type = tupledata[1] & 0x1f;
286 }
287 dinfo->fepresent |= 1<<type;
288 break;
289 case TPL_FUNC_LAN:
290 switch (type) {
291 case TPL_FUNCE_LAN_TECH:
292 dinfo->funce.lan.tech = tupledata[1]; /* XXX mask? */
293 break;
294 #if 0
295 case TPL_FUNCE_LAN_SPEED:
296 for (i = 0; i < 3; i++) {
297 if (dinfo->funce.lan.speed[i] == 0) {
298 if (len > 4) {
299 dinfo->funce.lan.speed[i] =
300 ...;
301 }
302 break;
303 }
304 }
305 break;
306 #endif
307 case TPL_FUNCE_LAN_MEDIA:
308 for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) {
309 if (dinfo->funce.lan.media[i] == 0) {
310 /* NB: len known > 1 */
311 dinfo->funce.lan.media[i] =
312 tupledata[1]; /*XXX? mask */
313 break;
314 }
315 }
316 break;
317 case TPL_FUNCE_LAN_NID:
318 if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) {
319 /* ignore, warning? */
320 return (0);
321 }
322 bcopy(tupledata + 2, dinfo->funce.lan.nid,
323 tupledata[1]);
324 break;
325 case TPL_FUNCE_LAN_CONN:
326 dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */
327 break;
328 }
329 dinfo->fepresent |= 1<<type;
330 break;
331 }
332 return (0);
333 }
334
335 static int
336 decode_tuple_bar(device_t cbdev, device_t child, int id,
337 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
338 struct tuple_callbacks *info)
339 {
340 struct cardbus_devinfo *dinfo = device_get_ivars(child);
341 int type;
342 uint8_t reg;
343 uint32_t bar, pci_bar;
344
345 if (len != 6) {
346 device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len);
347 return (EINVAL);
348 }
349
350 reg = *tupledata;
351 len = le32toh(*(uint32_t*)(tupledata + 2));
352 if (reg & TPL_BAR_REG_AS) {
353 type = SYS_RES_IOPORT;
354 } else {
355 type = SYS_RES_MEMORY;
356 }
357
358 bar = reg & TPL_BAR_REG_ASI_MASK;
359 if (bar == 0) {
360 device_printf(cbdev, "Invalid BAR type 0 in CIS\n");
361 return (EINVAL); /* XXX Return an error? */
362 } else if (bar == 7) {
363 /* XXX Should we try to map in Option ROMs? */
364 return (0);
365 }
366
367 /* Convert from BAR type to BAR offset */
368 bar = CARDBUS_BASE0_REG + (bar - 1) * 4;
369
370 if (type == SYS_RES_MEMORY) {
371 if (reg & TPL_BAR_REG_PREFETCHABLE)
372 dinfo->mprefetchable |= BARBIT(bar);
373 #if 0
374 /*
375 * XXX: It appears from a careful reading of the spec
376 * that we're not supposed to honor this when the bridge
377 * is not on the main system bus. PCI spec doesn't appear
378 * to allow for memory ranges not listed in the bridge's
379 * decode range to be decoded. The PC Card spec seems to
380 * indicate that this should only be done on x86 based
381 * machines, which seems to imply that on non-x86 machines
382 * the adddresses can be anywhere. This further implies that
383 * since the hardware can do it on non-x86 machines, it should
384 * be able to do it on x86 machines. Therefore, we can and
385 * should ignore this hint. Furthermore, the PC Card spec
386 * recommends always allocating memory above 1MB, contradicting
387 * the other part of the PC Card spec.
388 *
389 * NetBSD ignores this bit, but it also ignores the
390 * prefetchable bit too, so that's not an indication of
391 * correctness.
392 */
393 if (reg & TPL_BAR_REG_BELOW1MB)
394 dinfo->mbelow1mb |= BARBIT(bar);
395 #endif
396 }
397
398 /*
399 * Sanity check the BAR length reported in the CIS with the length
400 * encoded in the PCI BAR. The latter seems to be more reliable.
401 * XXX - This probably belongs elsewhere.
402 */
403 pci_write_config(child, bar, 0xffffffff, 4);
404 pci_bar = pci_read_config(child, bar, 4);
405 if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) {
406 if (type == SYS_RES_MEMORY) {
407 pci_bar &= ~0xf;
408 } else {
409 pci_bar &= ~0x3;
410 }
411 len = 1 << (ffs(pci_bar) - 1);
412 }
413
414 DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n",
415 (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len,
416 (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ?
417 " (Prefetchable)" : "", type == SYS_RES_MEMORY ?
418 ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : ""));
419
420 resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
421
422 /*
423 * Mark the appropriate bit in the PCI command register so that
424 * device drivers will know which type of BARs can be used.
425 */
426 pci_enable_io(child, type);
427 return (0);
428 }
429
430 static int
431 decode_tuple_unhandled(device_t cbdev, device_t child, int id,
432 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
433 struct tuple_callbacks *info)
434 {
435 /* Make this message suck less XXX */
436 printf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len);
437 return (-1);
438 }
439
440 static int
441 decode_tuple_end(device_t cbdev, device_t child, int id,
442 int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
443 struct tuple_callbacks *info)
444 {
445 if (cardbus_cis_debug) {
446 printf("CIS reading done\n");
447 }
448 return (0);
449 }
450
451 /*
452 * Functions to read the a tuple from the card
453 */
454
455 static int
456 cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start,
457 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
458 {
459 int i, j;
460 uint32_t e;
461 uint32_t loc;
462
463 loc = start + *off;
464
465 e = pci_read_config(child, loc - loc % 4, 4);
466 for (j = loc % 4; j > 0; j--)
467 e >>= 8;
468 *len = 0;
469 for (i = loc, j = -2; j < *len; j++, i++) {
470 if (i % 4 == 0)
471 e = pci_read_config(child, i, 4);
472 if (j == -2)
473 *tupleid = 0xff & e;
474 else if (j == -1)
475 *len = 0xff & e;
476 else
477 tupledata[j] = 0xff & e;
478 e >>= 8;
479 }
480 *off += *len + 2;
481 return (0);
482 }
483
484 static int
485 cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start,
486 uint32_t *off, int *tupleid, int *len, uint8_t *tupledata)
487 {
488 bus_space_tag_t bt;
489 bus_space_handle_t bh;
490 int ret;
491
492 bt = rman_get_bustag(res);
493 bh = rman_get_bushandle(res);
494
495 *tupleid = bus_space_read_1(bt, bh, start + *off);
496 *len = bus_space_read_1(bt, bh, start + *off + 1);
497 bus_space_read_region_1(bt, bh, *off + start + 2, tupledata, *len);
498 ret = 0;
499 *off += *len + 2;
500 return (ret);
501 }
502
503 static int
504 cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res,
505 uint32_t start, uint32_t *off, int *tupleid, int *len,
506 uint8_t *tupledata)
507 {
508 if (res == (struct resource*)~0UL) {
509 return (cardbus_read_tuple_conf(cbdev, child, start, off,
510 tupleid, len, tupledata));
511 } else {
512 return (cardbus_read_tuple_mem(cbdev, res, start, off,
513 tupleid, len, tupledata));
514 }
515 }
516
517 static void
518 cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid,
519 struct resource *res)
520 {
521 if (res != (struct resource*)~0UL) {
522 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
523 pci_write_config(child, rid, 0, 4);
524 PCI_DISABLE_IO(cbdev, child, SYS_RES_MEMORY);
525 }
526 }
527
528 static struct resource *
529 cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start,
530 int *rid)
531 {
532 uint32_t testval;
533 uint32_t size;
534 struct resource *res;
535
536 switch (CARDBUS_CIS_SPACE(*start)) {
537 case CARDBUS_CIS_ASI_TUPLE:
538 /* CIS in PCI config space need no initialization */
539 return ((struct resource*)~0UL);
540 case CARDBUS_CIS_ASI_BAR0:
541 case CARDBUS_CIS_ASI_BAR1:
542 case CARDBUS_CIS_ASI_BAR2:
543 case CARDBUS_CIS_ASI_BAR3:
544 case CARDBUS_CIS_ASI_BAR4:
545 case CARDBUS_CIS_ASI_BAR5:
546 *rid = CARDBUS_BASE0_REG + (CARDBUS_CIS_SPACE(*start) - 1) * 4;
547 break;
548 case CARDBUS_CIS_ASI_ROM:
549 *rid = CARDBUS_ROM_REG;
550 #if 0
551 /*
552 * This mask doesn't contain the bit that actually enables
553 * the Option ROM.
554 */
555 pci_write_config(child, *rid, CARDBUS_ROM_ADDRMASK, 4);
556 #endif
557 break;
558 default:
559 device_printf(cbdev, "Unable to read CIS: Unknown space: %d\n",
560 CARDBUS_CIS_SPACE(*start));
561 return (NULL);
562 }
563
564 /* figure out how much space we need */
565 pci_write_config(child, *rid, 0xffffffff, 4);
566 testval = pci_read_config(child, *rid, 4);
567
568 /*
569 * This bit has a different meaning depending if we are dealing
570 * with a normal BAR or an Option ROM BAR.
571 */
572 if (((testval & 0x1) == 0x1) && (*rid != CARDBUS_ROM_REG)) {
573 device_printf(cbdev, "CIS Space is IO, expecting memory.\n");
574 return (NULL);
575 }
576
577 size = CARDBUS_MAPREG_MEM_SIZE(testval);
578 /* XXX Is this some kind of hack? */
579 if (size < 4096)
580 size = 4096;
581 /* allocate the memory space to read CIS */
582 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, rid, 0, ~0, size,
583 rman_make_alignment_flags(size) | RF_ACTIVE);
584 if (res == NULL) {
585 device_printf(cbdev, "Unable to allocate resource "
586 "to read CIS.\n");
587 return (NULL);
588 }
589 pci_write_config(child, *rid,
590 rman_get_start(res) | ((*rid == CARDBUS_ROM_REG)?
591 CARDBUS_ROM_ENABLE : 0),
592 4);
593 PCI_ENABLE_IO(cbdev, child, SYS_RES_MEMORY);
594
595 /* Flip to the right ROM image if CIS is in ROM */
596 if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) {
597 bus_space_tag_t bt;
598 bus_space_handle_t bh;
599 uint32_t imagesize;
600 uint32_t imagebase = 0;
601 uint32_t pcidata;
602 uint16_t romsig;
603 int romnum = 0;
604 int imagenum;
605
606 bt = rman_get_bustag(res);
607 bh = rman_get_bushandle(res);
608
609 imagenum = CARDBUS_CIS_ASI_ROM_IMAGE(*start);
610 for (romnum = 0;; romnum++) {
611 romsig = bus_space_read_2(bt, bh,
612 imagebase + CARDBUS_EXROM_SIGNATURE);
613 if (romsig != 0xaa55) {
614 device_printf(cbdev, "Bad header in rom %d: "
615 "[%x] %04x\n", romnum, imagebase +
616 CARDBUS_EXROM_SIGNATURE, romsig);
617 bus_release_resource(cbdev, SYS_RES_MEMORY,
618 *rid, res);
619 *rid = 0;
620 return (NULL);
621 }
622
623 /*
624 * If this was the Option ROM image that we were
625 * looking for, then we are done.
626 */
627 if (romnum == imagenum)
628 break;
629
630 /* Find out where the next Option ROM image is */
631 pcidata = imagebase + bus_space_read_2(bt, bh,
632 imagebase + CARDBUS_EXROM_DATA_PTR);
633 imagesize = bus_space_read_2(bt, bh,
634 pcidata + CARDBUS_EXROM_DATA_IMAGE_LENGTH);
635
636 if (imagesize == 0) {
637 /*
638 * XXX some ROMs seem to have this as zero,
639 * can we assume this means 1 block?
640 */
641 device_printf(cbdev, "Warning, size of Option "
642 "ROM image %d is 0 bytes, assuming 512 "
643 "bytes.\n", romnum);
644 imagesize = 1;
645 }
646
647 /* Image size is in 512 byte units */
648 imagesize <<= 9;
649
650 if ((bus_space_read_1(bt, bh, pcidata +
651 CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) {
652 device_printf(cbdev, "Cannot find CIS in "
653 "Option ROM\n");
654 bus_release_resource(cbdev, SYS_RES_MEMORY,
655 *rid, res);
656 *rid = 0;
657 return (NULL);
658 }
659 imagebase += imagesize;
660 }
661 *start = imagebase + CARDBUS_CIS_ADDR(*start);
662 } else {
663 *start = CARDBUS_CIS_ADDR(*start);
664 }
665
666 return (res);
667 }
668
669 /*
670 * Dispatch the right handler function per tuple
671 */
672
673 static int
674 decode_tuple(device_t cbdev, device_t child, int tupleid, int len,
675 uint8_t *tupledata, uint32_t start, uint32_t *off,
676 struct tuple_callbacks *callbacks)
677 {
678 int i;
679 for (i = 0; callbacks[i].id != CISTPL_GENERIC; i++) {
680 if (tupleid == callbacks[i].id)
681 return (callbacks[i].func(cbdev, child, tupleid, len,
682 tupledata, start, off, &callbacks[i]));
683 }
684 return (callbacks[i].func(cbdev, child, tupleid, len,
685 tupledata, start, off, NULL));
686 }
687
688 static int
689 cardbus_parse_cis(device_t cbdev, device_t child,
690 struct tuple_callbacks *callbacks)
691 {
692 uint8_t tupledata[MAXTUPLESIZE];
693 int tupleid;
694 int len;
695 int expect_linktarget;
696 uint32_t start, off;
697 struct resource *res;
698 int rid;
699
700 bzero(tupledata, MAXTUPLESIZE);
701 expect_linktarget = TRUE;
702 if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0)
703 return (ENXIO);
704 off = 0;
705 res = cardbus_read_tuple_init(cbdev, child, &start, &rid);
706 if (res == NULL)
707 return (ENXIO);
708
709 do {
710 if (0 != cardbus_read_tuple(cbdev, child, res, start, &off,
711 &tupleid, &len, tupledata)) {
712 device_printf(cbdev, "Failed to read CIS.\n");
713 cardbus_read_tuple_finish(cbdev, child, rid, res);
714 return (ENXIO);
715 }
716
717 if (expect_linktarget && tupleid != CISTPL_LINKTARGET) {
718 device_printf(cbdev, "Expecting link target, got 0x%x\n",
719 tupleid);
720 cardbus_read_tuple_finish(cbdev, child, rid, res);
721 return (EINVAL);
722 }
723 expect_linktarget = decode_tuple(cbdev, child, tupleid, len,
724 tupledata, start, &off, callbacks);
725 if (expect_linktarget != 0) {
726 cardbus_read_tuple_finish(cbdev, child, rid, res);
727 return (expect_linktarget);
728 }
729 } while (tupleid != CISTPL_END);
730 cardbus_read_tuple_finish(cbdev, child, rid, res);
731 return (0);
732 }
733
734 static void
735 cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start)
736 {
737 rle->start = start;
738 rle->end = start + rle->count - 1;
739 pci_write_config(child, rle->rid, rle->start, 4);
740 }
741
742 static int
743 barsort(const void *a, const void *b)
744 {
745 return ((*(const struct resource_list_entry * const *)b)->count -
746 (*(const struct resource_list_entry * const *)a)->count);
747 }
748
749 static int
750 cardbus_alloc_resources(device_t cbdev, device_t child)
751 {
752 struct cardbus_devinfo *dinfo = device_get_ivars(child);
753 int count;
754 struct resource_list_entry *rle;
755 struct resource_list_entry **barlist;
756 int tmp;
757 uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0;
758 struct resource *res;
759 uint32_t start,end;
760 int rid, flags;
761
762 count = 0;
763 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
764 count++;
765 }
766 if (count == 0)
767 return (0);
768 barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
769 M_WAITOK);
770 count = 0;
771 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
772 barlist[count] = rle;
773 if (rle->type == SYS_RES_IOPORT) {
774 io_size += rle->count;
775 } else if (rle->type == SYS_RES_MEMORY) {
776 if (dinfo->mprefetchable & BARBIT(rle->rid))
777 mem_psize += rle->count;
778 else
779 mem_nsize += rle->count;
780 }
781 count++;
782 }
783
784 /*
785 * We want to allocate the largest resource first, so that our
786 * allocated memory is packed.
787 */
788 qsort(barlist, count, sizeof(struct resource_list_entry*), barsort);
789
790 /* Allocate prefetchable memory */
791 flags = 0;
792 for (tmp = 0; tmp < count; tmp++) {
793 rle = barlist[tmp];
794 if (rle->res == NULL &&
795 rle->type == SYS_RES_MEMORY &&
796 dinfo->mprefetchable & BARBIT(rle->rid)) {
797 flags = rman_make_alignment_flags(rle->count);
798 break;
799 }
800 }
801 if (flags > 0) { /* If any prefetchable memory is requested... */
802 /*
803 * First we allocate one big space for all resources of this
804 * type. We do this because our parent, pccbb, needs to open
805 * a window to forward all addresses within the window, and
806 * it would be best if nobody else has resources allocated
807 * within the window.
808 * (XXX: Perhaps there might be a better way to do this?)
809 */
810 rid = 0;
811 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
812 (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL,
813 mem_psize, flags);
814 if (res == NULL) {
815 device_printf(cbdev,
816 "Can't get memory for prefetch mem\n");
817 free(barlist, M_DEVBUF);
818 return (EIO);
819 }
820 start = rman_get_start(res);
821 end = rman_get_end(res);
822 DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end));
823 /*
824 * Now that we know the region is free, release it and hand it
825 * out piece by piece.
826 */
827 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
828 for (tmp = 0; tmp < count; tmp++) {
829 rle = barlist[tmp];
830 if (rle->type == SYS_RES_MEMORY &&
831 dinfo->mprefetchable & BARBIT(rle->rid)) {
832 cardbus_do_res(rle, child, start);
833 start += rle->count;
834 }
835 }
836 }
837
838 /* Allocate non-prefetchable memory */
839 flags = 0;
840 for (tmp = 0; tmp < count; tmp++) {
841 rle = barlist[tmp];
842 if (rle->type == SYS_RES_MEMORY &&
843 (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
844 flags = rman_make_alignment_flags(rle->count);
845 break;
846 }
847 }
848 if (flags > 0) { /* If any non-prefetchable memory is requested... */
849 /*
850 * First we allocate one big space for all resources of this
851 * type. We do this because our parent, pccbb, needs to open
852 * a window to forward all addresses within the window, and
853 * it would be best if nobody else has resources allocated
854 * within the window.
855 * (XXX: Perhaps there might be a better way to do this?)
856 */
857 rid = 0;
858 res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0,
859 ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL,
860 mem_nsize, flags);
861 if (res == NULL) {
862 device_printf(cbdev,
863 "Can't get memory for non-prefetch mem\n");
864 free(barlist, M_DEVBUF);
865 return (EIO);
866 }
867 start = rman_get_start(res);
868 end = rman_get_end(res);
869 DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n",
870 start, end));
871 /*
872 * Now that we know the region is free, release it and hand it
873 * out piece by piece.
874 */
875 bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res);
876 for (tmp = 0; tmp < count; tmp++) {
877 rle = barlist[tmp];
878 if (rle->type == SYS_RES_MEMORY &&
879 (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) {
880 cardbus_do_res(rle, child, start);
881 start += rle->count;
882 }
883 }
884 }
885
886 /* Allocate IO ports */
887 flags = 0;
888 for (tmp = 0; tmp < count; tmp++) {
889 rle = barlist[tmp];
890 if (rle->type == SYS_RES_IOPORT) {
891 flags = rman_make_alignment_flags(rle->count);
892 break;
893 }
894 }
895 if (flags > 0) { /* If any IO port is requested... */
896 /*
897 * First we allocate one big space for all resources of this
898 * type. We do this because our parent, pccbb, needs to open
899 * a window to forward all addresses within the window, and
900 * it would be best if nobody else has resources allocated
901 * within the window.
902 * (XXX: Perhaps there might be a better way to do this?)
903 */
904 rid = 0;
905 res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
906 (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
907 if (res == NULL) {
908 device_printf(cbdev,
909 "Can't get memory for IO ports\n");
910 free(barlist, M_DEVBUF);
911 return (EIO);
912 }
913 start = rman_get_start(res);
914 end = rman_get_end(res);
915 DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
916 /*
917 * Now that we know the region is free, release it and hand it
918 * out piece by piece.
919 */
920 bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
921 for (tmp = 0; tmp < count; tmp++) {
922 rle = barlist[tmp];
923 if (rle->type == SYS_RES_IOPORT) {
924 cardbus_do_res(rle, child, start);
925 start += rle->count;
926 }
927 }
928 }
929
930 /* Allocate IRQ */
931 rid = 0;
932 res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE);
933 if (res == NULL) {
934 device_printf(cbdev, "Can't get memory for irq\n");
935 free(barlist, M_DEVBUF);
936 return (EIO);
937 }
938 start = rman_get_start(res);
939 end = rman_get_end(res);
940 bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
941 resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end,
942 1);
943 dinfo->pci.cfg.intline = rman_get_start(res);
944 pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
945
946 free(barlist, M_DEVBUF);
947 return (0);
948 }
949
950 /*
951 * Adding a memory/io resource (sans CIS)
952 */
953
954 static void
955 cardbus_add_map(device_t cbdev, device_t child, int reg)
956 {
957 struct cardbus_devinfo *dinfo = device_get_ivars(child);
958 struct resource_list_entry *rle;
959 uint32_t size;
960 uint32_t testval;
961 int type;
962
963 SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
964 if (rle->rid == reg)
965 return;
966 }
967
968 if (reg == CARDBUS_ROM_REG)
969 testval = CARDBUS_ROM_ADDRMASK;
970 else
971 testval = ~0;
972
973 pci_write_config(child, reg, testval, 4);
974 testval = pci_read_config(child, reg, 4);
975
976 if (testval == ~0 || testval == 0)
977 return;
978
979 if ((testval & 1) == 0)
980 type = SYS_RES_MEMORY;
981 else
982 type = SYS_RES_IOPORT;
983
984 size = CARDBUS_MAPREG_MEM_SIZE(testval);
985 device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
986 reg, size);
987 resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
988 }
989
990 static void
991 cardbus_pickup_maps(device_t cbdev, device_t child)
992 {
993 struct cardbus_devinfo *dinfo = device_get_ivars(child);
994 int reg;
995
996 /*
997 * Try to pick up any resources that was not specified in CIS.
998 * Maybe this isn't any longer necessary now that we have fixed
999 * CIS parsing and we should filter things here? XXX
1000 */
1001 for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++)
1002 cardbus_add_map(cbdev, child, PCIR_BAR(reg));
1003 }
1004
1005 int
1006 cardbus_do_cis(device_t cbdev, device_t child)
1007 {
1008 int ret;
1009 struct tuple_callbacks init_callbacks[] = {
1010 MAKETUPLE(LONGLINK_CB, unhandled),
1011 MAKETUPLE(INDIRECT, unhandled),
1012 MAKETUPLE(LONGLINK_MFC, unhandled),
1013 MAKETUPLE(BAR, bar),
1014 MAKETUPLE(LONGLINK_A, unhandled),
1015 MAKETUPLE(LONGLINK_C, unhandled),
1016 MAKETUPLE(LINKTARGET, linktarget),
1017 MAKETUPLE(VERS_1, vers_1),
1018 MAKETUPLE(MANFID, manfid),
1019 MAKETUPLE(FUNCID, funcid),
1020 MAKETUPLE(FUNCE, funce),
1021 MAKETUPLE(END, end),
1022 MAKETUPLE(GENERIC, generic),
1023 };
1024
1025 ret = cardbus_parse_cis(cbdev, child, init_callbacks);
1026 if (ret < 0)
1027 return (ret);
1028 cardbus_pickup_maps(cbdev, child);
1029 return (cardbus_alloc_resources(cbdev, child));
1030 }
Cache object: 528476496b96f46fd118fc7324917b74
|