Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * BIOS32 and PCI BIOS handling.
0004  */
0005 
0006 #include <linux/pci.h>
0007 #include <linux/init.h>
0008 #include <linux/slab.h>
0009 #include <linux/module.h>
0010 #include <linux/uaccess.h>
0011 
0012 #include <asm/pci_x86.h>
0013 #include <asm/e820/types.h>
0014 #include <asm/pci-functions.h>
0015 #include <asm/set_memory.h>
0016 
0017 /* BIOS32 signature: "_32_" */
0018 #define BIOS32_SIGNATURE    (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
0019 
0020 /* PCI signature: "PCI " */
0021 #define PCI_SIGNATURE       (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
0022 
0023 /* PCI service signature: "$PCI" */
0024 #define PCI_SERVICE     (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
0025 
0026 /* PCI BIOS hardware mechanism flags */
0027 #define PCIBIOS_HW_TYPE1        0x01
0028 #define PCIBIOS_HW_TYPE2        0x02
0029 #define PCIBIOS_HW_TYPE1_SPEC       0x10
0030 #define PCIBIOS_HW_TYPE2_SPEC       0x20
0031 
0032 int pcibios_enabled;
0033 
0034 /* According to the BIOS specification at:
0035  * http://members.datafast.net.au/dft0802/specs/bios21.pdf, we could
0036  * restrict the x zone to some pages and make it ro. But this may be
0037  * broken on some bios, complex to handle with static_protections.
0038  * We could make the 0xe0000-0x100000 range rox, but this can break
0039  * some ISA mapping.
0040  *
0041  * So we let's an rw and x hole when pcibios is used. This shouldn't
0042  * happen for modern system with mmconfig, and if you don't want it
0043  * you could disable pcibios...
0044  */
0045 static inline void set_bios_x(void)
0046 {
0047     pcibios_enabled = 1;
0048     set_memory_x(PAGE_OFFSET + BIOS_BEGIN, (BIOS_END - BIOS_BEGIN) >> PAGE_SHIFT);
0049     if (__supported_pte_mask & _PAGE_NX)
0050         printk(KERN_INFO "PCI: PCI BIOS area is rw and x. Use pci=nobios if you want it NX.\n");
0051 }
0052 
0053 /*
0054  * This is the standard structure used to identify the entry point
0055  * to the BIOS32 Service Directory, as documented in
0056  *  Standard BIOS 32-bit Service Directory Proposal
0057  *  Revision 0.4 May 24, 1993
0058  *  Phoenix Technologies Ltd.
0059  *  Norwood, MA
0060  * and the PCI BIOS specification.
0061  */
0062 
0063 union bios32 {
0064     struct {
0065         unsigned long signature;    /* _32_ */
0066         unsigned long entry;        /* 32 bit physical address */
0067         unsigned char revision;     /* Revision level, 0 */
0068         unsigned char length;       /* Length in paragraphs should be 01 */
0069         unsigned char checksum;     /* All bytes must add up to zero */
0070         unsigned char reserved[5];  /* Must be zero */
0071     } fields;
0072     char chars[16];
0073 };
0074 
0075 /*
0076  * Physical address of the service directory.  I don't know if we're
0077  * allowed to have more than one of these or not, so just in case
0078  * we'll make pcibios_present() take a memory start parameter and store
0079  * the array there.
0080  */
0081 
0082 static struct {
0083     unsigned long address;
0084     unsigned short segment;
0085 } bios32_indirect __initdata = { 0, __KERNEL_CS };
0086 
0087 /*
0088  * Returns the entry point for the given service, NULL on error
0089  */
0090 
0091 static unsigned long __init bios32_service(unsigned long service)
0092 {
0093     unsigned char return_code;  /* %al */
0094     unsigned long address;      /* %ebx */
0095     unsigned long length;       /* %ecx */
0096     unsigned long entry;        /* %edx */
0097     unsigned long flags;
0098 
0099     local_irq_save(flags);
0100     __asm__("lcall *(%%edi); cld"
0101         : "=a" (return_code),
0102           "=b" (address),
0103           "=c" (length),
0104           "=d" (entry)
0105         : "0" (service),
0106           "1" (0),
0107           "D" (&bios32_indirect));
0108     local_irq_restore(flags);
0109 
0110     switch (return_code) {
0111         case 0:
0112             return address + entry;
0113         case 0x80:  /* Not present */
0114             printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
0115             return 0;
0116         default: /* Shouldn't happen */
0117             printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
0118                 service, return_code);
0119             return 0;
0120     }
0121 }
0122 
0123 static struct {
0124     unsigned long address;
0125     unsigned short segment;
0126 } pci_indirect __ro_after_init = {
0127     .address = 0,
0128     .segment = __KERNEL_CS,
0129 };
0130 
0131 static int pci_bios_present __ro_after_init;
0132 
0133 static int __init check_pcibios(void)
0134 {
0135     u32 signature, eax, ebx, ecx;
0136     u8 status, major_ver, minor_ver, hw_mech;
0137     unsigned long flags, pcibios_entry;
0138 
0139     if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
0140         pci_indirect.address = pcibios_entry + PAGE_OFFSET;
0141 
0142         local_irq_save(flags);
0143         __asm__(
0144             "lcall *(%%edi); cld\n\t"
0145             "jc 1f\n\t"
0146             "xor %%ah, %%ah\n"
0147             "1:"
0148             : "=d" (signature),
0149               "=a" (eax),
0150               "=b" (ebx),
0151               "=c" (ecx)
0152             : "1" (PCIBIOS_PCI_BIOS_PRESENT),
0153               "D" (&pci_indirect)
0154             : "memory");
0155         local_irq_restore(flags);
0156 
0157         status = (eax >> 8) & 0xff;
0158         hw_mech = eax & 0xff;
0159         major_ver = (ebx >> 8) & 0xff;
0160         minor_ver = ebx & 0xff;
0161         if (pcibios_last_bus < 0)
0162             pcibios_last_bus = ecx & 0xff;
0163         DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
0164             status, hw_mech, major_ver, minor_ver, pcibios_last_bus);
0165         if (status || signature != PCI_SIGNATURE) {
0166             printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found\n",
0167                 status, signature);
0168             return 0;
0169         }
0170         printk(KERN_INFO "PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
0171             major_ver, minor_ver, pcibios_entry, pcibios_last_bus);
0172 #ifdef CONFIG_PCI_DIRECT
0173         if (!(hw_mech & PCIBIOS_HW_TYPE1))
0174             pci_probe &= ~PCI_PROBE_CONF1;
0175         if (!(hw_mech & PCIBIOS_HW_TYPE2))
0176             pci_probe &= ~PCI_PROBE_CONF2;
0177 #endif
0178         return 1;
0179     }
0180     return 0;
0181 }
0182 
0183 static int pci_bios_read(unsigned int seg, unsigned int bus,
0184              unsigned int devfn, int reg, int len, u32 *value)
0185 {
0186     unsigned long result = 0;
0187     unsigned long flags;
0188     unsigned long bx = (bus << 8) | devfn;
0189     u16 number = 0, mask = 0;
0190 
0191     WARN_ON(seg);
0192     if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
0193         return -EINVAL;
0194 
0195     raw_spin_lock_irqsave(&pci_config_lock, flags);
0196 
0197     switch (len) {
0198     case 1:
0199         number = PCIBIOS_READ_CONFIG_BYTE;
0200         mask = 0xff;
0201         break;
0202     case 2:
0203         number = PCIBIOS_READ_CONFIG_WORD;
0204         mask = 0xffff;
0205         break;
0206     case 4:
0207         number = PCIBIOS_READ_CONFIG_DWORD;
0208         break;
0209     }
0210 
0211     __asm__("lcall *(%%esi); cld\n\t"
0212         "jc 1f\n\t"
0213         "xor %%ah, %%ah\n"
0214         "1:"
0215         : "=c" (*value),
0216           "=a" (result)
0217         : "1" (number),
0218           "b" (bx),
0219           "D" ((long)reg),
0220           "S" (&pci_indirect));
0221     /*
0222      * Zero-extend the result beyond 8 or 16 bits, do not trust the
0223      * BIOS having done it:
0224      */
0225     if (mask)
0226         *value &= mask;
0227 
0228     raw_spin_unlock_irqrestore(&pci_config_lock, flags);
0229 
0230     return (int)((result & 0xff00) >> 8);
0231 }
0232 
0233 static int pci_bios_write(unsigned int seg, unsigned int bus,
0234               unsigned int devfn, int reg, int len, u32 value)
0235 {
0236     unsigned long result = 0;
0237     unsigned long flags;
0238     unsigned long bx = (bus << 8) | devfn;
0239     u16 number = 0;
0240 
0241     WARN_ON(seg);
0242     if ((bus > 255) || (devfn > 255) || (reg > 255)) 
0243         return -EINVAL;
0244 
0245     raw_spin_lock_irqsave(&pci_config_lock, flags);
0246 
0247     switch (len) {
0248     case 1:
0249         number = PCIBIOS_WRITE_CONFIG_BYTE;
0250         break;
0251     case 2:
0252         number = PCIBIOS_WRITE_CONFIG_WORD;
0253         break;
0254     case 4:
0255         number = PCIBIOS_WRITE_CONFIG_DWORD;
0256         break;
0257     }
0258 
0259     __asm__("lcall *(%%esi); cld\n\t"
0260         "jc 1f\n\t"
0261         "xor %%ah, %%ah\n"
0262         "1:"
0263         : "=a" (result)
0264         : "0" (number),
0265           "c" (value),
0266           "b" (bx),
0267           "D" ((long)reg),
0268           "S" (&pci_indirect));
0269 
0270     raw_spin_unlock_irqrestore(&pci_config_lock, flags);
0271 
0272     return (int)((result & 0xff00) >> 8);
0273 }
0274 
0275 
0276 /*
0277  * Function table for BIOS32 access
0278  */
0279 
0280 static const struct pci_raw_ops pci_bios_access = {
0281     .read =     pci_bios_read,
0282     .write =    pci_bios_write
0283 };
0284 
0285 /*
0286  * Try to find PCI BIOS.
0287  */
0288 
0289 static const struct pci_raw_ops *__init pci_find_bios(void)
0290 {
0291     union bios32 *check;
0292     unsigned char sum;
0293     int i, length;
0294 
0295     /*
0296      * Follow the standard procedure for locating the BIOS32 Service
0297      * directory by scanning the permissible address range from
0298      * 0xe0000 through 0xfffff for a valid BIOS32 structure.
0299      */
0300 
0301     for (check = (union bios32 *) __va(0xe0000);
0302          check <= (union bios32 *) __va(0xffff0);
0303          ++check) {
0304         long sig;
0305         if (get_kernel_nofault(sig, &check->fields.signature))
0306             continue;
0307 
0308         if (check->fields.signature != BIOS32_SIGNATURE)
0309             continue;
0310         length = check->fields.length * 16;
0311         if (!length)
0312             continue;
0313         sum = 0;
0314         for (i = 0; i < length ; ++i)
0315             sum += check->chars[i];
0316         if (sum != 0)
0317             continue;
0318         if (check->fields.revision != 0) {
0319             printk("PCI: unsupported BIOS32 revision %d at 0x%p\n",
0320                 check->fields.revision, check);
0321             continue;
0322         }
0323         DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check);
0324         if (check->fields.entry >= 0x100000) {
0325             printk("PCI: BIOS32 entry (0x%p) in high memory, "
0326                     "cannot use.\n", check);
0327             return NULL;
0328         } else {
0329             unsigned long bios32_entry = check->fields.entry;
0330             DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n",
0331                     bios32_entry);
0332             bios32_indirect.address = bios32_entry + PAGE_OFFSET;
0333             set_bios_x();
0334             if (check_pcibios())
0335                 return &pci_bios_access;
0336         }
0337         break;  /* Hopefully more than one BIOS32 cannot happen... */
0338     }
0339 
0340     return NULL;
0341 }
0342 
0343 /*
0344  *  BIOS Functions for IRQ Routing
0345  */
0346 
0347 struct irq_routing_options {
0348     u16 size;
0349     struct irq_info *table;
0350     u16 segment;
0351 } __attribute__((packed));
0352 
0353 struct irq_routing_table * pcibios_get_irq_routing_table(void)
0354 {
0355     struct irq_routing_options opt;
0356     struct irq_routing_table *rt = NULL;
0357     int ret, map;
0358     unsigned long page;
0359 
0360     if (!pci_bios_present)
0361         return NULL;
0362     page = __get_free_page(GFP_KERNEL);
0363     if (!page)
0364         return NULL;
0365     opt.table = (struct irq_info *) page;
0366     opt.size = PAGE_SIZE;
0367     opt.segment = __KERNEL_DS;
0368 
0369     DBG("PCI: Fetching IRQ routing table... ");
0370     __asm__("push %%es\n\t"
0371         "push %%ds\n\t"
0372         "pop  %%es\n\t"
0373         "lcall *(%%esi); cld\n\t"
0374         "pop %%es\n\t"
0375         "jc 1f\n\t"
0376         "xor %%ah, %%ah\n"
0377         "1:"
0378         : "=a" (ret),
0379           "=b" (map),
0380           "=m" (opt)
0381         : "0" (PCIBIOS_GET_ROUTING_OPTIONS),
0382           "1" (0),
0383           "D" ((long) &opt),
0384           "S" (&pci_indirect),
0385           "m" (opt)
0386         : "memory");
0387     DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
0388     if (ret & 0xff00)
0389         printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
0390     else if (opt.size) {
0391         rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL);
0392         if (rt) {
0393             memset(rt, 0, sizeof(struct irq_routing_table));
0394             rt->size = opt.size + sizeof(struct irq_routing_table);
0395             rt->exclusive_irqs = map;
0396             memcpy(rt->slots, (void *) page, opt.size);
0397             printk(KERN_INFO "PCI: Using BIOS Interrupt Routing Table\n");
0398         }
0399     }
0400     free_page(page);
0401     return rt;
0402 }
0403 EXPORT_SYMBOL(pcibios_get_irq_routing_table);
0404 
0405 int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
0406 {
0407     int ret;
0408 
0409     __asm__("lcall *(%%esi); cld\n\t"
0410         "jc 1f\n\t"
0411         "xor %%ah, %%ah\n"
0412         "1:"
0413         : "=a" (ret)
0414         : "0" (PCIBIOS_SET_PCI_HW_INT),
0415           "b" ((dev->bus->number << 8) | dev->devfn),
0416           "c" ((irq << 8) | (pin + 10)),
0417           "S" (&pci_indirect));
0418     return !(ret & 0xff00);
0419 }
0420 EXPORT_SYMBOL(pcibios_set_irq_routing);
0421 
0422 void __init pci_pcbios_init(void)
0423 {
0424     if ((pci_probe & PCI_PROBE_BIOS) 
0425         && ((raw_pci_ops = pci_find_bios()))) {
0426         pci_bios_present = 1;
0427     }
0428 }
0429