diff options
| -rw-r--r-- | arch/x86/boot/compressed/eboot.c | 118 | ||||
| -rw-r--r-- | arch/x86/include/asm/bootparam.h | 1 | ||||
| -rw-r--r-- | arch/x86/include/asm/pci.h | 12 | ||||
| -rw-r--r-- | include/linux/efi.h | 71 |
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 | ||
| 247 | static 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 | |||
| 357 | free_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 */ |
| 18 | struct setup_data { | 19 | struct 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 | ||
| 174 | struct 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 | ||
| 199 | typedef 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 | |||
| 215 | typedef enum { | ||
| 216 | EfiPciIoAttributeOperationGet, | ||
| 217 | EfiPciIoAttributeOperationSet, | ||
| 218 | EfiPciIoAttributeOperationEnable, | ||
| 219 | EfiPciIoAttributeOperationDisable, | ||
| 220 | EfiPciIoAttributeOperationSupported, | ||
| 221 | EfiPciIoAttributeOperationMaximum | ||
| 222 | } EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION; | ||
| 223 | |||
| 224 | |||
| 225 | typedef struct { | ||
| 226 | void *read; | ||
| 227 | void *write; | ||
| 228 | } efi_pci_io_protocol_access_t; | ||
| 229 | |||
| 230 | typedef 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 | */ |
