diff options
Diffstat (limited to 'arch/x86/boot/compressed/eboot.c')
| -rw-r--r-- | arch/x86/boot/compressed/eboot.c | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index f277184e2ac1..de8eebd6f67c 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
| @@ -19,7 +19,10 @@ | |||
| 19 | 19 | ||
| 20 | static efi_system_table_t *sys_table; | 20 | static efi_system_table_t *sys_table; |
| 21 | 21 | ||
| 22 | struct efi_config *efi_early; | 22 | static struct efi_config *efi_early; |
| 23 | |||
| 24 | #define efi_call_early(f, ...) \ | ||
| 25 | efi_early->call(efi_early->f, __VA_ARGS__); | ||
| 23 | 26 | ||
| 24 | #define BOOT_SERVICES(bits) \ | 27 | #define BOOT_SERVICES(bits) \ |
| 25 | static void setup_boot_services##bits(struct efi_config *c) \ | 28 | static void setup_boot_services##bits(struct efi_config *c) \ |
| @@ -265,21 +268,25 @@ void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) | |||
| 265 | 268 | ||
| 266 | offset = offsetof(typeof(*out), output_string); | 269 | offset = offsetof(typeof(*out), output_string); |
| 267 | output_string = efi_early->text_output + offset; | 270 | output_string = efi_early->text_output + offset; |
| 271 | out = (typeof(out))(unsigned long)efi_early->text_output; | ||
| 268 | func = (u64 *)output_string; | 272 | func = (u64 *)output_string; |
| 269 | 273 | ||
| 270 | efi_early->call(*func, efi_early->text_output, str); | 274 | efi_early->call(*func, out, str); |
| 271 | } else { | 275 | } else { |
| 272 | struct efi_simple_text_output_protocol_32 *out; | 276 | struct efi_simple_text_output_protocol_32 *out; |
| 273 | u32 *func; | 277 | u32 *func; |
| 274 | 278 | ||
| 275 | offset = offsetof(typeof(*out), output_string); | 279 | offset = offsetof(typeof(*out), output_string); |
| 276 | output_string = efi_early->text_output + offset; | 280 | output_string = efi_early->text_output + offset; |
| 281 | out = (typeof(out))(unsigned long)efi_early->text_output; | ||
| 277 | func = (u32 *)output_string; | 282 | func = (u32 *)output_string; |
| 278 | 283 | ||
| 279 | efi_early->call(*func, efi_early->text_output, str); | 284 | efi_early->call(*func, out, str); |
| 280 | } | 285 | } |
| 281 | } | 286 | } |
| 282 | 287 | ||
| 288 | #include "../../../../drivers/firmware/efi/libstub/efi-stub-helper.c" | ||
| 289 | |||
| 283 | static void find_bits(unsigned long mask, u8 *pos, u8 *size) | 290 | static void find_bits(unsigned long mask, u8 *pos, u8 *size) |
| 284 | { | 291 | { |
| 285 | u8 first, len; | 292 | u8 first, len; |
| @@ -360,7 +367,7 @@ free_struct: | |||
| 360 | return status; | 367 | return status; |
| 361 | } | 368 | } |
| 362 | 369 | ||
| 363 | static efi_status_t | 370 | static void |
| 364 | setup_efi_pci32(struct boot_params *params, void **pci_handle, | 371 | setup_efi_pci32(struct boot_params *params, void **pci_handle, |
| 365 | unsigned long size) | 372 | unsigned long size) |
| 366 | { | 373 | { |
| @@ -403,8 +410,6 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle, | |||
| 403 | data = (struct setup_data *)rom; | 410 | data = (struct setup_data *)rom; |
| 404 | 411 | ||
| 405 | } | 412 | } |
| 406 | |||
| 407 | return status; | ||
| 408 | } | 413 | } |
| 409 | 414 | ||
| 410 | static efi_status_t | 415 | static efi_status_t |
| @@ -463,7 +468,7 @@ free_struct: | |||
| 463 | 468 | ||
| 464 | } | 469 | } |
| 465 | 470 | ||
| 466 | static efi_status_t | 471 | static void |
| 467 | setup_efi_pci64(struct boot_params *params, void **pci_handle, | 472 | setup_efi_pci64(struct boot_params *params, void **pci_handle, |
| 468 | unsigned long size) | 473 | unsigned long size) |
| 469 | { | 474 | { |
| @@ -506,11 +511,18 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle, | |||
| 506 | data = (struct setup_data *)rom; | 511 | data = (struct setup_data *)rom; |
| 507 | 512 | ||
| 508 | } | 513 | } |
| 509 | |||
| 510 | return status; | ||
| 511 | } | 514 | } |
| 512 | 515 | ||
| 513 | static efi_status_t setup_efi_pci(struct boot_params *params) | 516 | /* |
| 517 | * There's no way to return an informative status from this function, | ||
| 518 | * because any analysis (and printing of error messages) needs to be | ||
| 519 | * done directly at the EFI function call-site. | ||
| 520 | * | ||
| 521 | * For example, EFI_INVALID_PARAMETER could indicate a bug or maybe we | ||
| 522 | * just didn't find any PCI devices, but there's no way to tell outside | ||
| 523 | * the context of the call. | ||
| 524 | */ | ||
| 525 | static void setup_efi_pci(struct boot_params *params) | ||
| 514 | { | 526 | { |
| 515 | efi_status_t status; | 527 | efi_status_t status; |
| 516 | void **pci_handle = NULL; | 528 | void **pci_handle = NULL; |
| @@ -527,7 +539,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params) | |||
| 527 | size, (void **)&pci_handle); | 539 | size, (void **)&pci_handle); |
| 528 | 540 | ||
| 529 | if (status != EFI_SUCCESS) | 541 | if (status != EFI_SUCCESS) |
| 530 | return status; | 542 | return; |
| 531 | 543 | ||
| 532 | status = efi_call_early(locate_handle, | 544 | status = efi_call_early(locate_handle, |
| 533 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, | 545 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, |
| @@ -538,13 +550,12 @@ static efi_status_t setup_efi_pci(struct boot_params *params) | |||
| 538 | goto free_handle; | 550 | goto free_handle; |
| 539 | 551 | ||
| 540 | if (efi_early->is64) | 552 | if (efi_early->is64) |
| 541 | status = setup_efi_pci64(params, pci_handle, size); | 553 | setup_efi_pci64(params, pci_handle, size); |
| 542 | else | 554 | else |
| 543 | status = setup_efi_pci32(params, pci_handle, size); | 555 | setup_efi_pci32(params, pci_handle, size); |
| 544 | 556 | ||
| 545 | free_handle: | 557 | free_handle: |
| 546 | efi_call_early(free_pool, pci_handle); | 558 | efi_call_early(free_pool, pci_handle); |
| 547 | return status; | ||
| 548 | } | 559 | } |
| 549 | 560 | ||
| 550 | static void | 561 | static void |
| @@ -1032,7 +1043,6 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
| 1032 | int i; | 1043 | int i; |
| 1033 | unsigned long ramdisk_addr; | 1044 | unsigned long ramdisk_addr; |
| 1034 | unsigned long ramdisk_size; | 1045 | unsigned long ramdisk_size; |
| 1035 | unsigned long initrd_addr_max; | ||
| 1036 | 1046 | ||
| 1037 | efi_early = c; | 1047 | efi_early = c; |
| 1038 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; | 1048 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; |
| @@ -1095,15 +1105,20 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
| 1095 | 1105 | ||
| 1096 | memset(sdt, 0, sizeof(*sdt)); | 1106 | memset(sdt, 0, sizeof(*sdt)); |
| 1097 | 1107 | ||
| 1098 | if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) | ||
| 1099 | initrd_addr_max = -1UL; | ||
| 1100 | else | ||
| 1101 | initrd_addr_max = hdr->initrd_addr_max; | ||
| 1102 | |||
| 1103 | status = handle_cmdline_files(sys_table, image, | 1108 | status = handle_cmdline_files(sys_table, image, |
| 1104 | (char *)(unsigned long)hdr->cmd_line_ptr, | 1109 | (char *)(unsigned long)hdr->cmd_line_ptr, |
| 1105 | "initrd=", initrd_addr_max, | 1110 | "initrd=", hdr->initrd_addr_max, |
| 1106 | &ramdisk_addr, &ramdisk_size); | 1111 | &ramdisk_addr, &ramdisk_size); |
| 1112 | |||
| 1113 | if (status != EFI_SUCCESS && | ||
| 1114 | hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) { | ||
| 1115 | efi_printk(sys_table, "Trying to load files to higher address\n"); | ||
| 1116 | status = handle_cmdline_files(sys_table, image, | ||
| 1117 | (char *)(unsigned long)hdr->cmd_line_ptr, | ||
| 1118 | "initrd=", -1UL, | ||
| 1119 | &ramdisk_addr, &ramdisk_size); | ||
| 1120 | } | ||
| 1121 | |||
| 1107 | if (status != EFI_SUCCESS) | 1122 | if (status != EFI_SUCCESS) |
| 1108 | goto fail2; | 1123 | goto fail2; |
| 1109 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; | 1124 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; |
| @@ -1376,10 +1391,7 @@ struct boot_params *efi_main(struct efi_config *c, | |||
| 1376 | 1391 | ||
| 1377 | setup_graphics(boot_params); | 1392 | setup_graphics(boot_params); |
| 1378 | 1393 | ||
| 1379 | status = setup_efi_pci(boot_params); | 1394 | setup_efi_pci(boot_params); |
| 1380 | if (status != EFI_SUCCESS) { | ||
| 1381 | efi_printk(sys_table, "setup_efi_pci() failed!\n"); | ||
| 1382 | } | ||
| 1383 | 1395 | ||
| 1384 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, | 1396 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, |
| 1385 | sizeof(*gdt), (void **)&gdt); | 1397 | sizeof(*gdt), (void **)&gdt); |
