aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/boot/compressed/eboot.c118
-rw-r--r--arch/x86/include/asm/bootparam.h1
-rw-r--r--arch/x86/include/asm/pci.h12
-rw-r--r--include/linux/efi.h71
4 files changed, 202 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);
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
index 2ad874cb661c..92862cd90201 100644
--- a/arch/x86/include/asm/bootparam.h
+++ b/arch/x86/include/asm/bootparam.h
@@ -13,6 +13,7 @@
13#define SETUP_NONE 0 13#define SETUP_NONE 0
14#define SETUP_E820_EXT 1 14#define SETUP_E820_EXT 1
15#define SETUP_DTB 2 15#define SETUP_DTB 2
16#define SETUP_PCI 3
16 17
17/* extensible setup data list node */ 18/* extensible setup data list node */
18struct setup_data { 19struct setup_data {
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 6e41b9343928..dba7805176bf 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -171,4 +171,16 @@ cpumask_of_pcibus(const struct pci_bus *bus)
171} 171}
172#endif 172#endif
173 173
174struct pci_setup_rom {
175 struct setup_data data;
176 uint16_t vendor;
177 uint16_t devid;
178 uint64_t pcilen;
179 unsigned long segment;
180 unsigned long bus;
181 unsigned long device;
182 unsigned long function;
183 uint8_t romdata[0];
184};
185
174#endif /* _ASM_X86_PCI_H */ 186#endif /* _ASM_X86_PCI_H */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 8670eb1eb8cd..8eb1be17c801 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -196,6 +196,77 @@ typedef struct {
196 void *create_event_ex; 196 void *create_event_ex;
197} efi_boot_services_t; 197} efi_boot_services_t;
198 198
199typedef enum {
200 EfiPciIoWidthUint8,
201 EfiPciIoWidthUint16,
202 EfiPciIoWidthUint32,
203 EfiPciIoWidthUint64,
204 EfiPciIoWidthFifoUint8,
205 EfiPciIoWidthFifoUint16,
206 EfiPciIoWidthFifoUint32,
207 EfiPciIoWidthFifoUint64,
208 EfiPciIoWidthFillUint8,
209 EfiPciIoWidthFillUint16,
210 EfiPciIoWidthFillUint32,
211 EfiPciIoWidthFillUint64,
212 EfiPciIoWidthMaximum
213} EFI_PCI_IO_PROTOCOL_WIDTH;
214
215typedef enum {
216 EfiPciIoAttributeOperationGet,
217 EfiPciIoAttributeOperationSet,
218 EfiPciIoAttributeOperationEnable,
219 EfiPciIoAttributeOperationDisable,
220 EfiPciIoAttributeOperationSupported,
221 EfiPciIoAttributeOperationMaximum
222} EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION;
223
224
225typedef struct {
226 void *read;
227 void *write;
228} efi_pci_io_protocol_access_t;
229
230typedef struct {
231 void *poll_mem;
232 void *poll_io;
233 efi_pci_io_protocol_access_t mem;
234 efi_pci_io_protocol_access_t io;
235 efi_pci_io_protocol_access_t pci;
236 void *copy_mem;
237 void *map;
238 void *unmap;
239 void *allocate_buffer;
240 void *free_buffer;
241 void *flush;
242 void *get_location;
243 void *attributes;
244 void *get_bar_attributes;
245 void *set_bar_attributes;
246 uint64_t romsize;
247 void *romimage;
248} efi_pci_io_protocol;
249
250#define EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO 0x0001
251#define EFI_PCI_IO_ATTRIBUTE_ISA_IO 0x0002
252#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO 0x0004
253#define EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY 0x0008
254#define EFI_PCI_IO_ATTRIBUTE_VGA_IO 0x0010
255#define EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO 0x0020
256#define EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO 0x0040
257#define EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE 0x0080
258#define EFI_PCI_IO_ATTRIBUTE_IO 0x0100
259#define EFI_PCI_IO_ATTRIBUTE_MEMORY 0x0200
260#define EFI_PCI_IO_ATTRIBUTE_BUS_MASTER 0x0400
261#define EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED 0x0800
262#define EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE 0x1000
263#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE 0x2000
264#define EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM 0x4000
265#define EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE 0x8000
266#define EFI_PCI_IO_ATTRIBUTE_ISA_IO_16 0x10000
267#define EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16 0x20000
268#define EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 0x40000
269
199/* 270/*
200 * Types and defines for EFI ResetSystem 271 * Types and defines for EFI ResetSystem
201 */ 272 */