aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/compressed/eboot.c
diff options
context:
space:
mode:
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 c760e073963e..8a54313bc7dc 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>
@@ -243,6 +244,121 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
243 *size = len; 244 *size = len;
244} 245}
245 246
247static efi_status_t setup_efi_pci(struct boot_params *params)
248{
249 efi_pci_io_protocol *pci;
250 efi_status_t status;
251 void **pci_handle;
252 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
253 unsigned long nr_pci, size = 0;
254 int i;
255 struct setup_data *data;
256
257 data = (struct setup_data *)params->hdr.setup_data;
258
259 while (data && data->next)
260 data = (struct setup_data *)data->next;
261
262 status = efi_call_phys5(sys_table->boottime->locate_handle,
263 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
264 NULL, &size, pci_handle);
265
266 if (status == EFI_BUFFER_TOO_SMALL) {
267 status = efi_call_phys3(sys_table->boottime->allocate_pool,
268 EFI_LOADER_DATA, size, &pci_handle);
269
270 if (status != EFI_SUCCESS)
271 return status;
272
273 status = efi_call_phys5(sys_table->boottime->locate_handle,
274 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
275 NULL, &size, pci_handle);
276 }
277
278 if (status != EFI_SUCCESS)
279 goto free_handle;
280
281 nr_pci = size / sizeof(void *);
282 for (i = 0; i < nr_pci; i++) {
283 void *h = pci_handle[i];
284 uint64_t attributes;
285 struct pci_setup_rom *rom;
286
287 status = efi_call_phys3(sys_table->boottime->handle_protocol,
288 h, &pci_proto, &pci);
289
290 if (status != EFI_SUCCESS)
291 continue;
292
293 if (!pci)
294 continue;
295
296 status = efi_call_phys4(pci->attributes, pci,
297 EfiPciIoAttributeOperationGet, 0,
298 &attributes);
299
300 if (status != EFI_SUCCESS)
301 continue;
302
303 if (!attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM)
304 continue;
305
306 if (!pci->romimage || !pci->romsize)
307 continue;
308
309 size = pci->romsize + sizeof(*rom);
310
311 status = efi_call_phys3(sys_table->boottime->allocate_pool,
312 EFI_LOADER_DATA, size, &rom);
313
314 if (status != EFI_SUCCESS)
315 continue;
316
317 rom->data.type = SETUP_PCI;
318 rom->data.len = size - sizeof(struct setup_data);
319 rom->data.next = 0;
320 rom->pcilen = pci->romsize;
321
322 status = efi_call_phys5(pci->pci.read, pci,
323 EfiPciIoWidthUint16, PCI_VENDOR_ID,
324 1, &(rom->vendor));
325
326 if (status != EFI_SUCCESS)
327 goto free_struct;
328
329 status = efi_call_phys5(pci->pci.read, pci,
330 EfiPciIoWidthUint16, PCI_DEVICE_ID,
331 1, &(rom->devid));
332
333 if (status != EFI_SUCCESS)
334 goto free_struct;
335
336 status = efi_call_phys5(pci->get_location, pci,
337 &(rom->segment), &(rom->bus),
338 &(rom->device), &(rom->function));
339
340 if (status != EFI_SUCCESS)
341 goto free_struct;
342
343 memcpy(rom->romdata, pci->romimage, pci->romsize);
344
345 if (data)
346 data->next = (uint64_t)rom;
347 else
348 params->hdr.setup_data = (uint64_t)rom;
349
350 data = (struct setup_data *)rom;
351
352 continue;
353 free_struct:
354 efi_call_phys1(sys_table->boottime->free_pool, rom);
355 }
356
357free_handle:
358 efi_call_phys1(sys_table->boottime->free_pool, pci_handle);
359 return status;
360}
361
246/* 362/*
247 * See if we have Graphics Output Protocol 363 * See if we have Graphics Output Protocol
248 */ 364 */
@@ -1026,6 +1142,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
1026 1142
1027 setup_graphics(boot_params); 1143 setup_graphics(boot_params);
1028 1144
1145 setup_efi_pci(boot_params);
1146
1029 status = efi_call_phys3(sys_table->boottime->allocate_pool, 1147 status = efi_call_phys3(sys_table->boottime->allocate_pool,
1030 EFI_LOADER_DATA, sizeof(*gdt), 1148 EFI_LOADER_DATA, sizeof(*gdt),
1031 (void **)&gdt); 1149 (void **)&gdt);