Loading arch/x86/boot/compressed/eboot.c +118 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ * ----------------------------------------------------------------------- */ #include <linux/efi.h> #include <linux/pci.h> #include <asm/efi.h> #include <asm/setup.h> #include <asm/desc.h> Loading Loading @@ -243,6 +244,121 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) *size = len; } static efi_status_t setup_efi_pci(struct boot_params *params) { efi_pci_io_protocol *pci; efi_status_t status; void **pci_handle; efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; unsigned long nr_pci, size = 0; int i; struct setup_data *data; data = (struct setup_data *)params->hdr.setup_data; while (data && data->next) data = (struct setup_data *)data->next; status = efi_call_phys5(sys_table->boottime->locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto, NULL, &size, pci_handle); if (status == EFI_BUFFER_TOO_SMALL) { status = efi_call_phys3(sys_table->boottime->allocate_pool, EFI_LOADER_DATA, size, &pci_handle); if (status != EFI_SUCCESS) return status; status = efi_call_phys5(sys_table->boottime->locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto, NULL, &size, pci_handle); } if (status != EFI_SUCCESS) goto free_handle; nr_pci = size / sizeof(void *); for (i = 0; i < nr_pci; i++) { void *h = pci_handle[i]; uint64_t attributes; struct pci_setup_rom *rom; status = efi_call_phys3(sys_table->boottime->handle_protocol, h, &pci_proto, &pci); if (status != EFI_SUCCESS) continue; if (!pci) continue; status = efi_call_phys4(pci->attributes, pci, EfiPciIoAttributeOperationGet, 0, &attributes); if (status != EFI_SUCCESS) continue; if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM) continue; if (!pci->romimage || !pci->romsize) continue; size = pci->romsize + sizeof(*rom); status = efi_call_phys3(sys_table->boottime->allocate_pool, EFI_LOADER_DATA, size, &rom); if (status != EFI_SUCCESS) continue; rom->data.type = SETUP_PCI; rom->data.len = size - sizeof(struct setup_data); rom->data.next = 0; rom->pcilen = pci->romsize; status = efi_call_phys5(pci->pci.read, pci, EfiPciIoWidthUint16, PCI_VENDOR_ID, 1, &(rom->vendor)); if (status != EFI_SUCCESS) goto free_struct; status = efi_call_phys5(pci->pci.read, pci, EfiPciIoWidthUint16, PCI_DEVICE_ID, 1, &(rom->devid)); if (status != EFI_SUCCESS) goto free_struct; status = efi_call_phys5(pci->get_location, pci, &(rom->segment), &(rom->bus), &(rom->device), &(rom->function)); if (status != EFI_SUCCESS) goto free_struct; memcpy(rom->romdata, pci->romimage, pci->romsize); if (data) data->next = (uint64_t)rom; else params->hdr.setup_data = (uint64_t)rom; data = (struct setup_data *)rom; continue; free_struct: efi_call_phys1(sys_table->boottime->free_pool, rom); } free_handle: efi_call_phys1(sys_table->boottime->free_pool, pci_handle); return status; } /* * See if we have Graphics Output Protocol */ Loading Loading @@ -1026,6 +1142,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, setup_graphics(boot_params); setup_efi_pci(boot_params); status = efi_call_phys3(sys_table->boottime->allocate_pool, EFI_LOADER_DATA, sizeof(*gdt), (void **)&gdt); Loading arch/x86/include/asm/bootparam.h +1 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #define SETUP_NONE 0 #define SETUP_E820_EXT 1 #define SETUP_DTB 2 #define SETUP_PCI 3 /* extensible setup data list node */ struct setup_data { Loading arch/x86/include/asm/pci.h +12 −0 Original line number Diff line number Diff line Loading @@ -171,4 +171,16 @@ cpumask_of_pcibus(const struct pci_bus *bus) } #endif struct pci_setup_rom { struct setup_data data; uint16_t vendor; uint16_t devid; uint64_t pcilen; unsigned long segment; unsigned long bus; unsigned long device; unsigned long function; uint8_t romdata[0]; }; #endif /* _ASM_X86_PCI_H */ arch/x86/kernel/setup.c +0 −4 Original line number Diff line number Diff line Loading @@ -143,11 +143,7 @@ int default_check_phys_apicid_present(int phys_apicid) } #endif #ifndef CONFIG_DEBUG_BOOT_PARAMS struct boot_params __initdata boot_params; #else struct boot_params boot_params; #endif /* * Machine setup.. Loading arch/x86/pci/common.c +30 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <asm/io.h> #include <asm/smp.h> #include <asm/pci_x86.h> #include <asm/setup.h> unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; Loading Loading @@ -608,6 +609,35 @@ unsigned int pcibios_assign_all_busses(void) return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; } int pcibios_add_device(struct pci_dev *dev) { struct setup_data *data; struct pci_setup_rom *rom; u64 pa_data; pa_data = boot_params.hdr.setup_data; while (pa_data) { data = phys_to_virt(pa_data); if (data->type == SETUP_PCI) { rom = (struct pci_setup_rom *)data; if ((pci_domain_nr(dev->bus) == rom->segment) && (dev->bus->number == rom->bus) && (PCI_SLOT(dev->devfn) == rom->device) && (PCI_FUNC(dev->devfn) == rom->function) && (dev->vendor == rom->vendor) && (dev->device == rom->devid)) { dev->rom = (void *)(unsigned long)(pa_data + offsetof(struct pci_setup_rom, romdata)); dev->romlen = rom->pcilen; } } pa_data = data->next; } return 0; } int pcibios_enable_device(struct pci_dev *dev, int mask) { int err; Loading Loading
arch/x86/boot/compressed/eboot.c +118 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ * ----------------------------------------------------------------------- */ #include <linux/efi.h> #include <linux/pci.h> #include <asm/efi.h> #include <asm/setup.h> #include <asm/desc.h> Loading Loading @@ -243,6 +244,121 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) *size = len; } static efi_status_t setup_efi_pci(struct boot_params *params) { efi_pci_io_protocol *pci; efi_status_t status; void **pci_handle; efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; unsigned long nr_pci, size = 0; int i; struct setup_data *data; data = (struct setup_data *)params->hdr.setup_data; while (data && data->next) data = (struct setup_data *)data->next; status = efi_call_phys5(sys_table->boottime->locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto, NULL, &size, pci_handle); if (status == EFI_BUFFER_TOO_SMALL) { status = efi_call_phys3(sys_table->boottime->allocate_pool, EFI_LOADER_DATA, size, &pci_handle); if (status != EFI_SUCCESS) return status; status = efi_call_phys5(sys_table->boottime->locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto, NULL, &size, pci_handle); } if (status != EFI_SUCCESS) goto free_handle; nr_pci = size / sizeof(void *); for (i = 0; i < nr_pci; i++) { void *h = pci_handle[i]; uint64_t attributes; struct pci_setup_rom *rom; status = efi_call_phys3(sys_table->boottime->handle_protocol, h, &pci_proto, &pci); if (status != EFI_SUCCESS) continue; if (!pci) continue; status = efi_call_phys4(pci->attributes, pci, EfiPciIoAttributeOperationGet, 0, &attributes); if (status != EFI_SUCCESS) continue; if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM) continue; if (!pci->romimage || !pci->romsize) continue; size = pci->romsize + sizeof(*rom); status = efi_call_phys3(sys_table->boottime->allocate_pool, EFI_LOADER_DATA, size, &rom); if (status != EFI_SUCCESS) continue; rom->data.type = SETUP_PCI; rom->data.len = size - sizeof(struct setup_data); rom->data.next = 0; rom->pcilen = pci->romsize; status = efi_call_phys5(pci->pci.read, pci, EfiPciIoWidthUint16, PCI_VENDOR_ID, 1, &(rom->vendor)); if (status != EFI_SUCCESS) goto free_struct; status = efi_call_phys5(pci->pci.read, pci, EfiPciIoWidthUint16, PCI_DEVICE_ID, 1, &(rom->devid)); if (status != EFI_SUCCESS) goto free_struct; status = efi_call_phys5(pci->get_location, pci, &(rom->segment), &(rom->bus), &(rom->device), &(rom->function)); if (status != EFI_SUCCESS) goto free_struct; memcpy(rom->romdata, pci->romimage, pci->romsize); if (data) data->next = (uint64_t)rom; else params->hdr.setup_data = (uint64_t)rom; data = (struct setup_data *)rom; continue; free_struct: efi_call_phys1(sys_table->boottime->free_pool, rom); } free_handle: efi_call_phys1(sys_table->boottime->free_pool, pci_handle); return status; } /* * See if we have Graphics Output Protocol */ Loading Loading @@ -1026,6 +1142,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, setup_graphics(boot_params); setup_efi_pci(boot_params); status = efi_call_phys3(sys_table->boottime->allocate_pool, EFI_LOADER_DATA, sizeof(*gdt), (void **)&gdt); Loading
arch/x86/include/asm/bootparam.h +1 −0 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #define SETUP_NONE 0 #define SETUP_E820_EXT 1 #define SETUP_DTB 2 #define SETUP_PCI 3 /* extensible setup data list node */ struct setup_data { Loading
arch/x86/include/asm/pci.h +12 −0 Original line number Diff line number Diff line Loading @@ -171,4 +171,16 @@ cpumask_of_pcibus(const struct pci_bus *bus) } #endif struct pci_setup_rom { struct setup_data data; uint16_t vendor; uint16_t devid; uint64_t pcilen; unsigned long segment; unsigned long bus; unsigned long device; unsigned long function; uint8_t romdata[0]; }; #endif /* _ASM_X86_PCI_H */
arch/x86/kernel/setup.c +0 −4 Original line number Diff line number Diff line Loading @@ -143,11 +143,7 @@ int default_check_phys_apicid_present(int phys_apicid) } #endif #ifndef CONFIG_DEBUG_BOOT_PARAMS struct boot_params __initdata boot_params; #else struct boot_params boot_params; #endif /* * Machine setup.. Loading
arch/x86/pci/common.c +30 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <asm/io.h> #include <asm/smp.h> #include <asm/pci_x86.h> #include <asm/setup.h> unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; Loading Loading @@ -608,6 +609,35 @@ unsigned int pcibios_assign_all_busses(void) return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; } int pcibios_add_device(struct pci_dev *dev) { struct setup_data *data; struct pci_setup_rom *rom; u64 pa_data; pa_data = boot_params.hdr.setup_data; while (pa_data) { data = phys_to_virt(pa_data); if (data->type == SETUP_PCI) { rom = (struct pci_setup_rom *)data; if ((pci_domain_nr(dev->bus) == rom->segment) && (dev->bus->number == rom->bus) && (PCI_SLOT(dev->devfn) == rom->device) && (PCI_FUNC(dev->devfn) == rom->function) && (dev->vendor == rom->vendor) && (dev->device == rom->devid)) { dev->rom = (void *)(unsigned long)(pa_data + offsetof(struct pci_setup_rom, romdata)); dev->romlen = rom->pcilen; } } pa_data = data->next; } return 0; } int pcibios_enable_device(struct pci_dev *dev, int mask) { int err; Loading