home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / arch / i386 / kernel / bios32.c next >
Encoding:
C/C++ Source or Header  |  1995-02-17  |  19.5 KB  |  798 lines

  1. /*
  2.  * bios32.c - BIOS32, PCI BIOS functions.
  3.  *
  4.  * Sponsored by
  5.  *    iX Multiuser Multitasking Magazine
  6.  *    Hannover, Germany
  7.  *    hm@ix.de
  8.  *
  9.  * Copyright 1993, 1994 Drew Eckhardt
  10.  *      Visionary Computing
  11.  *      (Unix and Linux consulting and custom programming)
  12.  *      Drew@Colorado.EDU
  13.  *      +1 (303) 786-7975
  14.  *
  15.  * For more information, please consult
  16.  *
  17.  * PCI BIOS Specification Revision
  18.  * PCI Local Bus Specification
  19.  * PCI System Design Guide
  20.  *
  21.  * PCI Special Interest Group
  22.  * M/S HF3-15A
  23.  * 5200 N.E. Elam Young Parkway
  24.  * Hillsboro, Oregon 97124-6497
  25.  * +1 (503) 696-2000
  26.  * +1 (800) 433-5177
  27.  *
  28.  * Manuals are $25 each or $50 for all three, plus $7 shipping
  29.  * within the United States, $35 abroad.
  30.  *
  31.  *
  32.  * CHANGELOG :
  33.  * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
  34.  *    Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
  35.  *
  36.  * Jan 5,  1995 : Modified to probe PCI hardware at boot time by Frederic
  37.  *     Potter, potter@cao-vlsi.ibp.fr
  38.  *
  39.  * Jan 10, 1995 : Modified to store the information about configured pci
  40.  *      devices into a list, which can be accessed via /proc/pci by
  41.  *      Curtis Varner, cvarner@cs.ucr.edu
  42.  *
  43.  * Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
  44.  *    Alpha version. Intel & UMC chipset support only. See pci.h for more.
  45.  */
  46.  
  47. #include <linux/config.h>
  48. #include <linux/types.h>
  49. #include <linux/kernel.h>
  50. #include <linux/bios32.h>
  51. #include <linux/pci.h>
  52.  
  53. #include <asm/segment.h>
  54.  
  55. #define PCIBIOS_PCI_FUNCTION_ID     0xb1XX
  56. #define PCIBIOS_PCI_BIOS_PRESENT     0xb101
  57. #define PCIBIOS_FIND_PCI_DEVICE        0xb102
  58. #define PCIBIOS_FIND_PCI_CLASS_CODE    0xb103
  59. #define PCIBIOS_GENERATE_SPECIAL_CYCLE    0xb106
  60. #define PCIBIOS_READ_CONFIG_BYTE    0xb108
  61. #define PCIBIOS_READ_CONFIG_WORD    0xb109
  62. #define PCIBIOS_READ_CONFIG_DWORD    0xb10a
  63. #define PCIBIOS_WRITE_CONFIG_BYTE    0xb10b
  64. #define PCIBIOS_WRITE_CONFIG_WORD    0xb10c
  65. #define PCIBIOS_WRITE_CONFIG_DWORD    0xb10d
  66.  
  67. #ifdef CONFIG_PCI
  68. extern void add_pci_resource(unsigned char, unsigned char);
  69. #endif
  70.  
  71. /* BIOS32 signature: "_32_" */
  72. #define BIOS32_SIGNATURE    (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
  73.  
  74. /* PCI signature: "PCI " */
  75. #define PCI_SIGNATURE        (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
  76.  
  77. /* PCI service signature: "$PCI" */
  78. #define PCI_SERVICE        (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
  79.  
  80. /*
  81.  * This is the standard structure used to identify the entry point
  82.  * to the BIOS32 Service Directory, as documented in
  83.  *     Standard BIOS 32-bit Service Directory Proposal
  84.  *     Revision 0.4 May 24, 1993
  85.  *     Phoenix Technologies Ltd.
  86.  *    Norwood, MA
  87.  * and the PCI BIOS specification.
  88.  */
  89.  
  90. #ifdef CONFIG_PCI
  91. typedef struct pci_resource_t
  92. {
  93.    unsigned char bus;
  94.    unsigned char dev_fn;
  95.    struct pci_resource_t *next;
  96. } pci_resource_t;
  97. #endif
  98.  
  99. union bios32 {
  100.     struct {
  101.         unsigned long signature;    /* _32_ */
  102.         unsigned long entry;        /* 32 bit physical address */
  103.         unsigned char revision;        /* Revision level, 0 */
  104.         unsigned char length;        /* Length in paragraphs should be 01 */
  105.         unsigned char checksum;        /* All bytes must add up to zero */
  106.         unsigned char reserved[5];     /* Must be zero */
  107.     } fields;
  108.     char chars[16];
  109. };
  110.  
  111. /*
  112.  * Physical address of the service directory.  I don't know if we're
  113.  * allowed to have more than one of these or not, so just in case
  114.  * we'll make bios32_init() take a memory start parameter and store
  115.  * the array there.
  116.  */
  117.  
  118. static unsigned long bios32_entry = 0;
  119. static struct {
  120.     unsigned long address;
  121.     unsigned short segment;
  122. } bios32_indirect = { 0, KERNEL_CS };
  123.  
  124. #ifdef CONFIG_PCI
  125. /*
  126.  * Returns the entry point for the given service, NULL on error
  127.  */
  128.  
  129. #define PCI_LIST_SIZE 32
  130.  
  131. static pci_resource_t pci_list = { 0, 0, NULL };
  132. static int pci_index = 0;
  133. static pci_resource_t pci_table[PCI_LIST_SIZE];
  134.  
  135. static struct    pci_class_type pci_class[PCI_CLASS_NUM] = PCI_CLASS_TYPE;
  136. static struct    pci_vendor_type    pci_vendor[PCI_VENDOR_NUM] = PCI_VENDOR_TYPE;
  137. static struct    pci_device_type    pci_device[PCI_DEVICE_NUM] = PCI_DEVICE_TYPE;
  138.  
  139. #ifdef CONFIG_PCI_OPTIMIZE
  140. static    struct bridge_mapping_type bridge_mapping[5*BRIDGE_MAPPING_NUM] = BRIDGE_MAPPING_TYPE;
  141. static    struct optimisation_type optimisation[OPTIMISATION_NUM] = OPTIMISATION_TYPE;
  142. #endif
  143.  
  144. static unsigned long bios32_service(unsigned long service)
  145. {
  146.     unsigned char return_code;    /* %al */
  147.     unsigned long address;        /* %ebx */
  148.     unsigned long length;        /* %ecx */
  149.     unsigned long entry;        /* %edx */
  150.  
  151.     __asm__("lcall (%%edi)"
  152.         : "=a" (return_code),
  153.           "=b" (address),
  154.           "=c" (length),
  155.           "=d" (entry)
  156.         : "0" (service),
  157.           "1" (0),
  158.           "D" (&bios32_indirect));
  159.  
  160.     switch (return_code) {
  161.         case 0:
  162.             return address + entry;
  163.         case 0x80:    /* Not present */
  164.             printk("bios32_service(%ld) : not present\n", service);
  165.             return 0;
  166.         default: /* Shouldn't happen */
  167.             printk("bios32_service(%ld) : returned 0x%x, mail drew@colorado.edu\n",
  168.                 service, return_code);
  169.             return 0;
  170.     }
  171. }
  172.  
  173. static long pcibios_entry = 0;
  174. static struct {
  175.     unsigned long address;
  176.     unsigned short segment;
  177. } pci_indirect = { 0, KERNEL_CS };
  178.  
  179. void NCR53c810_test(void);
  180.  
  181. static unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
  182. {
  183.     unsigned long signature;
  184.     unsigned char present_status;
  185.     unsigned char major_revision;
  186.     unsigned char minor_revision;
  187.     int pack;
  188.  
  189.     if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
  190.         pci_indirect.address = pcibios_entry;
  191.  
  192.         __asm__("lcall (%%edi)\n\t"
  193.             "jc 1f\n\t"
  194.             "xor %%ah, %%ah\n"
  195.             "1:\tshl $8, %%eax\n\t"
  196.             "movw %%bx, %%ax"
  197.             : "=d" (signature),
  198.               "=a" (pack)
  199.             : "1" (PCIBIOS_PCI_BIOS_PRESENT),
  200.               "D" (&pci_indirect)
  201.             : "bx", "cx");
  202.  
  203.         present_status = (pack >> 16) & 0xff;
  204.         major_revision = (pack >> 8) & 0xff;
  205.         minor_revision = pack & 0xff;
  206.         if (present_status || (signature != PCI_SIGNATURE)) {
  207.             printk ("pcibios_init : %s : BIOS32 Service Directory says PCI BIOS is present,\n"
  208.                 "    but PCI_BIOS_PRESENT subfunction fails with present status of 0x%x\n"
  209.                 "    and signature of 0x%08lx (%c%c%c%c).  mail drew@Colorado.EDU\n",
  210.                 (signature == PCI_SIGNATURE) ?  "WARNING" : "ERROR",
  211.                 present_status, signature,
  212.                 (char) (signature >>  0), (char) (signature >>  8),
  213.                 (char) (signature >> 16), (char) (signature >> 24));
  214.  
  215.             if (signature != PCI_SIGNATURE)
  216.                 pcibios_entry = 0;
  217.         }
  218.         if (pcibios_entry) {
  219.             printk ("pcibios_init : PCI BIOS revision %x.%02x entry at 0x%lx\n",
  220.                 major_revision, minor_revision, pcibios_entry);
  221.         }
  222.     }
  223.  
  224. #if 0
  225.     NCR53c810_test();
  226. #endif
  227.     return memory_start;
  228. }
  229.  
  230. int pcibios_present(void)
  231. {
  232.     return pcibios_entry ? 1 : 0;
  233. }
  234.  
  235. int pcibios_find_class (unsigned long class_code, unsigned short index,
  236.     unsigned char *bus, unsigned char *device_fn)
  237. {
  238.     unsigned long bx;
  239.     unsigned long ret;
  240.  
  241.     __asm__ ("lcall (%%edi)\n\t"
  242.         "jc 1f\n\t"
  243.         "xor %%ah, %%ah\n"
  244.         "1:"
  245.         : "=b" (bx),
  246.           "=a" (ret)
  247.         : "1" (PCIBIOS_FIND_PCI_CLASS_CODE),
  248.           "c" (class_code),
  249.           "S" ((int) index),
  250.           "D" (&pci_indirect));
  251.     *bus = (bx >> 8) & 0xff;
  252.     *device_fn = bx & 0xff;
  253.     return (int) (ret & 0xff00) >> 8;
  254. }
  255.  
  256.  
  257. int pcibios_find_device (unsigned short vendor, unsigned short device_id,
  258.     unsigned short index, unsigned char *bus, unsigned char *device_fn)
  259. {
  260.     unsigned short bx;
  261.     unsigned short ret;
  262.  
  263.     __asm__("lcall (%%edi)\n\t"
  264.         "jc 1f\n\t"
  265.         "xor %%ah, %%ah\n"
  266.         "1:"
  267.         : "=b" (bx),
  268.           "=a" (ret)
  269.         : "1" (PCIBIOS_FIND_PCI_DEVICE),
  270.           "c" (device_id),
  271.           "d" (vendor),
  272.           "S" ((int) index),
  273.           "D" (&pci_indirect));
  274.     *bus = (bx >> 8) & 0xff;
  275.     *device_fn = bx & 0xff;
  276.     return (int) (ret & 0xff00) >> 8;
  277. }
  278.  
  279. int pcibios_read_config_byte(unsigned char bus,
  280.     unsigned char device_fn, unsigned char where, unsigned char *value)
  281. {
  282.     unsigned long ret;
  283.     unsigned long bx = (bus << 8) | device_fn;
  284.  
  285.     __asm__("lcall (%%esi)\n\t"
  286.         "jc 1f\n\t"
  287.         "xor %%ah, %%ah\n"
  288.         "1:"
  289.         : "=c" (*value),
  290.           "=a" (ret)
  291.         : "1" (PCIBIOS_READ_CONFIG_BYTE),
  292.           "b" (bx),
  293.           "D" ((long) where),
  294.           "S" (&pci_indirect));
  295.     return (int) (ret & 0xff00) >> 8;
  296. }
  297.  
  298. int pcibios_read_config_word (unsigned char bus,
  299.     unsigned char device_fn, unsigned char where, unsigned short *value)
  300. {
  301.     unsigned long ret;
  302.     unsigned long bx = (bus << 8) | device_fn;
  303.  
  304.     __asm__("lcall (%%esi)\n\t"
  305.         "jc 1f\n\t"
  306.         "xor %%ah, %%ah\n"
  307.         "1:"
  308.         : "=c" (*value),
  309.           "=a" (ret)
  310.         : "1" (PCIBIOS_READ_CONFIG_WORD),
  311.           "b" (bx),
  312.           "D" ((long) where),
  313.           "S" (&pci_indirect));
  314.     return (int) (ret & 0xff00) >> 8;
  315. }
  316.  
  317. int pcibios_read_config_dword (unsigned char bus,
  318.     unsigned char device_fn, unsigned char where, unsigned long *value)
  319. {
  320.     unsigned long ret;
  321.     unsigned long bx = (bus << 8) | device_fn;
  322.  
  323.     __asm__("lcall (%%esi)\n\t"
  324.         "jc 1f\n\t"
  325.         "xor %%ah, %%ah\n"
  326.         "1:"
  327.         : "=c" (*value),
  328.           "=a" (ret)
  329.         : "1" (PCIBIOS_READ_CONFIG_DWORD),
  330.           "b" (bx),
  331.           "D" ((long) where),
  332.           "S" (&pci_indirect));
  333.     return (int) (ret & 0xff00) >> 8;
  334. }
  335.  
  336. int pcibios_write_config_byte (unsigned char bus,
  337.     unsigned char device_fn, unsigned char where, unsigned char value)
  338. {
  339.     unsigned long ret;
  340.     unsigned long bx = (bus << 8) | device_fn;
  341.  
  342.     __asm__("lcall (%%esi)\n\t"
  343.         "jc 1f\n\t"
  344.         "xor %%ah, %%ah\n"
  345.         "1:"
  346.         : "=a" (ret)
  347.         : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
  348.           "c" (value),
  349.           "b" (bx),
  350.           "D" ((long) where),
  351.           "S" (&pci_indirect));
  352.     return (int) (ret & 0xff00) >> 8;
  353. }
  354.  
  355. int pcibios_write_config_word (unsigned char bus,
  356.     unsigned char device_fn, unsigned char where, unsigned short value)
  357. {
  358.     unsigned long ret;
  359.     unsigned long bx = (bus << 8) | device_fn;
  360.  
  361.     __asm__("lcall (%%esi)\n\t"
  362.         "jc 1f\n\t"
  363.         "xor %%ah, %%ah\n"
  364.         "1:"
  365.         : "=a" (ret)
  366.         : "0" (PCIBIOS_WRITE_CONFIG_WORD),
  367.           "c" (value),
  368.           "b" (bx),
  369.           "D" ((long) where),
  370.           "S" (&pci_indirect));
  371.     return (int) (ret & 0xff00) >> 8;
  372. }
  373.  
  374. int pcibios_write_config_dword (unsigned char bus,
  375.     unsigned char device_fn, unsigned char where, unsigned long value)
  376. {
  377.     unsigned long ret;
  378.     unsigned long bx = (bus << 8) | device_fn;
  379.  
  380.     __asm__("lcall (%%esi)\n\t"
  381.         "jc 1f\n\t"
  382.         "xor %%ah, %%ah\n"
  383.         "1:"
  384.         : "=a" (ret)
  385.         : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
  386.           "c" (value),
  387.           "b" (bx),
  388.           "D" ((long) where),
  389.           "S" (&pci_indirect));
  390.     return (int) (ret & 0xff00) >> 8;
  391. }
  392.  
  393. void NCR53c810_test(void)
  394. {
  395.     unsigned char bus, device_fn;
  396.     unsigned short index;
  397.     int ret;
  398.     unsigned char row, col;
  399.     unsigned long val;
  400.  
  401.     for (index = 0; index < 4; ++index) {
  402.         ret = pcibios_find_device (
  403.             (unsigned short) PCI_VENDOR_ID_NCR,
  404.             (unsigned short) PCI_DEVICE_ID_NCR_53C810,
  405.             index, &bus, &device_fn);
  406.         if (ret)
  407.             break;
  408.         printk ("ncr53c810 : at PCI bus %d, device %d, function %d.",
  409.             bus, ((device_fn & 0xf8) >> 3), (device_fn & 7));
  410.         for (row = 0; row < 0x3c; row += 0x10) {
  411.             printk ("\n    reg 0x%02x    ", row);
  412.             for (col = 0; col < 0x10; col += 4) {
  413.             if (!(ret = pcibios_read_config_dword (bus, device_fn, row+col, &val)))
  414.                 printk ("0x%08lx      ", val);
  415.             else
  416.                 printk ("error 0x%02x ", ret);
  417.             }
  418.         }
  419.         printk ("\n");
  420.     }
  421. }
  422.  
  423. char *pcibios_strerror (int error)
  424. {
  425.     static char buf[80];
  426.  
  427.     switch (error) {
  428.         case PCIBIOS_SUCCESSFUL:
  429.             return "SUCCESSFUL";
  430.  
  431.         case PCIBIOS_FUNC_NOT_SUPPORTED:
  432.             return "FUNC_NOT_SUPPORTED";
  433.  
  434.         case PCIBIOS_BAD_VENDOR_ID:
  435.             return "SUCCESSFUL";
  436.  
  437.         case PCIBIOS_DEVICE_NOT_FOUND:
  438.             return "DEVICE_NOT_FOUND";
  439.  
  440.         case PCIBIOS_BAD_REGISTER_NUMBER:
  441.             return "BAD_REGISTER_NUMBER";
  442.  
  443.         default:
  444.             sprintf (buf, "UNKNOWN RETURN 0x%x", error);
  445.             return buf;
  446.     }
  447. }
  448.  
  449.  
  450. /* Recognize multi-function device */
  451.  
  452. int multi_function(unsigned char bus,unsigned char dev_fn)
  453. {
  454.     unsigned char header;
  455.         pcibios_read_config_byte(
  456.             bus, dev_fn, (unsigned char) PCI_HEADER_TYPE, &header);
  457.         return (header&7==7);
  458. }
  459.  
  460. /* Returns Interrupt register */
  461.  
  462. int interrupt_decode(unsigned char bus,unsigned char dev_fn)
  463. {
  464.     unsigned char interrupt;
  465.         pcibios_read_config_byte(
  466.             bus, dev_fn, (unsigned char) PCI_INTERRUPT_LINE, &interrupt);
  467.         if (interrupt>16) return 0;
  468.         return interrupt;
  469. }
  470.  
  471. /* probe for being bist capable */
  472.  
  473. int bist_probe(unsigned char bus,unsigned char dev_fn)
  474. {
  475.     unsigned char       bist;
  476.         pcibios_read_config_byte(
  477.             bus, dev_fn, (unsigned char) PCI_BIST, &bist);
  478.         return (bist & PCI_BIST_CAPABLE !=0);
  479. }
  480.  
  481.  
  482. /* Get the chip revision */
  483.  
  484. int revision_decode(unsigned char bus,unsigned char dev_fn)
  485. {
  486.     unsigned char       revision;
  487.                pcibios_read_config_byte(
  488.             bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &revision);
  489.         return (int) revision;
  490. }
  491.  
  492.  
  493.  
  494. /* Gives the Class code using the 16 higher bits */
  495. /* of the PCI_CLASS_REVISION configuration register */
  496.  
  497. int class_decode(unsigned char bus,unsigned char dev_fn)
  498. {
  499.     int             i;
  500.     unsigned long       class;
  501.         pcibios_read_config_dword(
  502.             bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &class);
  503.         class=class >> 16;
  504.         for (i=0;i<PCI_CLASS_NUM-1;i++)
  505.             if (class==pci_class[i].class_id) break;
  506.         return i;
  507. }
  508.  
  509.  
  510. int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor_num)
  511. {
  512.     int             i;
  513.     unsigned short       device;
  514.  
  515.     pcibios_read_config_word(
  516.         bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device);
  517.     for (i=0;i<PCI_DEVICE_NUM;i++)
  518.         if ((device==pci_device[i].device_id)
  519.          && (pci_vendor[vendor_num].vendor_id==pci_device[i].vendor_id)) return i;
  520.     return 0x10000 + (int) device;
  521. }
  522.  
  523.  
  524. int vendor_decode(unsigned char bus,unsigned char dev_fn)
  525. {
  526.     int            i;
  527.     unsigned short       vendor;
  528.  
  529.     pcibios_read_config_word(
  530.         bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
  531.     for (i=0;i<PCI_VENDOR_NUM;i++)
  532.         if (vendor==pci_vendor[i].vendor_id) return i;
  533.     return 0x10000 + (int) vendor;
  534. }
  535.  
  536. #ifdef CONFIG_PCI_OPTIMIZE
  537.  
  538. /* Turn on/off PCI bridge optimisation. This should allow benchmarking. */
  539.  
  540. void burst_bridge(unsigned char bus,unsigned char dev_fn,unsigned char pos, int turn_on)
  541. {
  542.     int i;
  543.     unsigned char val;
  544.  
  545.     pos*=OPTIMISATION_NUM;
  546.     printk("PCI bridge optimisation.\n");
  547.     for (i=0;i<OPTIMISATION_NUM;i++)
  548.     {
  549.         printk("    %s : ",optimisation[i].type);
  550.         if (bridge_mapping[pos+i].address==0) printk("Not supported.");
  551.         else {
  552.             pcibios_read_config_byte(
  553.                 bus, dev_fn, bridge_mapping[pos+i].address, &val);
  554.             if ((val & bridge_mapping[pos+i].mask)==bridge_mapping[pos+i].value) 
  555.             {
  556.                 printk("%s.",optimisation[i].on);
  557.                 if (turn_on==0) 
  558.                 {
  559.                 pcibios_write_config_byte(
  560.                     bus, dev_fn, bridge_mapping[pos+i].address,
  561.                     (val | bridge_mapping[pos+i].mask) -
  562.                     bridge_mapping[pos+i].value);
  563.                 printk("Changed! now %s.",optimisation[i].off);
  564.                 }
  565.             } else {
  566.                 printk("%s.",optimisation[i].off);
  567.                 if (turn_on==1) 
  568.                 {
  569.                 pcibios_write_config_byte(
  570.                     bus, dev_fn, bridge_mapping[pos+i].address,
  571.                     (val & (0xff-bridge_mapping[pos+i].mask)) +
  572.                     bridge_mapping[pos+i].value);
  573.                 printk("Changed! now %s.",optimisation[i].on);
  574.                 }
  575.             }
  576.         }
  577.         printk("\n");
  578.     }
  579. }
  580.  
  581. #endif
  582.  
  583. /* In future version in case we detect a PCI to PCI bridge, we will go
  584. for a recursive device search*/
  585.  
  586. void probe_devices(unsigned char bus)
  587. {
  588.     unsigned long    res;
  589.     unsigned char    dev_fn;
  590.  
  591. /* For a mysterious reason, my PC crash if I try to probe device 31 function 7  */
  592. /* (i.e. dev_fn=0xff) It can be a bug in my BIOS, or I haven't understood all about */
  593. /* PCI */
  594.  
  595.  
  596.         for (dev_fn=0x0;dev_fn<0xff;dev_fn++) {
  597.             pcibios_read_config_dword(
  598.                 bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &res);
  599.  
  600. /* First we won't try to talk to non_present chip */
  601. /* Second, we get rid of non multi-function device that seems to be lazy  */
  602. /* and not fully decode the function number */
  603.  
  604.             if ((res!=0xffffffff) &&
  605.                 (((dev_fn & 7) == 0) || multi_function(bus,dev_fn))) {
  606.                 add_pci_resource( bus, dev_fn);
  607.             }
  608.         }
  609. }
  610.  
  611.  
  612. void probe_pci(void)
  613. {
  614.     if (pcibios_present()==0) {
  615.         printk("ProbePci PCI bios not detected.\n");
  616.         return;
  617.     }
  618.     printk( "Probing PCI hardware.\n");
  619.     probe_devices(0);
  620. }
  621.  
  622.  
  623. /*
  624.  * Function to add a resource to the pci list...
  625.  */
  626. void add_pci_resource(unsigned char bus, unsigned char dev_fn)
  627. {
  628.     pci_resource_t* new_pci;
  629.     pci_resource_t* temp;
  630.     int vendor_id, device_id;
  631. #ifdef CONFIG_PCI_OPTIMIZE
  632.     unsigned char bridge_id;
  633. #endif
  634.     /*
  635.      * Verify if we know about this chip. If not, print Vendor & Device id
  636.      * + ask for report.
  637.      */
  638.     vendor_id=vendor_decode(bus,dev_fn);
  639.     device_id=device_decode(bus,dev_fn,vendor_id);
  640.     if ((device_id & 0x10000)==0x10000)
  641.     {
  642.         printk("Unknown PCI device. PCI Vendor id=%x. PCI Device id=%x.\n",
  643.             vendor_id & 0xffff,device_id & 0xffff);
  644.         printk("PLEASE MAIL POTTER@CAO-VLSI.IBP.FR your hardware description and /proc/pci.\n");
  645.         return;
  646.     }
  647.     /*
  648.      * If the PCI agent is a known bridge, then configure it.
  649.      */
  650. #ifdef CONFIG_PCI_OPTIMIZE
  651.  
  652.     bridge_id=pci_device[device_id].bridge_id;
  653.     if (bridge_id != 0xff)
  654.     {
  655.         burst_bridge(bus,dev_fn,bridge_id,1); /* Burst bridge */
  656.     }
  657. #endif
  658.     /*
  659.      * Request and verify allocation of kernel RAM
  660.      */
  661.     if(pci_index > PCI_LIST_SIZE-1)
  662.     {
  663.         printk("PCI resource list full.\n");
  664.         return;
  665.     }
  666.  
  667.  
  668.     new_pci = &pci_table[pci_index];
  669.     pci_index++;
  670.  
  671.     /*
  672.      * Enter the new node into the list....
  673.      *
  674.      */
  675.     if(pci_list.next != NULL)
  676.     {
  677.         for(temp = pci_list.next; (temp->next); temp = temp->next)
  678.             /* nothing */;
  679.  
  680.         temp->next = new_pci;
  681.     }
  682.     else
  683.         pci_list.next = new_pci;
  684.  
  685.     /*
  686.      * Set the information for the node
  687.      */
  688.     new_pci->next = NULL;
  689.     new_pci->bus = bus;
  690.     new_pci->dev_fn = dev_fn;
  691.  
  692.     return;
  693. }
  694.  
  695.  
  696. int get_pci_list(char* buf)
  697. {
  698.     int pr, length;
  699.     pci_resource_t* temp = pci_list.next;
  700.  
  701.     pr = sprintf(buf, "PCI devices found :\n"); 
  702.     for (length = pr ; (temp) && (length<4000); temp = temp->next)
  703.     {
  704.         pr=vendor_decode(temp->bus,temp->dev_fn);
  705.  
  706.         length += sprintf(buf+length, "Bus %2d Device %3d Function %2d.\n",
  707.             (int)temp->bus,
  708.             (int)((temp->dev_fn & 0xf8) >> 3),
  709.             (int) (temp->dev_fn & 7));
  710.  
  711.         length += sprintf(buf+length, "    %s : %s %s (rev %d). ",
  712.             pci_class[class_decode(temp->bus, temp->dev_fn)].class_name,
  713.             pci_vendor[pr].vendor_name,
  714.             pci_device[device_decode(temp->bus, temp->dev_fn, pr)].device_name,
  715.             revision_decode(temp->bus, temp->dev_fn));
  716.  
  717.         if (bist_probe(temp->bus, temp->dev_fn))
  718.             length += sprintf(buf+length, "BIST capable. ");
  719.  
  720.         if ((pr = interrupt_decode(temp->bus, temp->dev_fn)) != 0)
  721.             length += sprintf(buf+length, "8259's interrupt %d.", pr);
  722.  
  723.         length += sprintf(buf+length, "\n");
  724.     }
  725.  
  726.     if (temp)
  727.         length += sprintf(buf+length, "4K limit reached!\n");
  728.  
  729.     return length;
  730. }
  731.  
  732.  
  733. #endif
  734.  
  735. unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
  736. {
  737.     union bios32 *check;
  738.     unsigned char sum;
  739.     int i, length;
  740.  
  741.     /*
  742.      * Follow the standard procedure for locating the BIOS32 Service
  743.      * directory by scanning the permissible address range from
  744.      * 0xe0000 through 0xfffff for a valid BIOS32 structure.
  745.      *
  746.      * The PCI BIOS doesn't seem to work too well on many machines,
  747.      * so we disable this unless it's really needed (NCR SCSI driver)
  748.      */
  749.  
  750.     for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
  751.         if (check->fields.signature != BIOS32_SIGNATURE)
  752.             continue;
  753.         length = check->fields.length * 16;
  754.         if (!length)
  755.             continue;
  756.         sum = 0;
  757.         for (i = 0; i < length ; ++i)
  758.             sum += check->chars[i];
  759.         if (sum != 0)
  760.             continue;
  761.         if (check->fields.revision != 0) {
  762.             printk("bios32_init : unsupported revision %d at 0x%p, mail drew@colorado.edu\n",
  763.                 check->fields.revision, check);
  764.             continue;
  765.         }
  766.         printk ("bios32_init : BIOS32 Service Directory structure at 0x%p\n", check);
  767.         if (!bios32_entry) {
  768.             if (check->fields.entry >= 0x100000) {
  769.                 printk("bios32_init: entry in high memory, unable to access\n");
  770.             } else {
  771.                 bios32_indirect.address = bios32_entry = check->fields.entry;
  772.                 printk ("bios32_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
  773.             }
  774.         } else {
  775.             printk ("bios32_init : multiple entries, mail drew@colorado.edu\n");
  776.             /*
  777.              * Jeremy Fitzhardinge reports at least one PCI BIOS
  778.              * with two different service directories, and as both
  779.              * worked for him, we'll just mention the fact, and
  780.              * not actually disallow it..
  781.              */
  782. #if 0
  783.             return memory_start;
  784. #endif
  785.         }
  786.     }
  787. #ifdef CONFIG_PCI
  788.     if (bios32_entry) {
  789.         memory_start = pcibios_init (memory_start, memory_end);
  790.         probe_pci();
  791.     }
  792. #endif
  793.     return memory_start;
  794. }
  795.  
  796.  
  797.  
  798.