root/arch/i386/kernel/bios32.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bios32_service
  2. pcibios_init
  3. pcibios_present
  4. pcibios_find_class
  5. pcibios_find_device
  6. pcibios_read_config_byte
  7. pcibios_read_config_word
  8. pcibios_read_config_dword
  9. pcibios_write_config_byte
  10. pcibios_write_config_word
  11. pcibios_write_config_dword
  12. NCR53c810_test
  13. pcibios_strerror
  14. multi_function
  15. interrupt_decode
  16. bist_probe
  17. revision_decode
  18. class_decode
  19. device_decode
  20. vendor_decode
  21. burst_bridge
  22. probe_devices
  23. probe_pci
  24. add_pci_resource
  25. get_pci_list
  26. bios32_init

   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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232         return pcibios_entry ? 1 : 0;
 233 }
 234 
 235 int pcibios_find_class (unsigned long class_code, unsigned short index,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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,
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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                         bios32_indirect.address = bios32_entry = check->fields.entry;
 769                         printk ("bios32_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
 770                 } else {
 771                         printk ("bios32_init : multiple entries, mail drew@colorado.edu\n");
 772                         /*
 773                          * Jeremy Fitzhardinge reports at least one PCI BIOS
 774                          * with two different service directories, and as both
 775                          * worked for him, we'll just mention the fact, and
 776                          * not actually disallow it..
 777                          */
 778 #if 0
 779                         return memory_start;
 780 #endif
 781                 }
 782         }
 783 #ifdef CONFIG_PCI
 784         if (bios32_entry) {
 785                 memory_start = pcibios_init (memory_start, memory_end);
 786                 probe_pci();
 787         }
 788 #endif
 789         return memory_start;
 790 }
 791 
 792 
 793 

/* [previous][next][first][last][top][bottom][index][help] */