^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * BIOS32 and PCI BIOS handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/pci_x86.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/e820/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/pci-functions.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/set_memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* BIOS32 signature: "_32_" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* PCI signature: "PCI " */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* PCI service signature: "$PCI" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* PCI BIOS hardware mechanism flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define PCIBIOS_HW_TYPE1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define PCIBIOS_HW_TYPE2 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define PCIBIOS_HW_TYPE1_SPEC 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define PCIBIOS_HW_TYPE2_SPEC 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int pcibios_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* According to the BIOS specification at:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * http://members.datafast.net.au/dft0802/specs/bios21.pdf, we could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * restrict the x zone to some pages and make it ro. But this may be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * broken on some bios, complex to handle with static_protections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * We could make the 0xe0000-0x100000 range rox, but this can break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * some ISA mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * So we let's an rw and x hole when pcibios is used. This shouldn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * happen for modern system with mmconfig, and if you don't want it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * you could disable pcibios...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static inline void set_bios_x(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pcibios_enabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) set_memory_x(PAGE_OFFSET + BIOS_BEGIN, (BIOS_END - BIOS_BEGIN) >> PAGE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (__supported_pte_mask & _PAGE_NX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) printk(KERN_INFO "PCI: PCI BIOS area is rw and x. Use pci=nobios if you want it NX.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * This is the standard structure used to identify the entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * to the BIOS32 Service Directory, as documented in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Standard BIOS 32-bit Service Directory Proposal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Revision 0.4 May 24, 1993
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Phoenix Technologies Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Norwood, MA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * and the PCI BIOS specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) union bios32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned long signature; /* _32_ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) unsigned long entry; /* 32 bit physical address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned char revision; /* Revision level, 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned char length; /* Length in paragraphs should be 01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned char checksum; /* All bytes must add up to zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) unsigned char reserved[5]; /* Must be zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) } fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) char chars[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Physical address of the service directory. I don't know if we're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * allowed to have more than one of these or not, so just in case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * we'll make pcibios_present() take a memory start parameter and store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * the array there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) unsigned short segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) } bios32_indirect __initdata = { 0, __KERNEL_CS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Returns the entry point for the given service, NULL on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static unsigned long __init bios32_service(unsigned long service)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) unsigned char return_code; /* %al */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) unsigned long address; /* %ebx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long length; /* %ecx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned long entry; /* %edx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) __asm__("lcall *(%%edi); cld"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) : "=a" (return_code),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) "=b" (address),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) "=c" (length),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) "=d" (entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) : "0" (service),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) "1" (0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) "D" (&bios32_indirect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) switch (return_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return address + entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) case 0x80: /* Not present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) default: /* Shouldn't happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) service, return_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) unsigned long address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned short segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) } pci_indirect __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .address = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .segment = __KERNEL_CS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int pci_bios_present __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int __init check_pcibios(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 signature, eax, ebx, ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u8 status, major_ver, minor_ver, hw_mech;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned long flags, pcibios_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) pci_indirect.address = pcibios_entry + PAGE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) __asm__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) "lcall *(%%edi); cld\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) "jc 1f\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) "xor %%ah, %%ah\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) "1:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) : "=d" (signature),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) "=a" (eax),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) "=b" (ebx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) "=c" (ecx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) : "1" (PCIBIOS_PCI_BIOS_PRESENT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) "D" (&pci_indirect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) status = (eax >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) hw_mech = eax & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) major_ver = (ebx >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) minor_ver = ebx & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (pcibios_last_bus < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) pcibios_last_bus = ecx & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) status, hw_mech, major_ver, minor_ver, pcibios_last_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (status || signature != PCI_SIGNATURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) status, signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) printk(KERN_INFO "PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) major_ver, minor_ver, pcibios_entry, pcibios_last_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #ifdef CONFIG_PCI_DIRECT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (!(hw_mech & PCIBIOS_HW_TYPE1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pci_probe &= ~PCI_PROBE_CONF1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!(hw_mech & PCIBIOS_HW_TYPE2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pci_probe &= ~PCI_PROBE_CONF2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int pci_bios_read(unsigned int seg, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) unsigned int devfn, int reg, int len, u32 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned long result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) unsigned long bx = (bus << 8) | devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) u16 number = 0, mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) WARN_ON(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) raw_spin_lock_irqsave(&pci_config_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) number = PCIBIOS_READ_CONFIG_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) mask = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) number = PCIBIOS_READ_CONFIG_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) mask = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) number = PCIBIOS_READ_CONFIG_DWORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) __asm__("lcall *(%%esi); cld\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "jc 1f\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) "xor %%ah, %%ah\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) "1:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) : "=c" (*value),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) "=a" (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) : "1" (number),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) "b" (bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) "D" ((long)reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) "S" (&pci_indirect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Zero-extend the result beyond 8 or 16 bits, do not trust the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * BIOS having done it:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *value &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) raw_spin_unlock_irqrestore(&pci_config_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return (int)((result & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static int pci_bios_write(unsigned int seg, unsigned int bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned int devfn, int reg, int len, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) unsigned long result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) unsigned long bx = (bus << 8) | devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) u16 number = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) WARN_ON(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if ((bus > 255) || (devfn > 255) || (reg > 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) raw_spin_lock_irqsave(&pci_config_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) number = PCIBIOS_WRITE_CONFIG_BYTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) number = PCIBIOS_WRITE_CONFIG_WORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) number = PCIBIOS_WRITE_CONFIG_DWORD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) __asm__("lcall *(%%esi); cld\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) "jc 1f\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) "xor %%ah, %%ah\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) "1:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) : "=a" (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) : "0" (number),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) "c" (value),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) "b" (bx),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) "D" ((long)reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) "S" (&pci_indirect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) raw_spin_unlock_irqrestore(&pci_config_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return (int)((result & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Function table for BIOS32 access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static const struct pci_raw_ops pci_bios_access = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .read = pci_bios_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .write = pci_bios_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * Try to find PCI BIOS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static const struct pci_raw_ops *__init pci_find_bios(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) union bios32 *check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned char sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int i, length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * Follow the standard procedure for locating the BIOS32 Service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * directory by scanning the permissible address range from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * 0xe0000 through 0xfffff for a valid BIOS32 structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for (check = (union bios32 *) __va(0xe0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) check <= (union bios32 *) __va(0xffff0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ++check) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) long sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (get_kernel_nofault(sig, &check->fields.signature))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (check->fields.signature != BIOS32_SIGNATURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) length = check->fields.length * 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (!length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) for (i = 0; i < length ; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) sum += check->chars[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (sum != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (check->fields.revision != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) printk("PCI: unsupported BIOS32 revision %d at 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) check->fields.revision, check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (check->fields.entry >= 0x100000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) printk("PCI: BIOS32 entry (0x%p) in high memory, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) "cannot use.\n", check);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned long bios32_entry = check->fields.entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) bios32_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) bios32_indirect.address = bios32_entry + PAGE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) set_bios_x();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (check_pcibios())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return &pci_bios_access;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) break; /* Hopefully more than one BIOS32 cannot happen... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * BIOS Functions for IRQ Routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct irq_routing_options {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) u16 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct irq_info *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) u16 segment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct irq_routing_table * pcibios_get_irq_routing_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct irq_routing_options opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct irq_routing_table *rt = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int ret, map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned long page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (!pci_bios_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) page = __get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) opt.table = (struct irq_info *) page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) opt.size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) opt.segment = __KERNEL_DS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) DBG("PCI: Fetching IRQ routing table... ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) __asm__("push %%es\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) "push %%ds\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) "pop %%es\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) "lcall *(%%esi); cld\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) "pop %%es\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) "jc 1f\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) "xor %%ah, %%ah\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) "1:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) : "=a" (ret),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) "=b" (map),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) "=m" (opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) : "0" (PCIBIOS_GET_ROUTING_OPTIONS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) "1" (0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) "D" ((long) &opt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) "S" (&pci_indirect),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) "m" (opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) : "memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (ret & 0xff00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) printk(KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) else if (opt.size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) rt = kmalloc(sizeof(struct irq_routing_table) + opt.size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (rt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) memset(rt, 0, sizeof(struct irq_routing_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) rt->size = opt.size + sizeof(struct irq_routing_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) rt->exclusive_irqs = map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) memcpy(rt->slots, (void *) page, opt.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) printk(KERN_INFO "PCI: Using BIOS Interrupt Routing Table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) EXPORT_SYMBOL(pcibios_get_irq_routing_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int pcibios_set_irq_routing(struct pci_dev *dev, int pin, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) __asm__("lcall *(%%esi); cld\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) "jc 1f\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) "xor %%ah, %%ah\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) "1:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) : "=a" (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) : "0" (PCIBIOS_SET_PCI_HW_INT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) "b" ((dev->bus->number << 8) | dev->devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "c" ((irq << 8) | (pin + 10)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) "S" (&pci_indirect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return !(ret & 0xff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) EXPORT_SYMBOL(pcibios_set_irq_routing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) void __init pci_pcbios_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if ((pci_probe & PCI_PROBE_BIOS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) && ((raw_pci_ops = pci_find_bios()))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) pci_bios_present = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)