|
|
1.1 root 1: /*
2: * bios32.c - BIOS32, PCI BIOS functions.
3: *
4: * $Id: bios32.c,v 1.1 1999/04/26 05:50:57 tb Exp $
5: *
6: * Sponsored by
7: * iX Multiuser Multitasking Magazine
8: * Hannover, Germany
9: * [email protected]
10: *
11: * Copyright 1993, 1994 Drew Eckhardt
12: * Visionary Computing
13: * (Unix and Linux consulting and custom programming)
14: * [email protected]
15: * +1 (303) 786-7975
16: *
17: * For more information, please consult
18: *
19: * PCI BIOS Specification Revision
20: * PCI Local Bus Specification
21: * PCI System Design Guide
22: *
23: * PCI Special Interest Group
24: * M/S HF3-15A
25: * 5200 N.E. Elam Young Parkway
26: * Hillsboro, Oregon 97124-6497
27: * +1 (503) 696-2000
28: * +1 (800) 433-5177
29: *
30: * Manuals are $25 each or $50 for all three, plus $7 shipping
31: * within the United States, $35 abroad.
32: *
33: *
34: * CHANGELOG :
35: * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
36: * Revision 2.0 present on <[email protected]>'s ASUS mainboard.
37: *
38: * Jan 5, 1995 : Modified to probe PCI hardware at boot time by Frederic
39: * Potter, [email protected]
40: *
41: * Jan 10, 1995 : Modified to store the information about configured pci
42: * devices into a list, which can be accessed via /proc/pci by
43: * Curtis Varner, [email protected]
44: *
45: * Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
46: * Alpha version. Intel & UMC chipset support only.
47: *
48: * Apr 16, 1995 : Source merge with the DEC Alpha PCI support. Most of the code
49: * moved to drivers/pci/pci.c.
50: *
51: * Dec 7, 1996 : Added support for direct configuration access of boards
52: * with Intel compatible access schemes ([email protected])
53: *
54: * Feb 3, 1997 : Set internal functions to static, save/restore flags
55: * avoid dead locks reading broken PCI BIOS, [email protected]
56: *
57: * Apr 26, 1997 : Fixed case when there is BIOS32, but not PCI BIOS
58: * ([email protected])
59: *
60: * May 7, 1997 : Added some missing cli()'s. [mj]
61: *
62: * Jun 20, 1997 : Corrected problems in "conf1" type accesses.
63: * ([email protected])
64: */
65:
66: #include <linux/config.h>
67: #include <linux/types.h>
68: #include <linux/kernel.h>
69: #include <linux/bios32.h>
70: #include <linux/pci.h>
71:
72: #include <asm/segment.h>
73: #include <asm/system.h>
74: #include <asm/io.h>
75:
76: #define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
77: #define PCIBIOS_PCI_BIOS_PRESENT 0xb101
78: #define PCIBIOS_FIND_PCI_DEVICE 0xb102
79: #define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103
80: #define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106
81: #define PCIBIOS_READ_CONFIG_BYTE 0xb108
82: #define PCIBIOS_READ_CONFIG_WORD 0xb109
83: #define PCIBIOS_READ_CONFIG_DWORD 0xb10a
84: #define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
85: #define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
86: #define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
87:
88:
89: /* BIOS32 signature: "_32_" */
90: #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
91:
92: /* PCI signature: "PCI " */
93: #define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
94:
95: /* PCI service signature: "$PCI" */
96: #define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
97:
98: /*
99: * This is the standard structure used to identify the entry point
100: * to the BIOS32 Service Directory, as documented in
101: * Standard BIOS 32-bit Service Directory Proposal
102: * Revision 0.4 May 24, 1993
103: * Phoenix Technologies Ltd.
104: * Norwood, MA
105: * and the PCI BIOS specification.
106: */
107:
108: union bios32 {
109: struct {
110: unsigned long signature; /* _32_ */
111: unsigned long entry; /* 32 bit physical address */
112: unsigned char revision; /* Revision level, 0 */
113: unsigned char length; /* Length in paragraphs should be 01 */
114: unsigned char checksum; /* All bytes must add up to zero */
115: unsigned char reserved[5]; /* Must be zero */
116: } fields;
117: char chars[16];
118: };
119:
120: #ifdef CONFIG_PCI
121: /*
122: * Physical address of the service directory. I don't know if we're
123: * allowed to have more than one of these or not, so just in case
124: * we'll make pcibios_present() take a memory start parameter and store
125: * the array there.
126: */
127:
128: static unsigned long bios32_entry = 0;
129: static struct {
130: unsigned long address;
131: unsigned short segment;
132: } bios32_indirect = { 0, KERNEL_CS };
133:
134:
135: /*
136: * function table for accessing PCI configuration space
137: */
138: struct pci_access {
139: int (*find_device)(unsigned short, unsigned short, unsigned short, unsigned char *, unsigned char *);
140: int (*find_class)(unsigned int, unsigned short, unsigned char *, unsigned char *);
141: int (*read_config_byte)(unsigned char, unsigned char, unsigned char, unsigned char *);
142: int (*read_config_word)(unsigned char, unsigned char, unsigned char, unsigned short *);
143: int (*read_config_dword)(unsigned char, unsigned char, unsigned char, unsigned int *);
144: int (*write_config_byte)(unsigned char, unsigned char, unsigned char, unsigned char);
145: int (*write_config_word)(unsigned char, unsigned char, unsigned char, unsigned short);
146: int (*write_config_dword)(unsigned char, unsigned char, unsigned char, unsigned int);
147: };
148:
149: /*
150: * pointer to selected PCI access function table
151: */
152: static struct pci_access *access_pci = NULL;
153:
154:
155:
156: /*
157: * Returns the entry point for the given service, NULL on error
158: */
159:
160: static unsigned long bios32_service(unsigned long service)
161: {
162: unsigned char return_code; /* %al */
163: unsigned long address; /* %ebx */
164: unsigned long length; /* %ecx */
165: unsigned long entry; /* %edx */
166: unsigned long flags;
167:
168: save_flags(flags); cli();
1.1.1.2 root 169: __asm__("lcall *(%%edi); cld"
1.1 root 170: : "=a" (return_code),
171: "=b" (address),
172: "=c" (length),
173: "=d" (entry)
174: : "0" (service),
175: "1" (0),
176: "D" (&bios32_indirect));
177: restore_flags(flags);
178:
179: switch (return_code) {
180: case 0:
181: return address + entry;
182: case 0x80: /* Not present */
183: printk("bios32_service(0x%lx) : not present\n", service);
184: return 0;
185: default: /* Shouldn't happen */
186: printk("bios32_service(0x%lx) : returned 0x%x, mail [email protected]\n",
187: service, return_code);
188: return 0;
189: }
190: }
191:
192: static long pcibios_entry = 0;
193: static struct {
194: unsigned long address;
195: unsigned short segment;
196: } pci_indirect = { 0, KERNEL_CS };
197:
198:
199: static int check_pcibios(void)
200: {
201: unsigned long signature;
202: unsigned char present_status;
203: unsigned char major_revision;
204: unsigned char minor_revision;
205: unsigned long flags;
206: int pack;
207:
208: if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
1.1.1.2 root 209: pci_indirect.address = phystokv(pcibios_entry);
1.1 root 210:
211: save_flags(flags); cli();
1.1.1.2 root 212: __asm__("lcall *(%%edi); cld\n\t"
1.1 root 213: "jc 1f\n\t"
214: "xor %%ah, %%ah\n"
215: "1:\tshl $8, %%eax\n\t"
216: "movw %%bx, %%ax"
217: : "=d" (signature),
218: "=a" (pack)
219: : "1" (PCIBIOS_PCI_BIOS_PRESENT),
220: "D" (&pci_indirect)
221: : "bx", "cx");
222: restore_flags(flags);
223:
224: present_status = (pack >> 16) & 0xff;
225: major_revision = (pack >> 8) & 0xff;
226: minor_revision = pack & 0xff;
227: if (present_status || (signature != PCI_SIGNATURE)) {
228: printk ("pcibios_init : %s : BIOS32 Service Directory says PCI BIOS is present,\n"
229: " but PCI_BIOS_PRESENT subfunction fails with present status of 0x%x\n"
230: " and signature of 0x%08lx (%c%c%c%c). mail [email protected]\n",
231: (signature == PCI_SIGNATURE) ? "WARNING" : "ERROR",
232: present_status, signature,
233: (char) (signature >> 0), (char) (signature >> 8),
234: (char) (signature >> 16), (char) (signature >> 24));
235:
236: if (signature != PCI_SIGNATURE)
237: pcibios_entry = 0;
238: }
239: if (pcibios_entry) {
240: printk ("pcibios_init : PCI BIOS revision %x.%02x entry at 0x%lx\n",
241: major_revision, minor_revision, pcibios_entry);
242: return 1;
243: }
244: }
245: return 0;
246: }
247:
248:
249: static int pci_bios_find_class (unsigned int class_code, unsigned short index,
250: unsigned char *bus, unsigned char *device_fn)
251: {
252: unsigned long bx;
253: unsigned long ret;
254: unsigned long flags;
255:
256: save_flags(flags); cli();
1.1.1.2 root 257: __asm__ ("lcall *(%%edi); cld\n\t"
1.1 root 258: "jc 1f\n\t"
259: "xor %%ah, %%ah\n"
260: "1:"
261: : "=b" (bx),
262: "=a" (ret)
263: : "1" (PCIBIOS_FIND_PCI_CLASS_CODE),
264: "c" (class_code),
265: "S" ((int) index),
266: "D" (&pci_indirect));
267: restore_flags(flags);
268: *bus = (bx >> 8) & 0xff;
269: *device_fn = bx & 0xff;
270: return (int) (ret & 0xff00) >> 8;
271: }
272:
273:
274: static int pci_bios_find_device (unsigned short vendor, unsigned short device_id,
275: unsigned short index, unsigned char *bus, unsigned char *device_fn)
276: {
277: unsigned short bx;
278: unsigned short ret;
279: unsigned long flags;
280:
281: save_flags(flags); cli();
1.1.1.2 root 282: __asm__("lcall *(%%edi); cld\n\t"
1.1 root 283: "jc 1f\n\t"
284: "xor %%ah, %%ah\n"
285: "1:"
286: : "=b" (bx),
287: "=a" (ret)
288: : "1" (PCIBIOS_FIND_PCI_DEVICE),
289: "c" (device_id),
290: "d" (vendor),
291: "S" ((int) index),
292: "D" (&pci_indirect));
293: restore_flags(flags);
294: *bus = (bx >> 8) & 0xff;
295: *device_fn = bx & 0xff;
296: return (int) (ret & 0xff00) >> 8;
297: }
298:
299: static int pci_bios_read_config_byte(unsigned char bus,
300: unsigned char device_fn, unsigned char where, unsigned char *value)
301: {
302: unsigned long ret;
303: unsigned long bx = (bus << 8) | device_fn;
304: unsigned long flags;
305:
306: save_flags(flags); cli();
1.1.1.2 root 307: __asm__("lcall *(%%esi); cld\n\t"
1.1 root 308: "jc 1f\n\t"
309: "xor %%ah, %%ah\n"
310: "1:"
311: : "=c" (*value),
312: "=a" (ret)
313: : "1" (PCIBIOS_READ_CONFIG_BYTE),
314: "b" (bx),
315: "D" ((long) where),
316: "S" (&pci_indirect));
317: restore_flags(flags);
318: return (int) (ret & 0xff00) >> 8;
319: }
320:
321: static int pci_bios_read_config_word (unsigned char bus,
322: unsigned char device_fn, unsigned char where, unsigned short *value)
323: {
324: unsigned long ret;
325: unsigned long bx = (bus << 8) | device_fn;
326: unsigned long flags;
327:
328: save_flags(flags); cli();
1.1.1.2 root 329: __asm__("lcall *(%%esi); cld\n\t"
1.1 root 330: "jc 1f\n\t"
331: "xor %%ah, %%ah\n"
332: "1:"
333: : "=c" (*value),
334: "=a" (ret)
335: : "1" (PCIBIOS_READ_CONFIG_WORD),
336: "b" (bx),
337: "D" ((long) where),
338: "S" (&pci_indirect));
339: restore_flags(flags);
340: return (int) (ret & 0xff00) >> 8;
341: }
342:
343: static int pci_bios_read_config_dword (unsigned char bus,
344: unsigned char device_fn, unsigned char where, unsigned int *value)
345: {
346: unsigned long ret;
347: unsigned long bx = (bus << 8) | device_fn;
348: unsigned long flags;
349:
350: save_flags(flags); cli();
1.1.1.2 root 351: __asm__("lcall *(%%esi); cld\n\t"
1.1 root 352: "jc 1f\n\t"
353: "xor %%ah, %%ah\n"
354: "1:"
355: : "=c" (*value),
356: "=a" (ret)
357: : "1" (PCIBIOS_READ_CONFIG_DWORD),
358: "b" (bx),
359: "D" ((long) where),
360: "S" (&pci_indirect));
361: restore_flags(flags);
362: return (int) (ret & 0xff00) >> 8;
363: }
364:
365: static int pci_bios_write_config_byte (unsigned char bus,
366: unsigned char device_fn, unsigned char where, unsigned char value)
367: {
368: unsigned long ret;
369: unsigned long bx = (bus << 8) | device_fn;
370: unsigned long flags;
371:
372: save_flags(flags); cli();
1.1.1.2 root 373: __asm__("lcall *(%%esi); cld\n\t"
1.1 root 374: "jc 1f\n\t"
375: "xor %%ah, %%ah\n"
376: "1:"
377: : "=a" (ret)
378: : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
379: "c" (value),
380: "b" (bx),
381: "D" ((long) where),
382: "S" (&pci_indirect));
383: restore_flags(flags);
384: return (int) (ret & 0xff00) >> 8;
385: }
386:
387: static int pci_bios_write_config_word (unsigned char bus,
388: unsigned char device_fn, unsigned char where, unsigned short value)
389: {
390: unsigned long ret;
391: unsigned long bx = (bus << 8) | device_fn;
392: unsigned long flags;
393:
394: save_flags(flags); cli();
1.1.1.2 root 395: __asm__("lcall *(%%esi); cld\n\t"
1.1 root 396: "jc 1f\n\t"
397: "xor %%ah, %%ah\n"
398: "1:"
399: : "=a" (ret)
400: : "0" (PCIBIOS_WRITE_CONFIG_WORD),
401: "c" (value),
402: "b" (bx),
403: "D" ((long) where),
404: "S" (&pci_indirect));
405: restore_flags(flags);
406: return (int) (ret & 0xff00) >> 8;
407: }
408:
409: static int pci_bios_write_config_dword (unsigned char bus,
410: unsigned char device_fn, unsigned char where, unsigned int value)
411: {
412: unsigned long ret;
413: unsigned long bx = (bus << 8) | device_fn;
414: unsigned long flags;
415:
416: save_flags(flags); cli();
1.1.1.2 root 417: __asm__("lcall *(%%esi); cld\n\t"
1.1 root 418: "jc 1f\n\t"
419: "xor %%ah, %%ah\n"
420: "1:"
421: : "=a" (ret)
422: : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
423: "c" (value),
424: "b" (bx),
425: "D" ((long) where),
426: "S" (&pci_indirect));
427: restore_flags(flags);
428: return (int) (ret & 0xff00) >> 8;
429: }
430:
431: /*
432: * function table for BIOS32 access
433: */
434: static struct pci_access pci_bios_access = {
435: pci_bios_find_device,
436: pci_bios_find_class,
437: pci_bios_read_config_byte,
438: pci_bios_read_config_word,
439: pci_bios_read_config_dword,
440: pci_bios_write_config_byte,
441: pci_bios_write_config_word,
442: pci_bios_write_config_dword
443: };
444:
445:
446:
447: /*
448: * Given the vendor and device ids, find the n'th instance of that device
449: * in the system.
450: */
451: static int pci_direct_find_device (unsigned short vendor, unsigned short device_id,
452: unsigned short index, unsigned char *bus,
453: unsigned char *devfn)
454: {
455: unsigned int curr = 0;
456: struct pci_dev *dev;
457:
458: for (dev = pci_devices; dev; dev = dev->next) {
459: if (dev->vendor == vendor && dev->device == device_id) {
460: if (curr == index) {
461: *devfn = dev->devfn;
462: *bus = dev->bus->number;
463: return PCIBIOS_SUCCESSFUL;
464: }
465: ++curr;
466: }
467: }
468: return PCIBIOS_DEVICE_NOT_FOUND;
469: }
470:
471:
472: /*
473: * Given the class, find the n'th instance of that device
474: * in the system.
475: */
476: static int pci_direct_find_class (unsigned int class_code, unsigned short index,
477: unsigned char *bus, unsigned char *devfn)
478: {
479: unsigned int curr = 0;
480: struct pci_dev *dev;
481:
482: for (dev = pci_devices; dev; dev = dev->next) {
483: if (dev->class == class_code) {
484: if (curr == index) {
485: *devfn = dev->devfn;
486: *bus = dev->bus->number;
487: return PCIBIOS_SUCCESSFUL;
488: }
489: ++curr;
490: }
491: }
492: return PCIBIOS_DEVICE_NOT_FOUND;
493: }
494:
495: /*
496: * Functions for accessing PCI configuration space with type 1 accesses
497: */
498: #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
499:
500: static int pci_conf1_read_config_byte(unsigned char bus, unsigned char device_fn,
501: unsigned char where, unsigned char *value)
502: {
503: unsigned long flags;
504:
505: save_flags(flags); cli();
506: outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
507: *value = inb(0xCFC + (where&3));
508: restore_flags(flags);
509: return PCIBIOS_SUCCESSFUL;
510: }
511:
512: static int pci_conf1_read_config_word (unsigned char bus,
513: unsigned char device_fn, unsigned char where, unsigned short *value)
514: {
515: unsigned long flags;
516:
517: if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
518: save_flags(flags); cli();
519: outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
520: *value = inw(0xCFC + (where&2));
521: restore_flags(flags);
522: return PCIBIOS_SUCCESSFUL;
523: }
524:
525: static int pci_conf1_read_config_dword (unsigned char bus, unsigned char device_fn,
526: unsigned char where, unsigned int *value)
527: {
528: unsigned long flags;
529:
530: if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
531: save_flags(flags); cli();
532: outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
533: *value = inl(0xCFC);
534: restore_flags(flags);
535: return PCIBIOS_SUCCESSFUL;
536: }
537:
538: static int pci_conf1_write_config_byte (unsigned char bus, unsigned char device_fn,
539: unsigned char where, unsigned char value)
540: {
541: unsigned long flags;
542:
543: save_flags(flags); cli();
544: outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
545: outb(value, 0xCFC + (where&3));
546: restore_flags(flags);
547: return PCIBIOS_SUCCESSFUL;
548: }
549:
550: static int pci_conf1_write_config_word (unsigned char bus, unsigned char device_fn,
551: unsigned char where, unsigned short value)
552: {
553: unsigned long flags;
554:
555: if (where&1) return PCIBIOS_BAD_REGISTER_NUMBER;
556: save_flags(flags); cli();
557: outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
558: outw(value, 0xCFC + (where&2));
559: restore_flags(flags);
560: return PCIBIOS_SUCCESSFUL;
561: }
562:
563: static int pci_conf1_write_config_dword (unsigned char bus, unsigned char device_fn,
564: unsigned char where, unsigned int value)
565: {
566: unsigned long flags;
567:
568: if (where&3) return PCIBIOS_BAD_REGISTER_NUMBER;
569: save_flags(flags); cli();
570: outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
571: outl(value, 0xCFC);
572: restore_flags(flags);
573: return PCIBIOS_SUCCESSFUL;
574: }
575:
576: #undef CONFIG_CMD
577:
578: /*
579: * functiontable for type 1
580: */
581: static struct pci_access pci_direct_conf1 = {
582: pci_direct_find_device,
583: pci_direct_find_class,
584: pci_conf1_read_config_byte,
585: pci_conf1_read_config_word,
586: pci_conf1_read_config_dword,
587: pci_conf1_write_config_byte,
588: pci_conf1_write_config_word,
589: pci_conf1_write_config_dword
590: };
591:
592: /*
593: * Functions for accessing PCI configuration space with type 2 accesses
594: */
595: #define IOADDR(devfn, where) ((0xC000 | ((devfn & 0x78) << 5)) + where)
596: #define FUNC(devfn) (((devfn & 7) << 1) | 0xf0)
597:
598: static int pci_conf2_read_config_byte(unsigned char bus, unsigned char device_fn,
599: unsigned char where, unsigned char *value)
600: {
601: unsigned long flags;
602:
603: if (device_fn & 0x80)
604: return PCIBIOS_DEVICE_NOT_FOUND;
605: save_flags(flags); cli();
606: outb (FUNC(device_fn), 0xCF8);
607: outb (bus, 0xCFA);
608: *value = inb(IOADDR(device_fn,where));
609: outb (0, 0xCF8);
610: restore_flags(flags);
611: return PCIBIOS_SUCCESSFUL;
612: }
613:
614: static int pci_conf2_read_config_word (unsigned char bus, unsigned char device_fn,
615: unsigned char where, unsigned short *value)
616: {
617: unsigned long flags;
618:
619: if (device_fn & 0x80)
620: return PCIBIOS_DEVICE_NOT_FOUND;
621: save_flags(flags); cli();
622: outb (FUNC(device_fn), 0xCF8);
623: outb (bus, 0xCFA);
624: *value = inw(IOADDR(device_fn,where));
625: outb (0, 0xCF8);
626: restore_flags(flags);
627: return PCIBIOS_SUCCESSFUL;
628: }
629:
630: static int pci_conf2_read_config_dword (unsigned char bus, unsigned char device_fn,
631: unsigned char where, unsigned int *value)
632: {
633: unsigned long flags;
634:
635: if (device_fn & 0x80)
636: return PCIBIOS_DEVICE_NOT_FOUND;
637: save_flags(flags); cli();
638: outb (FUNC(device_fn), 0xCF8);
639: outb (bus, 0xCFA);
640: *value = inl (IOADDR(device_fn,where));
641: outb (0, 0xCF8);
642: restore_flags(flags);
643: return PCIBIOS_SUCCESSFUL;
644: }
645:
646: static int pci_conf2_write_config_byte (unsigned char bus, unsigned char device_fn,
647: unsigned char where, unsigned char value)
648: {
649: unsigned long flags;
650:
651: save_flags(flags); cli();
652: outb (FUNC(device_fn), 0xCF8);
653: outb (bus, 0xCFA);
654: outb (value, IOADDR(device_fn,where));
655: outb (0, 0xCF8);
656: restore_flags(flags);
657: return PCIBIOS_SUCCESSFUL;
658: }
659:
660: static int pci_conf2_write_config_word (unsigned char bus, unsigned char device_fn,
661: unsigned char where, unsigned short value)
662: {
663: unsigned long flags;
664:
665: save_flags(flags); cli();
666: outb (FUNC(device_fn), 0xCF8);
667: outb (bus, 0xCFA);
668: outw (value, IOADDR(device_fn,where));
669: outb (0, 0xCF8);
670: restore_flags(flags);
671: return PCIBIOS_SUCCESSFUL;
672: }
673:
674: static int pci_conf2_write_config_dword (unsigned char bus, unsigned char device_fn,
675: unsigned char where, unsigned int value)
676: {
677: unsigned long flags;
678:
679: save_flags(flags); cli();
680: outb (FUNC(device_fn), 0xCF8);
681: outb (bus, 0xCFA);
682: outl (value, IOADDR(device_fn,where));
683: outb (0, 0xCF8);
684: restore_flags(flags);
685: return PCIBIOS_SUCCESSFUL;
686: }
687:
688: #undef IOADDR
689: #undef FUNC
690:
691: /*
692: * functiontable for type 2
693: */
694: static struct pci_access pci_direct_conf2 = {
695: pci_direct_find_device,
696: pci_direct_find_class,
697: pci_conf2_read_config_byte,
698: pci_conf2_read_config_word,
699: pci_conf2_read_config_dword,
700: pci_conf2_write_config_byte,
701: pci_conf2_write_config_word,
702: pci_conf2_write_config_dword
703: };
704:
705:
706: static struct pci_access *check_direct_pci(void)
707: {
708: unsigned int tmp;
709: unsigned long flags;
710:
711: save_flags(flags); cli();
712:
713: /*
714: * check if configuration type 1 works
715: */
716: outb (0x01, 0xCFB);
717: tmp = inl (0xCF8);
718: outl (0x80000000, 0xCF8);
719: if (inl (0xCF8) == 0x80000000) {
720: outl (tmp, 0xCF8);
721: restore_flags(flags);
722: printk("pcibios_init: Using configuration type 1\n");
723: return &pci_direct_conf1;
724: }
725: outl (tmp, 0xCF8);
726:
727: /*
728: * check if configuration type 2 works
729: */
730: outb (0x00, 0xCFB);
731: outb (0x00, 0xCF8);
732: outb (0x00, 0xCFA);
733: if (inb (0xCF8) == 0x00 && inb (0xCFB) == 0x00) {
734: restore_flags(flags);
735: printk("pcibios_init: Using configuration type 2\n");
736: return &pci_direct_conf2;
737: }
738: restore_flags(flags);
739: printk("pcibios_init: Not supported chipset for direct PCI access !\n");
740: return NULL;
741: }
742:
743:
744: /*
745: * access defined pcibios functions via
746: * the function table
747: */
748:
749: int pcibios_present(void)
750: {
751: return access_pci ? 1 : 0;
752: }
753:
754: int pcibios_find_class (unsigned int class_code, unsigned short index,
755: unsigned char *bus, unsigned char *device_fn)
756: {
757: if (access_pci && access_pci->find_class)
758: return access_pci->find_class(class_code, index, bus, device_fn);
759:
760: return PCIBIOS_FUNC_NOT_SUPPORTED;
761: }
762:
763: int pcibios_find_device (unsigned short vendor, unsigned short device_id,
764: unsigned short index, unsigned char *bus, unsigned char *device_fn)
765: {
766: if (access_pci && access_pci->find_device)
767: return access_pci->find_device(vendor, device_id, index, bus, device_fn);
768:
769: return PCIBIOS_FUNC_NOT_SUPPORTED;
770: }
771:
772: int pcibios_read_config_byte (unsigned char bus,
773: unsigned char device_fn, unsigned char where, unsigned char *value)
774: {
775: if (access_pci && access_pci->read_config_byte)
776: return access_pci->read_config_byte(bus, device_fn, where, value);
777:
778: return PCIBIOS_FUNC_NOT_SUPPORTED;
779: }
780:
781: int pcibios_read_config_word (unsigned char bus,
782: unsigned char device_fn, unsigned char where, unsigned short *value)
783: {
784: if (access_pci && access_pci->read_config_word)
785: return access_pci->read_config_word(bus, device_fn, where, value);
786:
787: return PCIBIOS_FUNC_NOT_SUPPORTED;
788: }
789:
790: int pcibios_read_config_dword (unsigned char bus,
791: unsigned char device_fn, unsigned char where, unsigned int *value)
792: {
793: if (access_pci && access_pci->read_config_dword)
794: return access_pci->read_config_dword(bus, device_fn, where, value);
795:
796: return PCIBIOS_FUNC_NOT_SUPPORTED;
797: }
798:
799: int pcibios_write_config_byte (unsigned char bus,
800: unsigned char device_fn, unsigned char where, unsigned char value)
801: {
802: if (access_pci && access_pci->write_config_byte)
803: return access_pci->write_config_byte(bus, device_fn, where, value);
804:
805: return PCIBIOS_FUNC_NOT_SUPPORTED;
806: }
807:
808: int pcibios_write_config_word (unsigned char bus,
809: unsigned char device_fn, unsigned char where, unsigned short value)
810: {
811: if (access_pci && access_pci->write_config_word)
812: return access_pci->write_config_word(bus, device_fn, where, value);
813:
814: return PCIBIOS_FUNC_NOT_SUPPORTED;
815: }
816:
817: int pcibios_write_config_dword (unsigned char bus,
818: unsigned char device_fn, unsigned char where, unsigned int value)
819: {
820: if (access_pci && access_pci->write_config_dword)
821: return access_pci->write_config_dword(bus, device_fn, where, value);
822:
823: return PCIBIOS_FUNC_NOT_SUPPORTED;
824: }
825:
826: const char *pcibios_strerror (int error)
827: {
828: static char buf[80];
829:
830: switch (error) {
831: case PCIBIOS_SUCCESSFUL:
832: return "SUCCESSFUL";
833:
834: case PCIBIOS_FUNC_NOT_SUPPORTED:
835: return "FUNC_NOT_SUPPORTED";
836:
837: case PCIBIOS_BAD_VENDOR_ID:
838: return "SUCCESSFUL";
839:
840: case PCIBIOS_DEVICE_NOT_FOUND:
841: return "DEVICE_NOT_FOUND";
842:
843: case PCIBIOS_BAD_REGISTER_NUMBER:
844: return "BAD_REGISTER_NUMBER";
845:
846: case PCIBIOS_SET_FAILED:
847: return "SET_FAILED";
848:
849: case PCIBIOS_BUFFER_TOO_SMALL:
850: return "BUFFER_TOO_SMALL";
851:
852: default:
853: sprintf (buf, "UNKNOWN RETURN 0x%x", error);
854: return buf;
855: }
856: }
857:
858:
859: unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
860: {
861: return mem_start;
862: }
863:
864: #endif
865:
866: unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
867: {
868: #ifdef CONFIG_PCI
869: union bios32 *check;
870: unsigned char sum;
871: int i, length;
872:
873: /*
874: * Follow the standard procedure for locating the BIOS32 Service
875: * directory by scanning the permissible address range from
876: * 0xe0000 through 0xfffff for a valid BIOS32 structure.
877: *
878: */
879:
880: for (check = (union bios32 *) 0xe0000;
881: check <= (union bios32 *) 0xffff0;
882: ++check) {
883: if (check->fields.signature != BIOS32_SIGNATURE)
884: continue;
885: length = check->fields.length * 16;
886: if (!length)
887: continue;
888: sum = 0;
889: for (i = 0; i < length ; ++i)
890: sum += check->chars[i];
891: if (sum != 0)
892: continue;
893: if (check->fields.revision != 0) {
894: printk("pcibios_init : unsupported revision %d at 0x%p, mail [email protected]\n",
895: check->fields.revision, check);
896: continue;
897: }
898: printk ("pcibios_init : BIOS32 Service Directory structure at 0x%p\n", check);
899: if (!bios32_entry) {
900: if (check->fields.entry >= 0x100000) {
901: printk("pcibios_init: entry in high memory, trying direct PCI access\n");
902: access_pci = check_direct_pci();
903: } else {
904: bios32_entry = check->fields.entry;
905: printk ("pcibios_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
1.1.1.2 root 906: bios32_indirect.address = phystokv(bios32_entry);
1.1 root 907: }
908: }
909: }
910: if (bios32_entry && check_pcibios())
911: access_pci = &pci_bios_access;
1.1.1.3 ! root 912: else
! 913: access_pci = check_direct_pci();
1.1 root 914: #endif
915: return memory_start;
916: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.