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_decod
  16. bist_probe
  17. revision_decode
  18. class_decode
  19. device_decode
  20. vendor_decode
  21. info
  22. probe_devices
  23. probe_pci
  24. 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  * Pciprobe added by Frederic Potter 1994
  16  *      Potter@Cao-Vlsi.Ibp.FR
  17  *
  18  *
  19  * For more information, please consult
  20  *
  21  * PCI BIOS Specification Revision
  22  * PCI Local Bus Specification
  23  * PCI System Design Guide
  24  *
  25  * PCI Special Interest Group
  26  * M/S HF3-15A
  27  * 5200 N.E. Elam Young Parkway
  28  * Hillsboro, Oregon 97124-6497
  29  * +1 (503) 696-2000
  30  * +1 (800) 433-5177
  31  *
  32  * Manuals are $25 each or $50 for all three, plus $7 shipping
  33  * within the United States, $35 abroad.
  34  *
  35  *
  36  * CHANGELOG :
  37  * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
  38  *      Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
  39  */
  40 
  41 #include <linux/config.h>
  42 #include <linux/kernel.h>
  43 #include <linux/bios32.h>
  44 #include <linux/pci.h>
  45 
  46 #include <asm/segment.h>
  47 
  48 #define PCIBIOS_PCI_FUNCTION_ID         0xb1XX
  49 #define PCIBIOS_PCI_BIOS_PRESENT        0xb101
  50 #define PCIBIOS_FIND_PCI_DEVICE         0xb102
  51 #define PCIBIOS_FIND_PCI_CLASS_CODE     0xb103
  52 #define PCIBIOS_GENERATE_SPECIAL_CYCLE  0xb106
  53 #define PCIBIOS_READ_CONFIG_BYTE        0xb108
  54 #define PCIBIOS_READ_CONFIG_WORD        0xb109
  55 #define PCIBIOS_READ_CONFIG_DWORD       0xb10a
  56 #define PCIBIOS_WRITE_CONFIG_BYTE       0xb10b
  57 #define PCIBIOS_WRITE_CONFIG_WORD       0xb10c
  58 #define PCIBIOS_WRITE_CONFIG_DWORD      0xb10d
  59 
  60 /* BIOS32 signature: "_32_" */
  61 #define BIOS32_SIGNATURE        (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
  62 
  63 /* PCI signature: "PCI " */
  64 #define PCI_SIGNATURE           (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
  65 
  66 /* PCI service signature: "$PCI" */
  67 #define PCI_SERVICE             (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
  68 
  69 /*
  70  * This is the standard structure used to identify the entry point
  71  * to the BIOS32 Service Directory, as documented in
  72  *      Standard BIOS 32-bit Service Directory Proposal
  73  *      Revision 0.4 May 24, 1993
  74  *      Phoenix Technologies Ltd.
  75  *      Norwood, MA
  76  * and the PCI BIOS specification.
  77  */
  78 
  79 union bios32 {
  80         struct {
  81                 unsigned long signature;        /* _32_ */
  82                 unsigned long entry;            /* 32 bit physical address */
  83                 unsigned char revision;         /* Revision level, 0 */
  84                 unsigned char length;           /* Length in paragraphs should be 01 */
  85                 unsigned char checksum;         /* All bytes must add up to zero */
  86                 unsigned char reserved[5];      /* Must be zero */
  87         } fields;
  88         char chars[16];
  89 };
  90 
  91 /*
  92  * Physical address of the service directory.  I don't know if we're
  93  * allowed to have more than one of these or not, so just in case
  94  * we'll make bios32_init() take a memory start parameter and store
  95  * the array there.
  96  */
  97 
  98 static unsigned long bios32_entry = 0;
  99 static struct {
 100         unsigned long address;
 101         unsigned short segment;
 102 } bios32_indirect = { 0, KERNEL_CS };
 103 
 104 #ifdef CONFIG_PCI
 105 /*
 106  * Returns the entry point for the given service, NULL on error
 107  */
 108 
 109 static unsigned long bios32_service(unsigned long service)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         unsigned char return_code;      /* %al */
 112         unsigned long address;          /* %ebx */
 113         unsigned long length;           /* %ecx */
 114         unsigned long entry;            /* %edx */
 115 
 116         __asm__("lcall (%%edi)"
 117                 : "=a" (return_code),
 118                   "=b" (address),
 119                   "=c" (length),
 120                   "=d" (entry)
 121                 : "0" (service),
 122                   "1" (0),
 123                   "D" (&bios32_indirect));
 124 
 125         switch (return_code) {
 126                 case 0:
 127                         return address + entry;
 128                 case 0x80:      /* Not present */
 129                         printk("bios32_service(%ld) : not present\n", service);
 130                         return 0;
 131                 default: /* Shouldn't happen */
 132                         printk("bios32_service(%ld) : returned 0x%x, mail drew@colorado.edu\n",
 133                                 service, return_code);
 134                         return 0;
 135         }
 136 }
 137 
 138 static long pcibios_entry = 0;
 139 static struct {
 140         unsigned long address;
 141         unsigned short segment;
 142 } pci_indirect = { 0, KERNEL_CS };
 143 
 144 void NCR53c810_test(void);
 145 
 146 static unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148         unsigned long signature;
 149         unsigned char present_status;
 150         unsigned char major_revision;
 151         unsigned char minor_revision;
 152         int pack;
 153 
 154         if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
 155                 pci_indirect.address = pcibios_entry;
 156 
 157                 __asm__("lcall (%%edi)\n\t"
 158                         "jc 1f\n\t"
 159                         "xor %%ah, %%ah\n"
 160                         "1:\tshl $8, %%eax\n\t"
 161                         "movw %%bx, %%ax"
 162                         : "=d" (signature),
 163                           "=a" (pack)
 164                         : "1" (PCIBIOS_PCI_BIOS_PRESENT),
 165                           "D" (&pci_indirect)
 166                         : "bx", "cx");
 167 
 168                 present_status = (pack >> 16) & 0xff;
 169                 major_revision = (pack >> 8) & 0xff;
 170                 minor_revision = pack & 0xff;
 171                 if (present_status || (signature != PCI_SIGNATURE)) {
 172                         printk ("pcibios_init : %s : BIOS32 Service Directory says PCI BIOS is present,\n"
 173                                 "       but PCI_BIOS_PRESENT subfunction fails with present status of 0x%x\n"
 174                                 "       and signature of 0x%08lx (%c%c%c%c).  mail drew@Colorado.EDU\n",
 175                                 (signature == PCI_SIGNATURE) ?  "WARNING" : "ERROR",
 176                                 present_status, signature,
 177                                 (char) (signature >>  0), (char) (signature >>  8),
 178                                 (char) (signature >> 16), (char) (signature >> 24));
 179 
 180                         if (signature != PCI_SIGNATURE)
 181                                 pcibios_entry = 0;
 182                 }
 183                 if (pcibios_entry) {
 184                         printk ("pcibios_init : PCI BIOS revision %x.%02x entry at 0x%lx\n",
 185                                 major_revision, minor_revision, pcibios_entry);
 186                 }
 187         }
 188 
 189 #if 0
 190         NCR53c810_test();
 191 #endif
 192         return memory_start;
 193 }
 194 
 195 int pcibios_present(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197         return pcibios_entry ? 1 : 0;
 198 }
 199 
 200 int pcibios_find_class (unsigned long class_code, unsigned short index,
     /* [previous][next][first][last][top][bottom][index][help] */
 201         unsigned char *bus, unsigned char *device_fn)
 202 {
 203         unsigned long bx;
 204         unsigned long ret;
 205 
 206         __asm__ ("lcall (%%edi)\n\t"
 207                 "jc 1f\n\t"
 208                 "xor %%ah, %%ah\n"
 209                 "1:"
 210                 : "=b" (bx),
 211                   "=a" (ret)
 212                 : "1" (PCIBIOS_FIND_PCI_CLASS_CODE),
 213                   "c" (class_code),
 214                   "S" ((int) index),
 215                   "D" (&pci_indirect));
 216         *bus = (bx >> 8) & 0xff;
 217         *device_fn = bx & 0xff;
 218         return (int) (ret & 0xff00) >> 8;
 219 }
 220 
 221 
 222 int pcibios_find_device (unsigned short vendor, unsigned short device_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 223         unsigned short index, unsigned char *bus, unsigned char *device_fn)
 224 {
 225         unsigned short bx;
 226         unsigned short ret;
 227 
 228         __asm__("lcall (%%edi)\n\t"
 229                 "jc 1f\n\t"
 230                 "xor %%ah, %%ah\n"
 231                 "1:"
 232                 : "=b" (bx),
 233                   "=a" (ret)
 234                 : "1" (PCIBIOS_FIND_PCI_DEVICE),
 235                   "c" (device_id),
 236                   "d" (vendor),
 237                   "S" ((int) index),
 238                   "D" (&pci_indirect));
 239         *bus = (bx >> 8) & 0xff;
 240         *device_fn = bx & 0xff;
 241         return (int) (ret & 0xff00) >> 8;
 242 }
 243 
 244 int pcibios_read_config_byte(unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 245         unsigned char device_fn, unsigned char where, unsigned char *value)
 246 {
 247         unsigned long ret;
 248         unsigned long bx = (bus << 8) | device_fn;
 249 
 250         __asm__("lcall (%%esi)\n\t"
 251                 "jc 1f\n\t"
 252                 "xor %%ah, %%ah\n"
 253                 "1:"
 254                 : "=c" (*value),
 255                   "=a" (ret)
 256                 : "1" (PCIBIOS_READ_CONFIG_BYTE),
 257                   "b" (bx),
 258                   "D" ((long) where),
 259                   "S" (&pci_indirect));
 260         return (int) (ret & 0xff00) >> 8;
 261 }
 262 
 263 int pcibios_read_config_word (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 264         unsigned char device_fn, unsigned char where, unsigned short *value)
 265 {
 266         unsigned long ret;
 267         unsigned long bx = (bus << 8) | device_fn;
 268 
 269         __asm__("lcall (%%esi)\n\t"
 270                 "jc 1f\n\t"
 271                 "xor %%ah, %%ah\n"
 272                 "1:"
 273                 : "=c" (*value),
 274                   "=a" (ret)
 275                 : "1" (PCIBIOS_READ_CONFIG_WORD),
 276                   "b" (bx),
 277                   "D" ((long) where),
 278                   "S" (&pci_indirect));
 279         return (int) (ret & 0xff00) >> 8;
 280 }
 281 
 282 int pcibios_read_config_dword (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 283         unsigned char device_fn, unsigned char where, unsigned long *value)
 284 {
 285         unsigned long ret;
 286         unsigned long bx = (bus << 8) | device_fn;
 287 
 288         __asm__("lcall (%%esi)\n\t"
 289                 "jc 1f\n\t"
 290                 "xor %%ah, %%ah\n"
 291                 "1:"
 292                 : "=c" (*value),
 293                   "=a" (ret)
 294                 : "1" (PCIBIOS_READ_CONFIG_DWORD),
 295                   "b" (bx),
 296                   "D" ((long) where),
 297                   "S" (&pci_indirect));
 298         return (int) (ret & 0xff00) >> 8;
 299 }
 300 
 301 int pcibios_write_config_byte (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 302         unsigned char device_fn, unsigned char where, unsigned char value)
 303 {
 304         unsigned long ret;
 305         unsigned long bx = (bus << 8) | device_fn;
 306 
 307         __asm__("lcall (%%esi)\n\t"
 308                 "jc 1f\n\t"
 309                 "xor %%ah, %%ah\n"
 310                 "1:"
 311                 : "=a" (ret)
 312                 : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
 313                   "c" (value),
 314                   "b" (bx),
 315                   "D" ((long) where),
 316                   "S" (&pci_indirect));
 317         return (int) (ret & 0xff00) >> 8;
 318 }
 319 
 320 int pcibios_write_config_word (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 321         unsigned char device_fn, unsigned char where, unsigned short value)
 322 {
 323         unsigned long ret;
 324         unsigned long bx = (bus << 8) | device_fn;
 325 
 326         __asm__("lcall (%%esi)\n\t"
 327                 "jc 1f\n\t"
 328                 "xor %%ah, %%ah\n"
 329                 "1:"
 330                 : "=a" (ret)
 331                 : "0" (PCIBIOS_WRITE_CONFIG_WORD),
 332                   "c" (value),
 333                   "b" (bx),
 334                   "D" ((long) where),
 335                   "S" (&pci_indirect));
 336         return (int) (ret & 0xff00) >> 8;
 337 }
 338 
 339 int pcibios_write_config_dword (unsigned char bus,
     /* [previous][next][first][last][top][bottom][index][help] */
 340         unsigned char device_fn, unsigned char where, unsigned long value)
 341 {
 342         unsigned long ret;
 343         unsigned long bx = (bus << 8) | device_fn;
 344 
 345         __asm__("lcall (%%esi)\n\t"
 346                 "jc 1f\n\t"
 347                 "xor %%ah, %%ah\n"
 348                 "1:"
 349                 : "=a" (ret)
 350                 : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
 351                   "c" (value),
 352                   "b" (bx),
 353                   "D" ((long) where),
 354                   "S" (&pci_indirect));
 355         return (int) (ret & 0xff00) >> 8;
 356 }
 357 
 358 void NCR53c810_test(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360         unsigned char bus, device_fn;
 361         unsigned short index;
 362         int ret;
 363         unsigned char row, col;
 364         unsigned long val;
 365 
 366         for (index = 0; index < 4; ++index) {
 367                 ret = pcibios_find_device (
 368                         (unsigned short) PCI_VENDOR_ID_NCR,
 369                         (unsigned short) PCI_DEVICE_ID_NCR_53C810,
 370                         index, &bus, &device_fn);
 371                 if (ret)
 372                         break;
 373                 printk ("ncr53c810 : at PCI bus %d, device %d, function %d.",
 374                         bus, ((device_fn & 0xf8) >> 3), (device_fn & 7));
 375                 for (row = 0; row < 0x3c; row += 0x10) {
 376                         printk ("\n     reg 0x%02x      ", row);
 377                         for (col = 0; col < 0x10; col += 4) {
 378                         if (!(ret = pcibios_read_config_dword (bus, device_fn, row+col, &val)))
 379                                 printk ("0x%08lx          ", val);
 380                         else
 381                                 printk ("error 0x%02x ", ret);
 382                         }
 383                 }
 384                 printk ("\n");
 385         }
 386 }
 387 
 388 char *pcibios_strerror (int error)
     /* [previous][next][first][last][top][bottom][index][help] */
 389 {
 390         static char buf[80];
 391 
 392         switch (error) {
 393                 case PCIBIOS_SUCCESSFUL:
 394                         return "SUCCESSFUL";
 395 
 396                 case PCIBIOS_FUNC_NOT_SUPPORTED:
 397                         return "FUNC_NOT_SUPPORTED";
 398 
 399                 case PCIBIOS_BAD_VENDOR_ID:
 400                         return "SUCCESSFUL";
 401 
 402                 case PCIBIOS_DEVICE_NOT_FOUND:
 403                         return "DEVICE_NOT_FOUND";
 404 
 405                 case PCIBIOS_BAD_REGISTER_NUMBER:
 406                         return "BAD_REGISTER_NUMBER";
 407 
 408                 default:
 409                         sprintf (buf, "UNKNOWN RETURN 0x%x", error);
 410                         return buf;
 411         }
 412 }
 413 
 414 
 415 /* Recognize multi-function device */
 416 
 417 int multi_function(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 418 {
 419         unsigned char header;
 420                 pcibios_read_config_byte(
 421                         bus, dev_fn, (unsigned char) PCI_HEADER_TYPE, &header);
 422                 return (header&7==7);
 423 }
 424 
 425 /* Returns Interrupt register */
 426 
 427 int interrupt_decod(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 428 {
 429         unsigned char interrupt;
 430                 pcibios_read_config_byte(
 431                         bus, dev_fn, (unsigned char) PCI_INTERRUPT_LINE, &interrupt);
 432                 if (interrupt>16) return 0;
 433                 return interrupt;
 434 }
 435 
 436 /* probe for being bist capable */
 437 
 438 int bist_probe(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 439 {
 440         unsigned char           bist;
 441                 pcibios_read_config_byte(
 442                         bus, dev_fn, (unsigned char) PCI_BIST, &bist);
 443                 return (bist & PCI_BIST_CAPABLE !=0);
 444 }
 445 
 446 
 447 /* Get the chip revision */
 448 
 449 int revision_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 450 {
 451         unsigned char           revision;
 452                 pcibios_read_config_byte(
 453                         bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &revision);
 454                 return (int) revision;
 455 }
 456 
 457 
 458 
 459 /* Gives the Class code using the 16 higher bits */
 460 /* of the PCI_CLASS_REVISION configuration register */
 461 
 462 int class_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 463 {
 464         struct pci_class_type   pci_class[PCI_CLASS_NUM+1] = PCI_CLASS_TYPE;
 465         int                     i;
 466         unsigned long           class;
 467                 pcibios_read_config_dword(
 468                         bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &class);
 469                 class=class >> 16;
 470                 for (i=0;i<PCI_CLASS_NUM;i++) 
 471                         if (class==pci_class[i].class_id) break;
 472                 return i;
 473 }
 474 
 475 
 476 
 477 
 478 int device_decode(unsigned char bus,unsigned char dev_fn,unsigned short vendor)
     /* [previous][next][first][last][top][bottom][index][help] */
 479 {
 480         struct pci_device_type  pci_device[PCI_DEVICE_NUM+1] = PCI_DEVICE_TYPE;
 481         int                     i;
 482         unsigned short          device;
 483                 pcibios_read_config_word(
 484                         bus, dev_fn, (unsigned char) PCI_DEVICE_ID, &device);
 485                 for (i=0;i<PCI_DEVICE_NUM;i++) 
 486                         if ((device==pci_device[i].device_id) 
 487                          && (vendor==pci_device[i].vendor_id)) return i;
 488                 printk("Device id=%x ",device);
 489                 return i;
 490 }
 491 
 492 
 493 
 494 
 495 
 496 
 497 int vendor_decode(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 498 {
 499         struct pci_vendor_type  pci_vendor[PCI_VENDOR_NUM+1] = PCI_VENDOR_TYPE;
 500         int                     i;
 501         unsigned short          vendor;
 502 
 503                 pcibios_read_config_word(
 504                         bus, dev_fn, (unsigned char) PCI_VENDOR_ID, &vendor);
 505                 for (i=0;i<PCI_VENDOR_NUM;i++) 
 506                         if (vendor==pci_vendor[i].vendor_id) return i;
 507                 printk("Vendor id=%x ",vendor);
 508                 return i;
 509 }
 510 
 511 
 512 
 513 
 514 /* Call all the information procedures */
 515 
 516 void info(unsigned char bus,unsigned char dev_fn)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518         struct  pci_class_type          pci_class[PCI_CLASS_NUM+1] = PCI_CLASS_TYPE;
 519         struct  pci_vendor_type         pci_vendor[PCI_VENDOR_NUM+1] = PCI_VENDOR_TYPE;
 520         struct  pci_device_type         pci_device[PCI_DEVICE_NUM+1] = PCI_DEVICE_TYPE;
 521         int                             pr;
 522                 pr=vendor_decode(bus,dev_fn);
 523                 printk("       %s : %s %s (rev %d). "
 524                         ,pci_class[class_decode(bus,dev_fn)].class_name
 525                         ,pci_vendor[pr].vendor_name
 526                         ,pci_device[device_decode(bus,dev_fn,pci_vendor[pr].vendor_id)].device_name
 527                         ,revision_decode(bus,dev_fn));
 528                         
 529                 if (bist_probe(bus,dev_fn))
 530                         printk("BIST capable. ");
 531                 if ((pr=interrupt_decod(bus,dev_fn))!=0)
 532                         printk("8259's interrupt %d.",pr);
 533                 printk("\n");
 534 }
 535 
 536 /* In futur version in case we detect a PCI to PCi bridge, we will go 
 537 for a recursive device search*/
 538 
 539 void probe_devices(unsigned char bus)
     /* [previous][next][first][last][top][bottom][index][help] */
 540 {
 541         unsigned long   res;
 542         unsigned char   dev_fn;
 543 
 544 /* For a mysterious reason, my PC crash if I try to probe device 31 function 7  */
 545 /* (i.e. dev_fn=0xff) It can be a bug in my BIOS, or I havn't understood all about */
 546 /* PCI */
 547 
 548 
 549                 for (dev_fn=0x0;dev_fn<0xff;dev_fn++) {
 550                         pcibios_read_config_dword(
 551                                 bus, dev_fn, (unsigned char) PCI_CLASS_REVISION, &res);
 552 
 553 /* First we won't try to talk to non_present chip */
 554 /* Second, we get rid of non multi-function device that seems to be lazy  */
 555 /* and not fully decode the function number */
 556 
 557                         if ((res!=0xffffffff) && 
 558                                 (((dev_fn & 7) == 0) || multi_function(bus,dev_fn))) {
 559                                 printk("Bus %d Device %d Function %d.\n",
 560                                                 (int) bus,
 561                                                 (int) ((dev_fn & 0xf8) >> 3),
 562                                                 (int) (dev_fn & 7));
 563                                 info(bus,dev_fn);
 564                         }
 565                 }
 566 }
 567 
 568 
 569 
 570 
 571 
 572 
 573 
 574 void probe_pci(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 575 {
 576         if (pcibios_present()==0) printk("ProbePci PCI bios not detected.\n");
 577          else {
 578                 printk( "Probing PCI hardware.\n");
 579                 probe_devices(0);
 580         }
 581 }
 582 
 583 #endif
 584 
 585 unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
     /* [previous][next][first][last][top][bottom][index][help] */
 586 {
 587         union bios32 *check;
 588         unsigned char sum;
 589         int i, length;
 590 
 591         /*
 592          * Follow the standard procedure for locating the BIOS32 Service
 593          * directory by scanning the permissible address range from
 594          * 0xe0000 through 0xfffff for a valid BIOS32 structure.
 595          *
 596          * The PCI BIOS doesn't seem to work too well on many machines,
 597          * so we disable this unless it's really needed (NCR SCSI driver)
 598          */
 599 
 600         for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
 601                 if (check->fields.signature != BIOS32_SIGNATURE)
 602                         continue;
 603                 length = check->fields.length * 16;
 604                 if (!length)
 605                         continue;
 606                 sum = 0;
 607                 for (i = 0; i < length ; ++i)
 608                         sum += check->chars[i];
 609                 if (sum != 0)
 610                         continue;
 611                 if (check->fields.revision != 0) {
 612                         printk("bios32_init : unsupported revision %d at 0x%p, mail drew@colorado.edu\n",
 613                                 check->fields.revision, check);
 614                         continue;
 615                 }
 616                 printk ("bios32_init : BIOS32 Service Directory structure at 0x%p\n", check);
 617                 if (!bios32_entry) {
 618                         bios32_indirect.address = bios32_entry = check->fields.entry;
 619                         printk ("bios32_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
 620                 } else {
 621                         printk ("bios32_init : multiple entries, mail drew@colorado.edu\n");
 622                         /*
 623                          * Jeremy Fitzhardinge reports at least one PCI BIOS
 624                          * with two different service directories, and as both
 625                          * worked for him, we'll just mention the fact, and
 626                          * not actually disallow it..
 627                          */
 628 #if 0
 629                         return memory_start;
 630 #endif
 631                 }
 632         }
 633 #ifdef CONFIG_PCI
 634         if (bios32_entry) {
 635                 memory_start = pcibios_init (memory_start, memory_end);
 636                 probe_pci();
 637         }
 638 #endif
 639         return memory_start;
 640 }

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