0001
0002 #include <linux/sched.h>
0003 #include <linux/mm.h>
0004 #include <linux/uaccess.h>
0005 #include <linux/mmzone.h>
0006 #include <linux/ioport.h>
0007 #include <linux/seq_file.h>
0008 #include <linux/console.h>
0009 #include <linux/init.h>
0010 #include <linux/edd.h>
0011 #include <linux/dmi.h>
0012 #include <linux/pfn.h>
0013 #include <linux/pci.h>
0014 #include <linux/export.h>
0015
0016 #include <asm/probe_roms.h>
0017 #include <asm/pci-direct.h>
0018 #include <asm/e820/api.h>
0019 #include <asm/mmzone.h>
0020 #include <asm/setup.h>
0021 #include <asm/sections.h>
0022 #include <asm/io.h>
0023 #include <asm/setup_arch.h>
0024 #include <asm/sev.h>
0025
0026 static struct resource system_rom_resource = {
0027 .name = "System ROM",
0028 .start = 0xf0000,
0029 .end = 0xfffff,
0030 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0031 };
0032
0033 static struct resource extension_rom_resource = {
0034 .name = "Extension ROM",
0035 .start = 0xe0000,
0036 .end = 0xeffff,
0037 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0038 };
0039
0040 static struct resource adapter_rom_resources[] = { {
0041 .name = "Adapter ROM",
0042 .start = 0xc8000,
0043 .end = 0,
0044 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0045 }, {
0046 .name = "Adapter ROM",
0047 .start = 0,
0048 .end = 0,
0049 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0050 }, {
0051 .name = "Adapter ROM",
0052 .start = 0,
0053 .end = 0,
0054 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0055 }, {
0056 .name = "Adapter ROM",
0057 .start = 0,
0058 .end = 0,
0059 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0060 }, {
0061 .name = "Adapter ROM",
0062 .start = 0,
0063 .end = 0,
0064 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0065 }, {
0066 .name = "Adapter ROM",
0067 .start = 0,
0068 .end = 0,
0069 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0070 } };
0071
0072 static struct resource video_rom_resource = {
0073 .name = "Video ROM",
0074 .start = 0xc0000,
0075 .end = 0xc7fff,
0076 .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
0077 };
0078
0079
0080
0081
0082 static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device)
0083 {
0084 struct pci_driver *drv = to_pci_driver(pdev->dev.driver);
0085 const struct pci_device_id *id;
0086
0087 if (pdev->vendor == vendor && pdev->device == device)
0088 return true;
0089
0090 for (id = drv ? drv->id_table : NULL; id && id->vendor; id++)
0091 if (id->vendor == vendor && id->device == device)
0092 break;
0093
0094 return id && id->vendor;
0095 }
0096
0097 static bool probe_list(struct pci_dev *pdev, unsigned short vendor,
0098 const void *rom_list)
0099 {
0100 unsigned short device;
0101
0102 do {
0103 if (get_kernel_nofault(device, rom_list) != 0)
0104 device = 0;
0105
0106 if (device && match_id(pdev, vendor, device))
0107 break;
0108
0109 rom_list += 2;
0110 } while (device);
0111
0112 return !!device;
0113 }
0114
0115 static struct resource *find_oprom(struct pci_dev *pdev)
0116 {
0117 struct resource *oprom = NULL;
0118 int i;
0119
0120 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) {
0121 struct resource *res = &adapter_rom_resources[i];
0122 unsigned short offset, vendor, device, list, rev;
0123 const void *rom;
0124
0125 if (res->end == 0)
0126 break;
0127
0128 rom = isa_bus_to_virt(res->start);
0129 if (get_kernel_nofault(offset, rom + 0x18) != 0)
0130 continue;
0131
0132 if (get_kernel_nofault(vendor, rom + offset + 0x4) != 0)
0133 continue;
0134
0135 if (get_kernel_nofault(device, rom + offset + 0x6) != 0)
0136 continue;
0137
0138 if (match_id(pdev, vendor, device)) {
0139 oprom = res;
0140 break;
0141 }
0142
0143 if (get_kernel_nofault(list, rom + offset + 0x8) == 0 &&
0144 get_kernel_nofault(rev, rom + offset + 0xc) == 0 &&
0145 rev >= 3 && list &&
0146 probe_list(pdev, vendor, rom + offset + list)) {
0147 oprom = res;
0148 break;
0149 }
0150 }
0151
0152 return oprom;
0153 }
0154
0155 void __iomem *pci_map_biosrom(struct pci_dev *pdev)
0156 {
0157 struct resource *oprom = find_oprom(pdev);
0158
0159 if (!oprom)
0160 return NULL;
0161
0162 return ioremap(oprom->start, resource_size(oprom));
0163 }
0164 EXPORT_SYMBOL(pci_map_biosrom);
0165
0166 void pci_unmap_biosrom(void __iomem *image)
0167 {
0168 iounmap(image);
0169 }
0170 EXPORT_SYMBOL(pci_unmap_biosrom);
0171
0172 size_t pci_biosrom_size(struct pci_dev *pdev)
0173 {
0174 struct resource *oprom = find_oprom(pdev);
0175
0176 return oprom ? resource_size(oprom) : 0;
0177 }
0178 EXPORT_SYMBOL(pci_biosrom_size);
0179
0180 #define ROMSIGNATURE 0xaa55
0181
0182 static int __init romsignature(const unsigned char *rom)
0183 {
0184 const unsigned short * const ptr = (const unsigned short *)rom;
0185 unsigned short sig;
0186
0187 return get_kernel_nofault(sig, ptr) == 0 && sig == ROMSIGNATURE;
0188 }
0189
0190 static int __init romchecksum(const unsigned char *rom, unsigned long length)
0191 {
0192 unsigned char sum, c;
0193
0194 for (sum = 0; length && get_kernel_nofault(c, rom++) == 0; length--)
0195 sum += c;
0196 return !length && !sum;
0197 }
0198
0199 void __init probe_roms(void)
0200 {
0201 unsigned long start, length, upper;
0202 const unsigned char *rom;
0203 unsigned char c;
0204 int i;
0205
0206
0207
0208
0209
0210
0211
0212 snp_prep_memory(video_rom_resource.start,
0213 ((system_rom_resource.end + 1) - video_rom_resource.start),
0214 SNP_PAGE_STATE_PRIVATE);
0215
0216
0217 upper = adapter_rom_resources[0].start;
0218 for (start = video_rom_resource.start; start < upper; start += 2048) {
0219 rom = isa_bus_to_virt(start);
0220 if (!romsignature(rom))
0221 continue;
0222
0223 video_rom_resource.start = start;
0224
0225 if (get_kernel_nofault(c, rom + 2) != 0)
0226 continue;
0227
0228
0229 length = c * 512;
0230
0231
0232 if (length && romchecksum(rom, length))
0233 video_rom_resource.end = start + length - 1;
0234
0235 request_resource(&iomem_resource, &video_rom_resource);
0236 break;
0237 }
0238
0239 start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
0240 if (start < upper)
0241 start = upper;
0242
0243
0244 request_resource(&iomem_resource, &system_rom_resource);
0245 upper = system_rom_resource.start;
0246
0247
0248 rom = isa_bus_to_virt(extension_rom_resource.start);
0249 if (romsignature(rom)) {
0250 length = resource_size(&extension_rom_resource);
0251 if (romchecksum(rom, length)) {
0252 request_resource(&iomem_resource, &extension_rom_resource);
0253 upper = extension_rom_resource.start;
0254 }
0255 }
0256
0257
0258 for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
0259 rom = isa_bus_to_virt(start);
0260 if (!romsignature(rom))
0261 continue;
0262
0263 if (get_kernel_nofault(c, rom + 2) != 0)
0264 continue;
0265
0266
0267 length = c * 512;
0268
0269
0270 if (!length || start + length > upper || !romchecksum(rom, length))
0271 continue;
0272
0273 adapter_rom_resources[i].start = start;
0274 adapter_rom_resources[i].end = start + length - 1;
0275 request_resource(&iomem_resource, &adapter_rom_resources[i]);
0276
0277 start = adapter_rom_resources[i++].end & ~2047UL;
0278 }
0279 }
0280