Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/efi: Build our own EFI services pointer table

It's not possible to dereference the EFI System table directly when
booting a 64-bit kernel on a 32-bit EFI firmware because the size of
pointers don't match.

In preparation for supporting the above use case, build a list of
function pointers on boot so that callers don't have to worry about
converting pointer sizes through multiple levels of indirection.

Signed-off-by: Matt Fleming <matt.fleming@intel.com>

+378 -212
+236 -85
arch/x86/boot/compressed/eboot.c
··· 19 19 20 20 static efi_system_table_t *sys_table; 21 21 22 + static struct efi_config *efi_early; 23 + 24 + #define BOOT_SERVICES(bits) \ 25 + static void setup_boot_services##bits(struct efi_config *c) \ 26 + { \ 27 + efi_system_table_##bits##_t *table; \ 28 + efi_boot_services_##bits##_t *bt; \ 29 + \ 30 + table = (typeof(table))sys_table; \ 31 + \ 32 + c->text_output = table->con_out; \ 33 + \ 34 + bt = (typeof(bt))(unsigned long)(table->boottime); \ 35 + \ 36 + c->allocate_pool = bt->allocate_pool; \ 37 + c->allocate_pages = bt->allocate_pages; \ 38 + c->get_memory_map = bt->get_memory_map; \ 39 + c->free_pool = bt->free_pool; \ 40 + c->free_pages = bt->free_pages; \ 41 + c->locate_handle = bt->locate_handle; \ 42 + c->handle_protocol = bt->handle_protocol; \ 43 + c->exit_boot_services = bt->exit_boot_services; \ 44 + } 45 + BOOT_SERVICES(32); 46 + BOOT_SERVICES(64); 47 + 48 + static void efi_printk(efi_system_table_t *, char *); 49 + static void efi_char16_printk(efi_system_table_t *, efi_char16_t *); 50 + 51 + static efi_status_t 52 + efi_file_size(efi_system_table_t *sys_table, void *__fh, 53 + efi_char16_t *filename_16, void **handle, u64 *file_sz) 54 + { 55 + efi_file_handle_t *h, *fh = __fh; 56 + efi_file_info_t *info; 57 + efi_status_t status; 58 + efi_guid_t info_guid = EFI_FILE_INFO_ID; 59 + u32 info_sz; 60 + 61 + status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, 62 + EFI_FILE_MODE_READ, (u64)0); 63 + if (status != EFI_SUCCESS) { 64 + efi_printk(sys_table, "Failed to open file: "); 65 + efi_char16_printk(sys_table, filename_16); 66 + efi_printk(sys_table, "\n"); 67 + return status; 68 + } 69 + 70 + *handle = h; 71 + 72 + info_sz = 0; 73 + status = efi_early->call((unsigned long)h->get_info, h, &info_guid, 74 + &info_sz, NULL); 75 + if (status != EFI_BUFFER_TOO_SMALL) { 76 + efi_printk(sys_table, "Failed to get file info size\n"); 77 + return status; 78 + } 79 + 80 + grow: 81 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 82 + info_sz, (void **)&info); 83 + if (status != EFI_SUCCESS) { 84 + efi_printk(sys_table, "Failed to alloc mem for file info\n"); 85 + return status; 86 + } 87 + 88 + status = efi_early->call((unsigned long)h->get_info, h, &info_guid, 89 + &info_sz, info); 90 + if (status == EFI_BUFFER_TOO_SMALL) { 91 + efi_early->call(efi_early->free_pool, info); 92 + goto grow; 93 + } 94 + 95 + *file_sz = info->file_size; 96 + efi_early->call(efi_early->free_pool, info); 97 + 98 + if (status != EFI_SUCCESS) 99 + efi_printk(sys_table, "Failed to get initrd info\n"); 100 + 101 + return status; 102 + } 103 + 104 + static inline efi_status_t 105 + efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr) 106 + { 107 + efi_file_handle_t *fh = __fh; 108 + return efi_early->call((unsigned long)fh->read, handle, size, addr); 109 + } 110 + 111 + static inline efi_status_t efi_file_close(void *__fh, void *handle) 112 + { 113 + efi_file_handle_t *fh = __fh; 114 + 115 + return efi_early->call((unsigned long)fh->close, handle); 116 + } 117 + 118 + static inline efi_status_t 119 + efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) 120 + { 121 + efi_file_io_interface_t *io; 122 + efi_loaded_image_t *image = __image; 123 + efi_file_handle_t *fh; 124 + efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; 125 + efi_status_t status; 126 + void *handle = (void *)(unsigned long)image->device_handle; 127 + u32 func; 128 + 129 + status = efi_early->call(efi_early->handle_protocol, handle, 130 + &fs_proto, (void **)&io); 131 + if (status != EFI_SUCCESS) { 132 + efi_printk(sys_table, "Failed to handle fs_proto\n"); 133 + return status; 134 + } 135 + 136 + func = (unsigned long)io->open_volume; 137 + status = efi_early->call(func, io, &fh); 138 + if (status != EFI_SUCCESS) 139 + efi_printk(sys_table, "Failed to open volume\n"); 140 + 141 + *__fh = fh; 142 + return status; 143 + } 144 + 145 + static inline void 146 + efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) 147 + { 148 + struct efi_simple_text_output_protocol *out; 149 + unsigned long output_string; 150 + size_t offset; 151 + unsigned long *func; 152 + 153 + offset = offsetof(typeof(*out), output_string); 154 + output_string = efi_early->text_output + offset; 155 + func = (unsigned long *)output_string; 156 + 157 + efi_early->call(*func, efi_early->text_output, str); 158 + } 22 159 23 160 #include "../../../../drivers/firmware/efi/efi-stub-helper.c" 24 - 25 - 26 161 27 162 static void find_bits(unsigned long mask, u8 *pos, u8 *size) 28 163 { ··· 186 51 { 187 52 efi_pci_io_protocol *pci; 188 53 efi_status_t status; 189 - void **pci_handle; 54 + void **pci_handle = NULL; 190 55 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; 191 56 unsigned long nr_pci, size = 0; 192 57 int i; ··· 197 62 while (data && data->next) 198 63 data = (struct setup_data *)(unsigned long)data->next; 199 64 200 - status = efi_call_phys5(sys_table->boottime->locate_handle, 201 - EFI_LOCATE_BY_PROTOCOL, &pci_proto, 202 - NULL, &size, pci_handle); 65 + status = efi_early->call(efi_early->locate_handle, 66 + EFI_LOCATE_BY_PROTOCOL, 67 + &pci_proto, NULL, &size, pci_handle); 203 68 204 69 if (status == EFI_BUFFER_TOO_SMALL) { 205 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 206 - EFI_LOADER_DATA, size, &pci_handle); 70 + status = efi_early->call(efi_early->allocate_pool, 71 + EFI_LOADER_DATA, 72 + size, (void **)&pci_handle); 207 73 208 74 if (status != EFI_SUCCESS) 209 75 return status; 210 76 211 - status = efi_call_phys5(sys_table->boottime->locate_handle, 212 - EFI_LOCATE_BY_PROTOCOL, &pci_proto, 213 - NULL, &size, pci_handle); 77 + status = efi_early->call(efi_early->locate_handle, 78 + EFI_LOCATE_BY_PROTOCOL, &pci_proto, 79 + NULL, &size, pci_handle); 214 80 } 215 81 216 82 if (status != EFI_SUCCESS) ··· 223 87 uint64_t attributes; 224 88 struct pci_setup_rom *rom; 225 89 226 - status = efi_call_phys3(sys_table->boottime->handle_protocol, 227 - h, &pci_proto, &pci); 90 + status = efi_early->call(efi_early->handle_protocol, h, 91 + &pci_proto, (void **)&pci); 228 92 229 93 if (status != EFI_SUCCESS) 230 94 continue; ··· 233 97 continue; 234 98 235 99 #ifdef CONFIG_X86_64 236 - status = efi_call_phys4(pci->attributes, pci, 237 - EfiPciIoAttributeOperationGet, 0, 238 - &attributes); 100 + status = efi_early->call((unsigned long)pci->attributes, pci, 101 + EfiPciIoAttributeOperationGet, 0, 102 + &attributes); 239 103 #else 240 - status = efi_call_phys5(pci->attributes, pci, 241 - EfiPciIoAttributeOperationGet, 0, 0, 242 - &attributes); 104 + status = efi_early->call((unsigned long)pci->attributes, pci, 105 + EfiPciIoAttributeOperationGet, 0, 0, 106 + &attributes); 243 107 #endif 244 108 if (status != EFI_SUCCESS) 245 109 continue; ··· 249 113 250 114 size = pci->romsize + sizeof(*rom); 251 115 252 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 253 - EFI_LOADER_DATA, size, &rom); 116 + status = efi_early->call(efi_early->allocate_pool, 117 + EFI_LOADER_DATA, size, &rom); 254 118 255 119 if (status != EFI_SUCCESS) 256 120 continue; ··· 260 124 rom->data.next = 0; 261 125 rom->pcilen = pci->romsize; 262 126 263 - status = efi_call_phys5(pci->pci.read, pci, 264 - EfiPciIoWidthUint16, PCI_VENDOR_ID, 265 - 1, &(rom->vendor)); 127 + status = efi_early->call((unsigned long)pci->pci.read, pci, 128 + EfiPciIoWidthUint16, PCI_VENDOR_ID, 129 + 1, &(rom->vendor)); 266 130 267 131 if (status != EFI_SUCCESS) 268 132 goto free_struct; 269 133 270 - status = efi_call_phys5(pci->pci.read, pci, 271 - EfiPciIoWidthUint16, PCI_DEVICE_ID, 272 - 1, &(rom->devid)); 134 + status = efi_early->call((unsigned long)pci->pci.read, pci, 135 + EfiPciIoWidthUint16, PCI_DEVICE_ID, 136 + 1, &(rom->devid)); 273 137 274 138 if (status != EFI_SUCCESS) 275 139 goto free_struct; 276 140 277 - status = efi_call_phys5(pci->get_location, pci, 278 - &(rom->segment), &(rom->bus), 279 - &(rom->device), &(rom->function)); 141 + status = efi_early->call((unsigned long)pci->get_location, pci, 142 + &(rom->segment), &(rom->bus), 143 + &(rom->device), &(rom->function)); 280 144 281 145 if (status != EFI_SUCCESS) 282 146 goto free_struct; ··· 292 156 293 157 continue; 294 158 free_struct: 295 - efi_call_phys1(sys_table->boottime->free_pool, rom); 159 + efi_early->call(efi_early->free_pool, rom); 296 160 } 297 161 298 162 free_handle: 299 - efi_call_phys1(sys_table->boottime->free_pool, pci_handle); 163 + efi_early->call(efi_early->free_pool, pci_handle); 300 164 return status; 301 165 } 302 166 ··· 310 174 struct efi_pixel_bitmask pixel_info; 311 175 unsigned long nr_gops; 312 176 efi_status_t status; 313 - void **gop_handle; 177 + void **gop_handle = NULL; 314 178 u16 width, height; 315 179 u32 fb_base, fb_size; 316 180 u32 pixels_per_scan_line; 317 181 int pixel_format; 318 182 int i; 319 183 320 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 321 - EFI_LOADER_DATA, size, &gop_handle); 184 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 185 + size, (void **)&gop_handle); 322 186 if (status != EFI_SUCCESS) 323 187 return status; 324 188 325 - status = efi_call_phys5(sys_table->boottime->locate_handle, 326 - EFI_LOCATE_BY_PROTOCOL, proto, 327 - NULL, &size, gop_handle); 189 + status = efi_early->call(efi_early->locate_handle, 190 + EFI_LOCATE_BY_PROTOCOL, 191 + proto, NULL, &size, gop_handle); 328 192 if (status != EFI_SUCCESS) 329 193 goto free_handle; 330 194 ··· 338 202 void *dummy; 339 203 void *h = gop_handle[i]; 340 204 341 - status = efi_call_phys3(sys_table->boottime->handle_protocol, 342 - h, proto, &gop); 205 + status = efi_early->call(efi_early->handle_protocol, h, 206 + proto, (void **)&gop); 343 207 if (status != EFI_SUCCESS) 344 208 continue; 345 209 346 - status = efi_call_phys3(sys_table->boottime->handle_protocol, 347 - h, &conout_proto, &dummy); 348 - 210 + status = efi_early->call(efi_early->handle_protocol, h, 211 + &conout_proto, &dummy); 349 212 if (status == EFI_SUCCESS) 350 213 conout_found = true; 351 214 352 - status = efi_call_phys4(gop->query_mode, gop, 353 - gop->mode->mode, &size, &info); 215 + status = efi_early->call((unsigned long)gop->query_mode, gop, 216 + gop->mode->mode, &size, &info); 354 217 if (status == EFI_SUCCESS && (!first_gop || conout_found)) { 355 218 /* 356 219 * Systems that use the UEFI Console Splitter may ··· 438 303 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; 439 304 440 305 free_handle: 441 - efi_call_phys1(sys_table->boottime->free_pool, gop_handle); 306 + efi_early->call(efi_early->free_pool, gop_handle); 442 307 return status; 443 308 } 444 309 ··· 455 320 void **uga_handle = NULL; 456 321 int i; 457 322 458 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 459 - EFI_LOADER_DATA, size, &uga_handle); 323 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 324 + size, (void **)&uga_handle); 460 325 if (status != EFI_SUCCESS) 461 326 return status; 462 327 463 - status = efi_call_phys5(sys_table->boottime->locate_handle, 464 - EFI_LOCATE_BY_PROTOCOL, uga_proto, 465 - NULL, &size, uga_handle); 328 + status = efi_early->call(efi_early->locate_handle, 329 + EFI_LOCATE_BY_PROTOCOL, 330 + uga_proto, NULL, &size, uga_handle); 466 331 if (status != EFI_SUCCESS) 467 332 goto free_handle; 468 333 ··· 475 340 u32 w, h, depth, refresh; 476 341 void *pciio; 477 342 478 - status = efi_call_phys3(sys_table->boottime->handle_protocol, 479 - handle, uga_proto, &uga); 343 + status = efi_early->call(efi_early->handle_protocol, handle, 344 + uga_proto, (void **)&uga); 480 345 if (status != EFI_SUCCESS) 481 346 continue; 482 347 483 - efi_call_phys3(sys_table->boottime->handle_protocol, 484 - handle, &pciio_proto, &pciio); 348 + efi_early->call(efi_early->handle_protocol, handle, 349 + &pciio_proto, &pciio); 485 350 486 - status = efi_call_phys5(uga->get_mode, uga, &w, &h, 487 - &depth, &refresh); 351 + status = efi_early->call((unsigned long)uga->get_mode, uga, 352 + &w, &h, &depth, &refresh); 488 353 if (status == EFI_SUCCESS && (!first_uga || pciio)) { 489 354 width = w; 490 355 height = h; ··· 521 386 522 387 523 388 free_handle: 524 - efi_call_phys1(sys_table->boottime->free_pool, uga_handle); 389 + efi_early->call(efi_early->free_pool, uga_handle); 525 390 return status; 526 391 } 527 392 ··· 539 404 memset(si, 0, sizeof(*si)); 540 405 541 406 size = 0; 542 - status = efi_call_phys5(sys_table->boottime->locate_handle, 543 - EFI_LOCATE_BY_PROTOCOL, &graphics_proto, 544 - NULL, &size, gop_handle); 407 + status = efi_early->call(efi_early->locate_handle, 408 + EFI_LOCATE_BY_PROTOCOL, 409 + &graphics_proto, NULL, &size, gop_handle); 545 410 if (status == EFI_BUFFER_TOO_SMALL) 546 411 status = setup_gop(si, &graphics_proto, size); 547 412 548 413 if (status != EFI_SUCCESS) { 549 414 size = 0; 550 - status = efi_call_phys5(sys_table->boottime->locate_handle, 551 - EFI_LOCATE_BY_PROTOCOL, &uga_proto, 552 - NULL, &size, uga_handle); 415 + status = efi_early->call(efi_early->locate_handle, 416 + EFI_LOCATE_BY_PROTOCOL, 417 + &uga_proto, NULL, &size, uga_handle); 553 418 if (status == EFI_BUFFER_TOO_SMALL) 554 419 setup_uga(si, &uga_proto, size); 555 420 } 556 421 } 557 - 558 422 559 423 /* 560 424 * Because the x86 boot code expects to be passed a boot_params we 561 425 * need to create one ourselves (usually the bootloader would create 562 426 * one for us). 563 427 */ 564 - struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) 428 + struct boot_params *make_boot_params(struct efi_config *c) 565 429 { 566 430 struct boot_params *boot_params; 567 431 struct sys_desc_table *sdt; ··· 568 434 struct setup_header *hdr; 569 435 struct efi_info *efi; 570 436 efi_loaded_image_t *image; 571 - void *options; 437 + void *options, *handle; 572 438 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; 573 439 int options_size = 0; 574 440 efi_status_t status; ··· 579 445 unsigned long ramdisk_addr; 580 446 unsigned long ramdisk_size; 581 447 582 - sys_table = _table; 448 + efi_early = c; 449 + sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; 450 + handle = (void *)(unsigned long)efi_early->image_handle; 583 451 584 452 /* Check if we were booted by the EFI firmware */ 585 453 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 586 454 return NULL; 587 455 588 - status = efi_call_phys3(sys_table->boottime->handle_protocol, 589 - handle, &proto, (void *)&image); 456 + if (efi_early->is64) 457 + setup_boot_services64(efi_early); 458 + else 459 + setup_boot_services32(efi_early); 460 + 461 + status = efi_early->call(efi_early->handle_protocol, handle, 462 + &proto, (void *)&image); 590 463 if (status != EFI_SUCCESS) { 591 464 efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); 592 465 return NULL; ··· 782 641 sizeof(struct e820entry) * nr_desc; 783 642 784 643 if (*e820ext) { 785 - efi_call_phys1(sys_table->boottime->free_pool, *e820ext); 644 + efi_early->call(efi_early->free_pool, *e820ext); 786 645 *e820ext = NULL; 787 646 *e820ext_size = 0; 788 647 } 789 648 790 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 791 - EFI_LOADER_DATA, size, e820ext); 792 - 649 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 650 + size, (void **)e820ext); 793 651 if (status == EFI_SUCCESS) 794 652 *e820ext_size = size; 795 653 ··· 831 691 if (status != EFI_SUCCESS) 832 692 goto free_mem_map; 833 693 834 - efi_call_phys1(sys_table->boottime->free_pool, mem_map); 694 + efi_early->call(efi_early->free_pool, mem_map); 835 695 goto get_map; /* Allocated memory, get map again */ 836 696 } 837 697 ··· 848 708 #endif 849 709 850 710 /* Might as well exit boot services now */ 851 - status = efi_call_phys2(sys_table->boottime->exit_boot_services, 852 - handle, key); 711 + status = efi_early->call(efi_early->exit_boot_services, handle, key); 853 712 if (status != EFI_SUCCESS) { 854 713 /* 855 714 * ExitBootServices() will fail if any of the event ··· 861 722 goto free_mem_map; 862 723 863 724 called_exit = true; 864 - efi_call_phys1(sys_table->boottime->free_pool, mem_map); 725 + efi_early->call(efi_early->free_pool, mem_map); 865 726 goto get_map; 866 727 } 867 728 ··· 875 736 return EFI_SUCCESS; 876 737 877 738 free_mem_map: 878 - efi_call_phys1(sys_table->boottime->free_pool, mem_map); 739 + efi_early->call(efi_early->free_pool, mem_map); 879 740 return status; 880 741 } 881 - 882 742 883 743 /* 884 744 * On success we return a pointer to a boot_params structure, and NULL 885 745 * on failure. 886 746 */ 887 - struct boot_params *efi_main(void *handle, efi_system_table_t *_table, 747 + struct boot_params *efi_main(struct efi_config *c, 888 748 struct boot_params *boot_params) 889 749 { 890 - struct desc_ptr *gdt; 750 + struct desc_ptr *gdt = NULL; 891 751 efi_loaded_image_t *image; 892 752 struct setup_header *hdr = &boot_params->hdr; 893 753 efi_status_t status; 894 754 struct desc_struct *desc; 755 + void *handle; 756 + efi_system_table_t *_table; 757 + bool is64; 758 + 759 + efi_early = c; 760 + 761 + _table = (efi_system_table_t *)(unsigned long)efi_early->table; 762 + handle = (void *)(unsigned long)efi_early->image_handle; 763 + is64 = efi_early->is64; 895 764 896 765 sys_table = _table; 897 766 ··· 907 760 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 908 761 goto fail; 909 762 763 + if (is64) 764 + setup_boot_services64(efi_early); 765 + else 766 + setup_boot_services32(efi_early); 767 + 910 768 setup_graphics(boot_params); 911 769 912 770 setup_efi_pci(boot_params); 913 771 914 - status = efi_call_phys3(sys_table->boottime->allocate_pool, 915 - EFI_LOADER_DATA, sizeof(*gdt), 916 - (void **)&gdt); 772 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 773 + sizeof(*gdt), (void **)&gdt); 917 774 if (status != EFI_SUCCESS) { 918 775 efi_printk(sys_table, "Failed to alloc mem for gdt structure\n"); 919 776 goto fail;
+16
arch/x86/boot/compressed/eboot.h
··· 103 103 void *blt; 104 104 }; 105 105 106 + struct efi_config { 107 + u64 image_handle; 108 + u64 table; 109 + u64 allocate_pool; 110 + u64 allocate_pages; 111 + u64 get_memory_map; 112 + u64 free_pool; 113 + u64 free_pages; 114 + u64 locate_handle; 115 + u64 handle_protocol; 116 + u64 exit_boot_services; 117 + u64 text_output; 118 + efi_status_t (*call)(unsigned long, ...); 119 + bool is64; 120 + } __packed; 121 + 106 122 #endif /* BOOT_COMPRESSED_EBOOT_H */
+41 -7
arch/x86/boot/compressed/head_32.S
··· 42 42 ENTRY(efi_pe_entry) 43 43 add $0x4, %esp 44 44 45 + call 1f 46 + 1: popl %esi 47 + subl $1b, %esi 48 + 49 + popl %ecx 50 + movl %ecx, efi32_config(%esi) /* Handle */ 51 + popl %ecx 52 + movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */ 53 + 54 + /* Relocate efi_config->call() */ 55 + leal efi32_config(%esi), %eax 56 + add %esi, 88(%eax) 57 + pushl %eax 58 + 45 59 call make_boot_params 46 60 cmpl $0, %eax 47 - je 1f 48 - movl 0x4(%esp), %esi 49 - movl (%esp), %ecx 61 + je fail 62 + popl %ecx 50 63 pushl %eax 51 - pushl %esi 52 64 pushl %ecx 53 - sub $0x4, %esp 65 + jmp 2f /* Skip efi_config initialization */ 54 66 55 67 ENTRY(efi_stub_entry) 56 68 add $0x4, %esp 69 + popl %ecx 70 + popl %edx 71 + 72 + call 1f 73 + 1: popl %esi 74 + subl $1b, %esi 75 + 76 + movl %ecx, efi32_config(%esi) /* Handle */ 77 + movl %edx, efi32_config+8(%esi) /* EFI System table pointer */ 78 + 79 + /* Relocate efi_config->call() */ 80 + leal efi32_config(%esi), %eax 81 + add %esi, 88(%eax) 82 + pushl %eax 83 + 2: 57 84 call efi_main 58 85 cmpl $0, %eax 59 86 movl %eax, %esi 60 87 jne 2f 61 - 1: 88 + fail: 62 89 /* EFI init failed, so hang. */ 63 90 hlt 64 - jmp 1b 91 + jmp fail 65 92 2: 66 93 call 3f 67 94 3: ··· 228 201 */ 229 202 xorl %ebx, %ebx 230 203 jmp *%eax 204 + 205 + .data 206 + efi32_config: 207 + .fill 11,8,0 208 + .long efi_call_phys 209 + .long 0 210 + .byte 0 231 211 232 212 /* 233 213 * Stack and heap for uncompression
+47 -10
arch/x86/boot/compressed/head_64.S
··· 209 209 jmp preferred_addr 210 210 211 211 ENTRY(efi_pe_entry) 212 - mov %rcx, %rdi 213 - mov %rdx, %rsi 214 - pushq %rdi 215 - pushq %rsi 212 + movq %rcx, efi64_config(%rip) /* Handle */ 213 + movq %rdx, efi64_config+8(%rip) /* EFI System table pointer */ 214 + 215 + leaq efi64_config(%rip), %rax 216 + movq %rax, efi_config(%rip) 217 + 218 + call 1f 219 + 1: popq %rbp 220 + subq $1b, %rbp 221 + 222 + /* 223 + * Relocate efi_config->call(). 224 + */ 225 + addq %rbp, efi64_config+88(%rip) 226 + 227 + movq %rax, %rdi 216 228 call make_boot_params 217 229 cmpq $0,%rax 218 - je 1f 219 - mov %rax, %rdx 220 - popq %rsi 221 - popq %rdi 230 + je fail 231 + mov %rax, %rsi 232 + jmp 2f /* Skip the relocation */ 222 233 223 234 ENTRY(efi_stub_entry) 235 + movq %rdi, efi64_config(%rip) /* Handle */ 236 + movq %rsi, efi64_config+8(%rip) /* EFI System table pointer */ 237 + 238 + leaq efi64_config(%rip), %rax 239 + movq %rax, efi_config(%rip) 240 + 241 + call 1f 242 + 1: popq %rbp 243 + subq $1b, %rbp 244 + 245 + /* 246 + * Relocate efi_config->call(). 247 + */ 248 + movq efi_config(%rip), %rax 249 + addq %rbp, 88(%rax) 250 + movq %rdx, %rsi 251 + 2: 252 + movq efi_config(%rip), %rdi 224 253 call efi_main 225 254 movq %rax,%rsi 226 255 cmpq $0,%rax 227 256 jne 2f 228 - 1: 257 + fail: 229 258 /* EFI init failed, so hang. */ 230 259 hlt 231 - jmp 1b 260 + jmp fail 232 261 2: 233 262 call 3f 234 263 3: ··· 401 372 .quad 0x0000000000000000 /* TS continued */ 402 373 gdt_end: 403 374 375 + efi_config: 376 + .quad 0 377 + 378 + .global efi64_config 379 + efi64_config: 380 + .fill 11,8,0 381 + .quad efi_call6 382 + .byte 1 404 383 /* 405 384 * Stack and heap for uncompression 406 385 */
+38 -110
drivers/firmware/efi/efi-stub-helper.c
··· 16 16 u64 size; 17 17 }; 18 18 19 - 20 - 21 - 22 - static void efi_char16_printk(efi_system_table_t *sys_table_arg, 23 - efi_char16_t *str) 24 - { 25 - struct efi_simple_text_output_protocol *out; 26 - 27 - out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out; 28 - efi_call_phys2(out->output_string, out, str); 29 - } 30 - 31 19 static void efi_printk(efi_system_table_t *sys_table_arg, char *str) 32 20 { 33 21 char *s8; ··· 53 65 * allocation which may be in a new descriptor region. 54 66 */ 55 67 *map_size += sizeof(*m); 56 - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool, 57 - EFI_LOADER_DATA, *map_size, (void **)&m); 68 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 69 + *map_size, (void **)&m); 58 70 if (status != EFI_SUCCESS) 59 71 goto fail; 60 72 61 - status = efi_call_phys5(sys_table_arg->boottime->get_memory_map, 62 - map_size, m, &key, desc_size, &desc_version); 73 + *desc_size = 0; 74 + key = 0; 75 + status = efi_early->call(efi_early->get_memory_map, map_size, m, 76 + &key, desc_size, &desc_version); 63 77 if (status == EFI_BUFFER_TOO_SMALL) { 64 - efi_call_phys1(sys_table_arg->boottime->free_pool, m); 78 + efi_early->call(efi_early->free_pool, m); 65 79 goto again; 66 80 } 67 81 68 82 if (status != EFI_SUCCESS) 69 - efi_call_phys1(sys_table_arg->boottime->free_pool, m); 83 + efi_early->call(efi_early->free_pool, m); 84 + 70 85 if (key_ptr && status == EFI_SUCCESS) 71 86 *key_ptr = key; 72 87 if (desc_ver && status == EFI_SUCCESS) ··· 149 158 if (!max_addr) 150 159 status = EFI_NOT_FOUND; 151 160 else { 152 - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages, 153 - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 154 - nr_pages, &max_addr); 161 + status = efi_early->call(efi_early->allocate_pages, 162 + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 163 + nr_pages, &max_addr); 155 164 if (status != EFI_SUCCESS) { 156 165 max = max_addr; 157 166 max_addr = 0; ··· 161 170 *addr = max_addr; 162 171 } 163 172 164 - efi_call_phys1(sys_table_arg->boottime->free_pool, map); 165 - 173 + efi_early->call(efi_early->free_pool, map); 166 174 fail: 167 175 return status; 168 176 } ··· 221 231 if ((start + size) > end) 222 232 continue; 223 233 224 - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages, 225 - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 226 - nr_pages, &start); 234 + status = efi_early->call(efi_early->allocate_pages, 235 + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 236 + nr_pages, &start); 227 237 if (status == EFI_SUCCESS) { 228 238 *addr = start; 229 239 break; ··· 233 243 if (i == map_size / desc_size) 234 244 status = EFI_NOT_FOUND; 235 245 236 - efi_call_phys1(sys_table_arg->boottime->free_pool, map); 246 + efi_early->call(efi_early->free_pool, map); 237 247 fail: 238 248 return status; 239 249 } ··· 247 257 return; 248 258 249 259 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; 250 - efi_call_phys2(sys_table_arg->boottime->free_pages, addr, nr_pages); 260 + efi_early->call(efi_early->free_pages, addr, nr_pages); 251 261 } 252 262 253 263 ··· 266 276 { 267 277 struct file_info *files; 268 278 unsigned long file_addr; 269 - efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; 270 279 u64 file_size_total; 271 - efi_file_io_interface_t *io; 272 280 efi_file_handle_t *fh; 273 281 efi_status_t status; 274 282 int nr_files; ··· 307 319 if (!nr_files) 308 320 return EFI_SUCCESS; 309 321 310 - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool, 311 - EFI_LOADER_DATA, 312 - nr_files * sizeof(*files), 313 - (void **)&files); 322 + status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA, 323 + nr_files * sizeof(*files), (void **)&files); 314 324 if (status != EFI_SUCCESS) { 315 325 efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n"); 316 326 goto fail; ··· 317 331 str = cmd_line; 318 332 for (i = 0; i < nr_files; i++) { 319 333 struct file_info *file; 320 - efi_file_handle_t *h; 321 - efi_file_info_t *info; 322 334 efi_char16_t filename_16[256]; 323 - unsigned long info_sz; 324 - efi_guid_t info_guid = EFI_FILE_INFO_ID; 325 335 efi_char16_t *p; 326 - u64 file_sz; 327 336 328 337 str = strstr(str, option_string); 329 338 if (!str) ··· 349 368 350 369 /* Only open the volume once. */ 351 370 if (!i) { 352 - efi_boot_services_t *boottime; 353 - 354 - boottime = sys_table_arg->boottime; 355 - 356 - status = efi_call_phys3(boottime->handle_protocol, 357 - image->device_handle, &fs_proto, 358 - (void **)&io); 359 - if (status != EFI_SUCCESS) { 360 - efi_printk(sys_table_arg, "Failed to handle fs_proto\n"); 371 + status = efi_open_volume(sys_table_arg, image, 372 + (void **)&fh); 373 + if (status != EFI_SUCCESS) 361 374 goto free_files; 362 - } 363 - 364 - status = efi_call_phys2(io->open_volume, io, &fh); 365 - if (status != EFI_SUCCESS) { 366 - efi_printk(sys_table_arg, "Failed to open volume\n"); 367 - goto free_files; 368 - } 369 375 } 370 376 371 - status = efi_call_phys5(fh->open, fh, &h, filename_16, 372 - EFI_FILE_MODE_READ, (u64)0); 373 - if (status != EFI_SUCCESS) { 374 - efi_printk(sys_table_arg, "Failed to open file: "); 375 - efi_char16_printk(sys_table_arg, filename_16); 376 - efi_printk(sys_table_arg, "\n"); 377 + status = efi_file_size(sys_table_arg, fh, filename_16, 378 + (void **)&file->handle, &file->size); 379 + if (status != EFI_SUCCESS) 377 380 goto close_handles; 378 - } 379 381 380 - file->handle = h; 381 - 382 - info_sz = 0; 383 - status = efi_call_phys4(h->get_info, h, &info_guid, 384 - &info_sz, NULL); 385 - if (status != EFI_BUFFER_TOO_SMALL) { 386 - efi_printk(sys_table_arg, "Failed to get file info size\n"); 387 - goto close_handles; 388 - } 389 - 390 - grow: 391 - status = efi_call_phys3(sys_table_arg->boottime->allocate_pool, 392 - EFI_LOADER_DATA, info_sz, 393 - (void **)&info); 394 - if (status != EFI_SUCCESS) { 395 - efi_printk(sys_table_arg, "Failed to alloc mem for file info\n"); 396 - goto close_handles; 397 - } 398 - 399 - status = efi_call_phys4(h->get_info, h, &info_guid, 400 - &info_sz, info); 401 - if (status == EFI_BUFFER_TOO_SMALL) { 402 - efi_call_phys1(sys_table_arg->boottime->free_pool, 403 - info); 404 - goto grow; 405 - } 406 - 407 - file_sz = info->file_size; 408 - efi_call_phys1(sys_table_arg->boottime->free_pool, info); 409 - 410 - if (status != EFI_SUCCESS) { 411 - efi_printk(sys_table_arg, "Failed to get file info\n"); 412 - goto close_handles; 413 - } 414 - 415 - file->size = file_sz; 416 - file_size_total += file_sz; 382 + file_size_total += file->size; 417 383 } 418 384 419 385 if (file_size_total) { ··· 396 468 chunksize = EFI_READ_CHUNK_SIZE; 397 469 else 398 470 chunksize = size; 399 - status = efi_call_phys3(fh->read, 400 - files[j].handle, 401 - &chunksize, 402 - (void *)addr); 471 + 472 + status = efi_file_read(fh, files[j].handle, 473 + &chunksize, 474 + (void *)addr); 403 475 if (status != EFI_SUCCESS) { 404 476 efi_printk(sys_table_arg, "Failed to read file\n"); 405 477 goto free_file_total; ··· 408 480 size -= chunksize; 409 481 } 410 482 411 - efi_call_phys1(fh->close, files[j].handle); 483 + efi_file_close(fh, files[j].handle); 412 484 } 413 485 414 486 } 415 487 416 - efi_call_phys1(sys_table_arg->boottime->free_pool, files); 488 + efi_early->call(efi_early->free_pool, files); 417 489 418 490 *load_addr = file_addr; 419 491 *load_size = file_size_total; ··· 425 497 426 498 close_handles: 427 499 for (k = j; k < i; k++) 428 - efi_call_phys1(fh->close, files[k].handle); 500 + efi_file_close(fh, files[k].handle); 429 501 free_files: 430 - efi_call_phys1(sys_table_arg->boottime->free_pool, files); 502 + efi_early->call(efi_early->free_pool, files); 431 503 fail: 432 504 *load_addr = 0; 433 505 *load_size = 0; ··· 473 545 * as possible while respecting the required alignment. 474 546 */ 475 547 nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE; 476 - status = efi_call_phys4(sys_table_arg->boottime->allocate_pages, 477 - EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 478 - nr_pages, &efi_addr); 548 + status = efi_early->call(efi_early->allocate_pages, 549 + EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 550 + nr_pages, &efi_addr); 479 551 new_addr = efi_addr; 480 552 /* 481 553 * If preferred address allocation failed allocate as low as