aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/compressed/eboot.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 15:14:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 15:14:47 -0500
commit193c0d682525987db59ac3a24531a77e4947aa95 (patch)
tree7b58346171c4d07e2c2ee6c3c469c325495149a4 /arch/x86/boot/compressed/eboot.c
parent8b0cab14951fbf8126795ab301835a8f8126a988 (diff)
parent1cb73f8c479e66541fefd3f7fa547b1fa56cdc54 (diff)
Merge tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI update from Bjorn Helgaas: "Host bridge hotplug: - Untangle _PRT from struct pci_bus (Bjorn Helgaas) - Request _OSC control before scanning root bus (Taku Izumi) - Assign resources when adding host bridge (Yinghai Lu) - Remove root bus when removing host bridge (Yinghai Lu) - Remove _PRT during hot remove (Yinghai Lu) SRIOV - Add sysfs knobs to control numVFs (Don Dutile) Power management - Notify devices when power resource turned on (Huang Ying) Bug fixes - Work around broken _SEG on HP xw9300 (Bjorn Helgaas) - Keep runtime PM enabled for unbound PCI devices (Huang Ying) - Fix Optimus dual-GPU runtime D3 suspend issue (Dave Airlie) - Fix xen frontend shutdown issue (David Vrabel) - Work around PLX PCI 9050 BAR alignment erratum (Ian Abbott) Miscellaneous - Add GPL license for drivers/pci/ioapic (Andrew Cooks) - Add standard PCI-X, PCIe ASPM register #defines (Bjorn Helgaas) - NumaChip remote PCI support (Daniel Blueman) - Fix PCIe Link Capabilities Supported Link Speed definition (Jingoo Han) - Convert dev_printk() to dev_info(), etc (Joe Perches) - Add support for non PCI BAR ROM data (Matthew Garrett) - Add x86 support for host bridge translation offset (Mike Yoknis) - Report success only when every driver supports AER (Vijay Pandarathil)" Fix up trivial conflicts. * tag 'for-3.8' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (48 commits) PCI: Use phys_addr_t for physical ROM address x86/PCI: Add NumaChip remote PCI support ath9k: Use standard #defines for PCIe Capability ASPM fields iwlwifi: Use standard #defines for PCIe Capability ASPM fields iwlwifi: collapse wrapper for pcie_capability_read_word() iwlegacy: Use standard #defines for PCIe Capability ASPM fields iwlegacy: collapse wrapper for pcie_capability_read_word() cxgb3: Use standard #defines for PCIe Capability ASPM fields PCI: Add standard PCIe Capability Link ASPM field names PCI/portdrv: Use PCI Express Capability accessors PCI: Use standard PCIe Capability Link register field names x86: Use PCI setup data PCI: Add support for non-BAR ROMs PCI: Add pcibios_add_device EFI: Stash ROMs if they're not in the PCI BAR PCI: Add and use standard PCI-X Capability register names PCI/PM: Keep runtime PM enabled for unbound PCI devices xen-pcifront: Handle backend CLOSED without CLOSING PCI: SRIOV control and status via sysfs (documentation) PCI/AER: Report success only when every device has AER-aware driver ...
Diffstat (limited to 'arch/x86/boot/compressed/eboot.c')
-rw-r--r--arch/x86/boot/compressed/eboot.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index e87b0cac14b5..b1942e222768 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -8,6 +8,7 @@
8 * ----------------------------------------------------------------------- */ 8 * ----------------------------------------------------------------------- */
9 9
10#include <linux/efi.h> 10#include <linux/efi.h>
11#include <linux/pci.h>
11#include <asm/efi.h> 12#include <asm/efi.h>
12#include <asm/setup.h> 13#include <asm/setup.h>
13#include <asm/desc.h> 14#include <asm/desc.h>
@@ -245,6 +246,121 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
245 *size = len; 246 *size = len;
246} 247}
247 248
249static efi_status_t setup_efi_pci(struct boot_params *params)
250{
251 efi_pci_io_protocol *pci;
252 efi_status_t status;
253 void **pci_handle;
254 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
255 unsigned long nr_pci, size = 0;
256 int i;
257 struct setup_data *data;
258
259 data = (struct setup_data *)params->hdr.setup_data;
260
261 while (data && data->next)
262 data = (struct setup_data *)data->next;
263
264 status = efi_call_phys5(sys_table->boottime->locate_handle,
265 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
266 NULL, &size, pci_handle);
267
268 if (status == EFI_BUFFER_TOO_SMALL) {
269 status = efi_call_phys3(sys_table->boottime->allocate_pool,
270 EFI_LOADER_DATA, size, &pci_handle);
271
272 if (status != EFI_SUCCESS)
273 return status;
274
275 status = efi_call_phys5(sys_table->boottime->locate_handle,
276 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
277 NULL, &size, pci_handle);
278 }
279
280 if (status != EFI_SUCCESS)
281 goto free_handle;
282
283 nr_pci = size / sizeof(void *);
284 for (i = 0; i < nr_pci; i++) {
285 void *h = pci_handle[i];
286 uint64_t attributes;
287 struct pci_setup_rom *rom;
288
289 status = efi_call_phys3(sys_table->boottime->handle_protocol,
290 h, &pci_proto, &pci);
291
292 if (status != EFI_SUCCESS)
293 continue;
294
295 if (!pci)
296 continue;
297
298 status = efi_call_phys4(pci->attributes, pci,
299 EfiPciIoAttributeOperationGet, 0,
300 &attributes);
301
302 if (status != EFI_SUCCESS)
303 continue;
304
305 if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM)
306 continue;
307
308 if (!pci->romimage || !pci->romsize)
309 continue;
310
311 size = pci->romsize + sizeof(*rom);
312
313 status = efi_call_phys3(sys_table->boottime->allocate_pool,
314 EFI_LOADER_DATA, size, &rom);
315
316 if (status != EFI_SUCCESS)
317 continue;
318
319 rom->data.type = SETUP_PCI;
320 rom->data.len = size - sizeof(struct setup_data);
321 rom->data.next = 0;
322 rom->pcilen = pci->romsize;
323
324 status = efi_call_phys5(pci->pci.read, pci,
325 EfiPciIoWidthUint16, PCI_VENDOR_ID,
326 1, &(rom->vendor));
327
328 if (status != EFI_SUCCESS)
329 goto free_struct;
330
331 status = efi_call_phys5(pci->pci.read, pci,
332 EfiPciIoWidthUint16, PCI_DEVICE_ID,
333 1, &(rom->devid));
334
335 if (status != EFI_SUCCESS)
336 goto free_struct;
337
338 status = efi_call_phys5(pci->get_location, pci,
339 &(rom->segment), &(rom->bus),
340 &(rom->device), &(rom->function));
341
342 if (status != EFI_SUCCESS)
343 goto free_struct;
344
345 memcpy(rom->romdata, pci->romimage, pci->romsize);
346
347 if (data)
348 data->next = (uint64_t)rom;
349 else
350 params->hdr.setup_data = (uint64_t)rom;
351
352 data = (struct setup_data *)rom;
353
354 continue;
355 free_struct:
356 efi_call_phys1(sys_table->boottime->free_pool, rom);
357 }
358
359free_handle:
360 efi_call_phys1(sys_table->boottime->free_pool, pci_handle);
361 return status;
362}
363
248/* 364/*
249 * See if we have Graphics Output Protocol 365 * See if we have Graphics Output Protocol
250 */ 366 */
@@ -1028,6 +1144,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
1028 1144
1029 setup_graphics(boot_params); 1145 setup_graphics(boot_params);
1030 1146
1147 setup_efi_pci(boot_params);
1148
1031 status = efi_call_phys3(sys_table->boottime->allocate_pool, 1149 status = efi_call_phys3(sys_table->boottime->allocate_pool,
1032 EFI_LOADER_DATA, sizeof(*gdt), 1150 EFI_LOADER_DATA, sizeof(*gdt),
1033 (void **)&gdt); 1151 (void **)&gdt);