aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot/compressed
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 20:48:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-11 20:48:30 -0500
commit69019d77c71472428a5d67ab8bb7cfa9145000d0 (patch)
tree370f038a801c5ceee5266bf95944a458bcc0bfbf /arch/x86/boot/compressed
parent6df1e7f2e96721dfdbfd8a034e52bc81916f978c (diff)
parent88392e9dd5a524b8194f1045369c7d0eb16d9f32 (diff)
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI changes from Ingo Molnar: "Main changes: - Add support for earlyprintk=efi which uses the EFI framebuffer. Very useful for debugging boot problems. - EFI stub support for large memory maps (more than 128 entries) - EFI ARM support - this was mostly done by generalizing x86 <-> ARM platform differences, such as by moving x86 EFI code into drivers/firmware/efi/ and sharing it with ARM. - Documentation updates - misc fixes" * 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits) x86/efi: Add EFI framebuffer earlyprintk support boot, efi: Remove redundant memset() x86/efi: Fix config_table_type array termination x86 efi: bugfix interrupt disabling sequence x86: EFI stub support for large memory maps efi: resolve warnings found on ARM compile efi: Fix types in EFI calls to match EFI function definitions. efi: Renames in handle_cmdline_files() to complete generalization. efi: Generalize handle_ramdisks() and rename to handle_cmdline_files(). efi: Allow efi_free() to be called with size of 0 efi: use efi_get_memory_map() to get final map for x86 efi: generalize efi_get_memory_map() efi: Rename __get_map() to efi_get_memory_map() efi: Move unicode to ASCII conversion to shared function. efi: Generalize relocate_kernel() for use by other architectures. efi: Move relocate_kernel() to shared file. efi: Enforce minimum alignment of 1 page on allocations. efi: Rename memory allocation/free functions efi: Add system table pointer argument to shared functions. efi: Move common EFI stub code from x86 arch code to common location ...
Diffstat (limited to 'arch/x86/boot/compressed')
-rw-r--r--arch/x86/boot/compressed/eboot.c789
-rw-r--r--arch/x86/boot/compressed/eboot.h9
2 files changed, 187 insertions, 611 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index b7388a425f09..a7677babf946 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -19,214 +19,10 @@
19 19
20static efi_system_table_t *sys_table; 20static efi_system_table_t *sys_table;
21 21
22static void efi_char16_printk(efi_char16_t *str)
23{
24 struct efi_simple_text_output_protocol *out;
25
26 out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
27 efi_call_phys2(out->output_string, out, str);
28}
29
30static void efi_printk(char *str)
31{
32 char *s8;
33
34 for (s8 = str; *s8; s8++) {
35 efi_char16_t ch[2] = { 0 };
36
37 ch[0] = *s8;
38 if (*s8 == '\n') {
39 efi_char16_t nl[2] = { '\r', 0 };
40 efi_char16_printk(nl);
41 }
42
43 efi_char16_printk(ch);
44 }
45}
46
47static efi_status_t __get_map(efi_memory_desc_t **map, unsigned long *map_size,
48 unsigned long *desc_size)
49{
50 efi_memory_desc_t *m = NULL;
51 efi_status_t status;
52 unsigned long key;
53 u32 desc_version;
54
55 *map_size = sizeof(*m) * 32;
56again:
57 /*
58 * Add an additional efi_memory_desc_t because we're doing an
59 * allocation which may be in a new descriptor region.
60 */
61 *map_size += sizeof(*m);
62 status = efi_call_phys3(sys_table->boottime->allocate_pool,
63 EFI_LOADER_DATA, *map_size, (void **)&m);
64 if (status != EFI_SUCCESS)
65 goto fail;
66
67 status = efi_call_phys5(sys_table->boottime->get_memory_map, map_size,
68 m, &key, desc_size, &desc_version);
69 if (status == EFI_BUFFER_TOO_SMALL) {
70 efi_call_phys1(sys_table->boottime->free_pool, m);
71 goto again;
72 }
73
74 if (status != EFI_SUCCESS)
75 efi_call_phys1(sys_table->boottime->free_pool, m);
76 22
77fail: 23#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
78 *map = m;
79 return status;
80}
81
82/*
83 * Allocate at the highest possible address that is not above 'max'.
84 */
85static efi_status_t high_alloc(unsigned long size, unsigned long align,
86 unsigned long *addr, unsigned long max)
87{
88 unsigned long map_size, desc_size;
89 efi_memory_desc_t *map;
90 efi_status_t status;
91 unsigned long nr_pages;
92 u64 max_addr = 0;
93 int i;
94
95 status = __get_map(&map, &map_size, &desc_size);
96 if (status != EFI_SUCCESS)
97 goto fail;
98
99 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
100again:
101 for (i = 0; i < map_size / desc_size; i++) {
102 efi_memory_desc_t *desc;
103 unsigned long m = (unsigned long)map;
104 u64 start, end;
105
106 desc = (efi_memory_desc_t *)(m + (i * desc_size));
107 if (desc->type != EFI_CONVENTIONAL_MEMORY)
108 continue;
109
110 if (desc->num_pages < nr_pages)
111 continue;
112 24
113 start = desc->phys_addr;
114 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
115 25
116 if ((start + size) > end || (start + size) > max)
117 continue;
118
119 if (end - size > max)
120 end = max;
121
122 if (round_down(end - size, align) < start)
123 continue;
124
125 start = round_down(end - size, align);
126
127 /*
128 * Don't allocate at 0x0. It will confuse code that
129 * checks pointers against NULL.
130 */
131 if (start == 0x0)
132 continue;
133
134 if (start > max_addr)
135 max_addr = start;
136 }
137
138 if (!max_addr)
139 status = EFI_NOT_FOUND;
140 else {
141 status = efi_call_phys4(sys_table->boottime->allocate_pages,
142 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
143 nr_pages, &max_addr);
144 if (status != EFI_SUCCESS) {
145 max = max_addr;
146 max_addr = 0;
147 goto again;
148 }
149
150 *addr = max_addr;
151 }
152
153free_pool:
154 efi_call_phys1(sys_table->boottime->free_pool, map);
155
156fail:
157 return status;
158}
159
160/*
161 * Allocate at the lowest possible address.
162 */
163static efi_status_t low_alloc(unsigned long size, unsigned long align,
164 unsigned long *addr)
165{
166 unsigned long map_size, desc_size;
167 efi_memory_desc_t *map;
168 efi_status_t status;
169 unsigned long nr_pages;
170 int i;
171
172 status = __get_map(&map, &map_size, &desc_size);
173 if (status != EFI_SUCCESS)
174 goto fail;
175
176 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
177 for (i = 0; i < map_size / desc_size; i++) {
178 efi_memory_desc_t *desc;
179 unsigned long m = (unsigned long)map;
180 u64 start, end;
181
182 desc = (efi_memory_desc_t *)(m + (i * desc_size));
183
184 if (desc->type != EFI_CONVENTIONAL_MEMORY)
185 continue;
186
187 if (desc->num_pages < nr_pages)
188 continue;
189
190 start = desc->phys_addr;
191 end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
192
193 /*
194 * Don't allocate at 0x0. It will confuse code that
195 * checks pointers against NULL. Skip the first 8
196 * bytes so we start at a nice even number.
197 */
198 if (start == 0x0)
199 start += 8;
200
201 start = round_up(start, align);
202 if ((start + size) > end)
203 continue;
204
205 status = efi_call_phys4(sys_table->boottime->allocate_pages,
206 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
207 nr_pages, &start);
208 if (status == EFI_SUCCESS) {
209 *addr = start;
210 break;
211 }
212 }
213
214 if (i == map_size / desc_size)
215 status = EFI_NOT_FOUND;
216
217free_pool:
218 efi_call_phys1(sys_table->boottime->free_pool, map);
219fail:
220 return status;
221}
222
223static void low_free(unsigned long size, unsigned long addr)
224{
225 unsigned long nr_pages;
226
227 nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
228 efi_call_phys2(sys_table->boottime->free_pages, addr, nr_pages);
229}
230 26
231static void find_bits(unsigned long mask, u8 *pos, u8 *size) 27static void find_bits(unsigned long mask, u8 *pos, u8 *size)
232{ 28{
@@ -624,242 +420,6 @@ void setup_graphics(struct boot_params *boot_params)
624 } 420 }
625} 421}
626 422
627struct initrd {
628 efi_file_handle_t *handle;
629 u64 size;
630};
631
632/*
633 * Check the cmdline for a LILO-style initrd= arguments.
634 *
635 * We only support loading an initrd from the same filesystem as the
636 * kernel image.
637 */
638static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
639 struct setup_header *hdr)
640{
641 struct initrd *initrds;
642 unsigned long initrd_addr;
643 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
644 u64 initrd_total;
645 efi_file_io_interface_t *io;
646 efi_file_handle_t *fh;
647 efi_status_t status;
648 int nr_initrds;
649 char *str;
650 int i, j, k;
651
652 initrd_addr = 0;
653 initrd_total = 0;
654
655 str = (char *)(unsigned long)hdr->cmd_line_ptr;
656
657 j = 0; /* See close_handles */
658
659 if (!str || !*str)
660 return EFI_SUCCESS;
661
662 for (nr_initrds = 0; *str; nr_initrds++) {
663 str = strstr(str, "initrd=");
664 if (!str)
665 break;
666
667 str += 7;
668
669 /* Skip any leading slashes */
670 while (*str == '/' || *str == '\\')
671 str++;
672
673 while (*str && *str != ' ' && *str != '\n')
674 str++;
675 }
676
677 if (!nr_initrds)
678 return EFI_SUCCESS;
679
680 status = efi_call_phys3(sys_table->boottime->allocate_pool,
681 EFI_LOADER_DATA,
682 nr_initrds * sizeof(*initrds),
683 &initrds);
684 if (status != EFI_SUCCESS) {
685 efi_printk("Failed to alloc mem for initrds\n");
686 goto fail;
687 }
688
689 str = (char *)(unsigned long)hdr->cmd_line_ptr;
690 for (i = 0; i < nr_initrds; i++) {
691 struct initrd *initrd;
692 efi_file_handle_t *h;
693 efi_file_info_t *info;
694 efi_char16_t filename_16[256];
695 unsigned long info_sz;
696 efi_guid_t info_guid = EFI_FILE_INFO_ID;
697 efi_char16_t *p;
698 u64 file_sz;
699
700 str = strstr(str, "initrd=");
701 if (!str)
702 break;
703
704 str += 7;
705
706 initrd = &initrds[i];
707 p = filename_16;
708
709 /* Skip any leading slashes */
710 while (*str == '/' || *str == '\\')
711 str++;
712
713 while (*str && *str != ' ' && *str != '\n') {
714 if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
715 break;
716
717 if (*str == '/') {
718 *p++ = '\\';
719 *str++;
720 } else {
721 *p++ = *str++;
722 }
723 }
724
725 *p = '\0';
726
727 /* Only open the volume once. */
728 if (!i) {
729 efi_boot_services_t *boottime;
730
731 boottime = sys_table->boottime;
732
733 status = efi_call_phys3(boottime->handle_protocol,
734 image->device_handle, &fs_proto, &io);
735 if (status != EFI_SUCCESS) {
736 efi_printk("Failed to handle fs_proto\n");
737 goto free_initrds;
738 }
739
740 status = efi_call_phys2(io->open_volume, io, &fh);
741 if (status != EFI_SUCCESS) {
742 efi_printk("Failed to open volume\n");
743 goto free_initrds;
744 }
745 }
746
747 status = efi_call_phys5(fh->open, fh, &h, filename_16,
748 EFI_FILE_MODE_READ, (u64)0);
749 if (status != EFI_SUCCESS) {
750 efi_printk("Failed to open initrd file: ");
751 efi_char16_printk(filename_16);
752 efi_printk("\n");
753 goto close_handles;
754 }
755
756 initrd->handle = h;
757
758 info_sz = 0;
759 status = efi_call_phys4(h->get_info, h, &info_guid,
760 &info_sz, NULL);
761 if (status != EFI_BUFFER_TOO_SMALL) {
762 efi_printk("Failed to get initrd info size\n");
763 goto close_handles;
764 }
765
766grow:
767 status = efi_call_phys3(sys_table->boottime->allocate_pool,
768 EFI_LOADER_DATA, info_sz, &info);
769 if (status != EFI_SUCCESS) {
770 efi_printk("Failed to alloc mem for initrd info\n");
771 goto close_handles;
772 }
773
774 status = efi_call_phys4(h->get_info, h, &info_guid,
775 &info_sz, info);
776 if (status == EFI_BUFFER_TOO_SMALL) {
777 efi_call_phys1(sys_table->boottime->free_pool, info);
778 goto grow;
779 }
780
781 file_sz = info->file_size;
782 efi_call_phys1(sys_table->boottime->free_pool, info);
783
784 if (status != EFI_SUCCESS) {
785 efi_printk("Failed to get initrd info\n");
786 goto close_handles;
787 }
788
789 initrd->size = file_sz;
790 initrd_total += file_sz;
791 }
792
793 if (initrd_total) {
794 unsigned long addr;
795
796 /*
797 * Multiple initrd's need to be at consecutive
798 * addresses in memory, so allocate enough memory for
799 * all the initrd's.
800 */
801 status = high_alloc(initrd_total, 0x1000,
802 &initrd_addr, hdr->initrd_addr_max);
803 if (status != EFI_SUCCESS) {
804 efi_printk("Failed to alloc highmem for initrds\n");
805 goto close_handles;
806 }
807
808 /* We've run out of free low memory. */
809 if (initrd_addr > hdr->initrd_addr_max) {
810 efi_printk("We've run out of free low memory\n");
811 status = EFI_INVALID_PARAMETER;
812 goto free_initrd_total;
813 }
814
815 addr = initrd_addr;
816 for (j = 0; j < nr_initrds; j++) {
817 u64 size;
818
819 size = initrds[j].size;
820 while (size) {
821 u64 chunksize;
822 if (size > EFI_READ_CHUNK_SIZE)
823 chunksize = EFI_READ_CHUNK_SIZE;
824 else
825 chunksize = size;
826 status = efi_call_phys3(fh->read,
827 initrds[j].handle,
828 &chunksize, addr);
829 if (status != EFI_SUCCESS) {
830 efi_printk("Failed to read initrd\n");
831 goto free_initrd_total;
832 }
833 addr += chunksize;
834 size -= chunksize;
835 }
836
837 efi_call_phys1(fh->close, initrds[j].handle);
838 }
839
840 }
841
842 efi_call_phys1(sys_table->boottime->free_pool, initrds);
843
844 hdr->ramdisk_image = initrd_addr;
845 hdr->ramdisk_size = initrd_total;
846
847 return status;
848
849free_initrd_total:
850 low_free(initrd_total, initrd_addr);
851
852close_handles:
853 for (k = j; k < i; k++)
854 efi_call_phys1(fh->close, initrds[k].handle);
855free_initrds:
856 efi_call_phys1(sys_table->boottime->free_pool, initrds);
857fail:
858 hdr->ramdisk_image = 0;
859 hdr->ramdisk_size = 0;
860
861 return status;
862}
863 423
864/* 424/*
865 * Because the x86 boot code expects to be passed a boot_params we 425 * Because the x86 boot code expects to be passed a boot_params we
@@ -875,14 +435,15 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
875 struct efi_info *efi; 435 struct efi_info *efi;
876 efi_loaded_image_t *image; 436 efi_loaded_image_t *image;
877 void *options; 437 void *options;
878 u32 load_options_size;
879 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; 438 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
880 int options_size = 0; 439 int options_size = 0;
881 efi_status_t status; 440 efi_status_t status;
882 unsigned long cmdline; 441 char *cmdline_ptr;
883 u16 *s2; 442 u16 *s2;
884 u8 *s1; 443 u8 *s1;
885 int i; 444 int i;
445 unsigned long ramdisk_addr;
446 unsigned long ramdisk_size;
886 447
887 sys_table = _table; 448 sys_table = _table;
888 449
@@ -893,13 +454,14 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
893 status = efi_call_phys3(sys_table->boottime->handle_protocol, 454 status = efi_call_phys3(sys_table->boottime->handle_protocol,
894 handle, &proto, (void *)&image); 455 handle, &proto, (void *)&image);
895 if (status != EFI_SUCCESS) { 456 if (status != EFI_SUCCESS) {
896 efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); 457 efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
897 return NULL; 458 return NULL;
898 } 459 }
899 460
900 status = low_alloc(0x4000, 1, (unsigned long *)&boot_params); 461 status = efi_low_alloc(sys_table, 0x4000, 1,
462 (unsigned long *)&boot_params);
901 if (status != EFI_SUCCESS) { 463 if (status != EFI_SUCCESS) {
902 efi_printk("Failed to alloc lowmem for boot params\n"); 464 efi_printk(sys_table, "Failed to alloc lowmem for boot params\n");
903 return NULL; 465 return NULL;
904 } 466 }
905 467
@@ -926,40 +488,11 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
926 hdr->type_of_loader = 0x21; 488 hdr->type_of_loader = 0x21;
927 489
928 /* Convert unicode cmdline to ascii */ 490 /* Convert unicode cmdline to ascii */
929 options = image->load_options; 491 cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image,
930 load_options_size = image->load_options_size / 2; /* ASCII */ 492 &options_size);
931 cmdline = 0; 493 if (!cmdline_ptr)
932 s2 = (u16 *)options; 494 goto fail;
933 495 hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
934 if (s2) {
935 while (*s2 && *s2 != '\n' && options_size < load_options_size) {
936 s2++;
937 options_size++;
938 }
939
940 if (options_size) {
941 if (options_size > hdr->cmdline_size)
942 options_size = hdr->cmdline_size;
943
944 options_size++; /* NUL termination */
945
946 status = low_alloc(options_size, 1, &cmdline);
947 if (status != EFI_SUCCESS) {
948 efi_printk("Failed to alloc mem for cmdline\n");
949 goto fail;
950 }
951
952 s1 = (u8 *)(unsigned long)cmdline;
953 s2 = (u16 *)options;
954
955 for (i = 0; i < options_size - 1; i++)
956 *s1++ = *s2++;
957
958 *s1 = '\0';
959 }
960 }
961
962 hdr->cmd_line_ptr = cmdline;
963 496
964 hdr->ramdisk_image = 0; 497 hdr->ramdisk_image = 0;
965 hdr->ramdisk_size = 0; 498 hdr->ramdisk_size = 0;
@@ -969,96 +502,64 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
969 502
970 memset(sdt, 0, sizeof(*sdt)); 503 memset(sdt, 0, sizeof(*sdt));
971 504
972 status = handle_ramdisks(image, hdr); 505 status = handle_cmdline_files(sys_table, image,
506 (char *)(unsigned long)hdr->cmd_line_ptr,
507 "initrd=", hdr->initrd_addr_max,
508 &ramdisk_addr, &ramdisk_size);
973 if (status != EFI_SUCCESS) 509 if (status != EFI_SUCCESS)
974 goto fail2; 510 goto fail2;
511 hdr->ramdisk_image = ramdisk_addr;
512 hdr->ramdisk_size = ramdisk_size;
975 513
976 return boot_params; 514 return boot_params;
977fail2: 515fail2:
978 if (options_size) 516 efi_free(sys_table, options_size, hdr->cmd_line_ptr);
979 low_free(options_size, hdr->cmd_line_ptr);
980fail: 517fail:
981 low_free(0x4000, (unsigned long)boot_params); 518 efi_free(sys_table, 0x4000, (unsigned long)boot_params);
982 return NULL; 519 return NULL;
983} 520}
984 521
985static efi_status_t exit_boot(struct boot_params *boot_params, 522static void add_e820ext(struct boot_params *params,
986 void *handle) 523 struct setup_data *e820ext, u32 nr_entries)
987{ 524{
988 struct efi_info *efi = &boot_params->efi_info; 525 struct setup_data *data;
989 struct e820entry *e820_map = &boot_params->e820_map[0];
990 struct e820entry *prev = NULL;
991 unsigned long size, key, desc_size, _size;
992 efi_memory_desc_t *mem_map;
993 efi_status_t status; 526 efi_status_t status;
994 __u32 desc_version; 527 unsigned long size;
995 bool called_exit = false;
996 u8 nr_entries;
997 int i;
998
999 size = sizeof(*mem_map) * 32;
1000
1001again:
1002 size += sizeof(*mem_map) * 2;
1003 _size = size;
1004 status = low_alloc(size, 1, (unsigned long *)&mem_map);
1005 if (status != EFI_SUCCESS)
1006 return status;
1007
1008get_map:
1009 status = efi_call_phys5(sys_table->boottime->get_memory_map, &size,
1010 mem_map, &key, &desc_size, &desc_version);
1011 if (status == EFI_BUFFER_TOO_SMALL) {
1012 low_free(_size, (unsigned long)mem_map);
1013 goto again;
1014 }
1015 528
1016 if (status != EFI_SUCCESS) 529 e820ext->type = SETUP_E820_EXT;
1017 goto free_mem_map; 530 e820ext->len = nr_entries * sizeof(struct e820entry);
531 e820ext->next = 0;
1018 532
1019 memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32)); 533 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
1020 efi->efi_systab = (unsigned long)sys_table;
1021 efi->efi_memdesc_size = desc_size;
1022 efi->efi_memdesc_version = desc_version;
1023 efi->efi_memmap = (unsigned long)mem_map;
1024 efi->efi_memmap_size = size;
1025
1026#ifdef CONFIG_X86_64
1027 efi->efi_systab_hi = (unsigned long)sys_table >> 32;
1028 efi->efi_memmap_hi = (unsigned long)mem_map >> 32;
1029#endif
1030 534
1031 /* Might as well exit boot services now */ 535 while (data && data->next)
1032 status = efi_call_phys2(sys_table->boottime->exit_boot_services, 536 data = (struct setup_data *)(unsigned long)data->next;
1033 handle, key);
1034 if (status != EFI_SUCCESS) {
1035 /*
1036 * ExitBootServices() will fail if any of the event
1037 * handlers change the memory map. In which case, we
1038 * must be prepared to retry, but only once so that
1039 * we're guaranteed to exit on repeated failures instead
1040 * of spinning forever.
1041 */
1042 if (called_exit)
1043 goto free_mem_map;
1044 537
1045 called_exit = true; 538 if (data)
1046 goto get_map; 539 data->next = (unsigned long)e820ext;
1047 } 540 else
541 params->hdr.setup_data = (unsigned long)e820ext;
542}
1048 543
1049 /* Historic? */ 544static efi_status_t setup_e820(struct boot_params *params,
1050 boot_params->alt_mem_k = 32 * 1024; 545 struct setup_data *e820ext, u32 e820ext_size)
546{
547 struct e820entry *e820_map = &params->e820_map[0];
548 struct efi_info *efi = &params->efi_info;
549 struct e820entry *prev = NULL;
550 u32 nr_entries;
551 u32 nr_desc;
552 int i;
1051 553
1052 /*
1053 * Convert the EFI memory map to E820.
1054 */
1055 nr_entries = 0; 554 nr_entries = 0;
1056 for (i = 0; i < size / desc_size; i++) { 555 nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
556
557 for (i = 0; i < nr_desc; i++) {
1057 efi_memory_desc_t *d; 558 efi_memory_desc_t *d;
1058 unsigned int e820_type = 0; 559 unsigned int e820_type = 0;
1059 unsigned long m = (unsigned long)mem_map; 560 unsigned long m = efi->efi_memmap;
1060 561
1061 d = (efi_memory_desc_t *)(m + (i * desc_size)); 562 d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
1062 switch (d->type) { 563 switch (d->type) {
1063 case EFI_RESERVED_TYPE: 564 case EFI_RESERVED_TYPE:
1064 case EFI_RUNTIME_SERVICES_CODE: 565 case EFI_RUNTIME_SERVICES_CODE:
@@ -1095,61 +596,151 @@ get_map:
1095 596
1096 /* Merge adjacent mappings */ 597 /* Merge adjacent mappings */
1097 if (prev && prev->type == e820_type && 598 if (prev && prev->type == e820_type &&
1098 (prev->addr + prev->size) == d->phys_addr) 599 (prev->addr + prev->size) == d->phys_addr) {
1099 prev->size += d->num_pages << 12; 600 prev->size += d->num_pages << 12;
1100 else { 601 continue;
1101 e820_map->addr = d->phys_addr; 602 }
1102 e820_map->size = d->num_pages << 12; 603
1103 e820_map->type = e820_type; 604 if (nr_entries == ARRAY_SIZE(params->e820_map)) {
1104 prev = e820_map++; 605 u32 need = (nr_desc - i) * sizeof(struct e820entry) +
1105 nr_entries++; 606 sizeof(struct setup_data);
607
608 if (!e820ext || e820ext_size < need)
609 return EFI_BUFFER_TOO_SMALL;
610
611 /* boot_params map full, switch to e820 extended */
612 e820_map = (struct e820entry *)e820ext->data;
1106 } 613 }
614
615 e820_map->addr = d->phys_addr;
616 e820_map->size = d->num_pages << PAGE_SHIFT;
617 e820_map->type = e820_type;
618 prev = e820_map++;
619 nr_entries++;
1107 } 620 }
1108 621
1109 boot_params->e820_entries = nr_entries; 622 if (nr_entries > ARRAY_SIZE(params->e820_map)) {
623 u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map);
624
625 add_e820ext(params, e820ext, nr_e820ext);
626 nr_entries -= nr_e820ext;
627 }
628
629 params->e820_entries = (u8)nr_entries;
1110 630
1111 return EFI_SUCCESS; 631 return EFI_SUCCESS;
632}
633
634static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
635 u32 *e820ext_size)
636{
637 efi_status_t status;
638 unsigned long size;
639
640 size = sizeof(struct setup_data) +
641 sizeof(struct e820entry) * nr_desc;
642
643 if (*e820ext) {
644 efi_call_phys1(sys_table->boottime->free_pool, *e820ext);
645 *e820ext = NULL;
646 *e820ext_size = 0;
647 }
648
649 status = efi_call_phys3(sys_table->boottime->allocate_pool,
650 EFI_LOADER_DATA, size, e820ext);
651
652 if (status == EFI_SUCCESS)
653 *e820ext_size = size;
1112 654
1113free_mem_map:
1114 low_free(_size, (unsigned long)mem_map);
1115 return status; 655 return status;
1116} 656}
1117 657
1118static efi_status_t relocate_kernel(struct setup_header *hdr) 658static efi_status_t exit_boot(struct boot_params *boot_params,
659 void *handle)
1119{ 660{
1120 unsigned long start, nr_pages; 661 struct efi_info *efi = &boot_params->efi_info;
662 unsigned long map_sz, key, desc_size;
663 efi_memory_desc_t *mem_map;
664 struct setup_data *e820ext;
665 __u32 e820ext_size;
666 __u32 nr_desc, prev_nr_desc;
1121 efi_status_t status; 667 efi_status_t status;
668 __u32 desc_version;
669 bool called_exit = false;
670 u8 nr_entries;
671 int i;
1122 672
1123 /* 673 nr_desc = 0;
1124 * The EFI firmware loader could have placed the kernel image 674 e820ext = NULL;
1125 * anywhere in memory, but the kernel has various restrictions 675 e820ext_size = 0;
1126 * on the max physical address it can run at. Attempt to move
1127 * the kernel to boot_params.pref_address, or as low as
1128 * possible.
1129 */
1130 start = hdr->pref_address;
1131 nr_pages = round_up(hdr->init_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
1132 676
1133 status = efi_call_phys4(sys_table->boottime->allocate_pages, 677get_map:
1134 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA, 678 status = efi_get_memory_map(sys_table, &mem_map, &map_sz, &desc_size,
1135 nr_pages, &start); 679 &desc_version, &key);
1136 if (status != EFI_SUCCESS) { 680
1137 status = low_alloc(hdr->init_size, hdr->kernel_alignment, 681 if (status != EFI_SUCCESS)
1138 &start); 682 return status;
683
684 prev_nr_desc = nr_desc;
685 nr_desc = map_sz / desc_size;
686 if (nr_desc > prev_nr_desc &&
687 nr_desc > ARRAY_SIZE(boot_params->e820_map)) {
688 u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params->e820_map);
689
690 status = alloc_e820ext(nr_e820ext, &e820ext, &e820ext_size);
1139 if (status != EFI_SUCCESS) 691 if (status != EFI_SUCCESS)
1140 efi_printk("Failed to alloc mem for kernel\n"); 692 goto free_mem_map;
693
694 efi_call_phys1(sys_table->boottime->free_pool, mem_map);
695 goto get_map; /* Allocated memory, get map again */
1141 } 696 }
1142 697
1143 if (status == EFI_SUCCESS) 698 memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
1144 memcpy((void *)start, (void *)(unsigned long)hdr->code32_start, 699 efi->efi_systab = (unsigned long)sys_table;
1145 hdr->init_size); 700 efi->efi_memdesc_size = desc_size;
701 efi->efi_memdesc_version = desc_version;
702 efi->efi_memmap = (unsigned long)mem_map;
703 efi->efi_memmap_size = map_sz;
704
705#ifdef CONFIG_X86_64
706 efi->efi_systab_hi = (unsigned long)sys_table >> 32;
707 efi->efi_memmap_hi = (unsigned long)mem_map >> 32;
708#endif
1146 709
1147 hdr->pref_address = hdr->code32_start; 710 /* Might as well exit boot services now */
1148 hdr->code32_start = (__u32)start; 711 status = efi_call_phys2(sys_table->boottime->exit_boot_services,
712 handle, key);
713 if (status != EFI_SUCCESS) {
714 /*
715 * ExitBootServices() will fail if any of the event
716 * handlers change the memory map. In which case, we
717 * must be prepared to retry, but only once so that
718 * we're guaranteed to exit on repeated failures instead
719 * of spinning forever.
720 */
721 if (called_exit)
722 goto free_mem_map;
1149 723
724 called_exit = true;
725 efi_call_phys1(sys_table->boottime->free_pool, mem_map);
726 goto get_map;
727 }
728
729 /* Historic? */
730 boot_params->alt_mem_k = 32 * 1024;
731
732 status = setup_e820(boot_params, e820ext, e820ext_size);
733 if (status != EFI_SUCCESS)
734 return status;
735
736 return EFI_SUCCESS;
737
738free_mem_map:
739 efi_call_phys1(sys_table->boottime->free_pool, mem_map);
1150 return status; 740 return status;
1151} 741}
1152 742
743
1153/* 744/*
1154 * On success we return a pointer to a boot_params structure, and NULL 745 * On success we return a pointer to a boot_params structure, and NULL
1155 * on failure. 746 * on failure.
@@ -1157,7 +748,7 @@ static efi_status_t relocate_kernel(struct setup_header *hdr)
1157struct boot_params *efi_main(void *handle, efi_system_table_t *_table, 748struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
1158 struct boot_params *boot_params) 749 struct boot_params *boot_params)
1159{ 750{
1160 struct desc_ptr *gdt, *idt; 751 struct desc_ptr *gdt;
1161 efi_loaded_image_t *image; 752 efi_loaded_image_t *image;
1162 struct setup_header *hdr = &boot_params->hdr; 753 struct setup_header *hdr = &boot_params->hdr;
1163 efi_status_t status; 754 efi_status_t status;
@@ -1177,37 +768,33 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
1177 EFI_LOADER_DATA, sizeof(*gdt), 768 EFI_LOADER_DATA, sizeof(*gdt),
1178 (void **)&gdt); 769 (void **)&gdt);
1179 if (status != EFI_SUCCESS) { 770 if (status != EFI_SUCCESS) {
1180 efi_printk("Failed to alloc mem for gdt structure\n"); 771 efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
1181 goto fail; 772 goto fail;
1182 } 773 }
1183 774
1184 gdt->size = 0x800; 775 gdt->size = 0x800;
1185 status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address); 776 status = efi_low_alloc(sys_table, gdt->size, 8,
1186 if (status != EFI_SUCCESS) { 777 (unsigned long *)&gdt->address);
1187 efi_printk("Failed to alloc mem for gdt\n");
1188 goto fail;
1189 }
1190
1191 status = efi_call_phys3(sys_table->boottime->allocate_pool,
1192 EFI_LOADER_DATA, sizeof(*idt),
1193 (void **)&idt);
1194 if (status != EFI_SUCCESS) { 778 if (status != EFI_SUCCESS) {
1195 efi_printk("Failed to alloc mem for idt structure\n"); 779 efi_printk(sys_table, "Failed to alloc mem for gdt\n");
1196 goto fail; 780 goto fail;
1197 } 781 }
1198 782
1199 idt->size = 0;
1200 idt->address = 0;
1201
1202 /* 783 /*
1203 * If the kernel isn't already loaded at the preferred load 784 * If the kernel isn't already loaded at the preferred load
1204 * address, relocate it. 785 * address, relocate it.
1205 */ 786 */
1206 if (hdr->pref_address != hdr->code32_start) { 787 if (hdr->pref_address != hdr->code32_start) {
1207 status = relocate_kernel(hdr); 788 unsigned long bzimage_addr = hdr->code32_start;
1208 789 status = efi_relocate_kernel(sys_table, &bzimage_addr,
790 hdr->init_size, hdr->init_size,
791 hdr->pref_address,
792 hdr->kernel_alignment);
1209 if (status != EFI_SUCCESS) 793 if (status != EFI_SUCCESS)
1210 goto fail; 794 goto fail;
795
796 hdr->pref_address = hdr->code32_start;
797 hdr->code32_start = bzimage_addr;
1211 } 798 }
1212 799
1213 status = exit_boot(boot_params, handle); 800 status = exit_boot(boot_params, handle);
@@ -1267,10 +854,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
1267 desc->base2 = 0x00; 854 desc->base2 = 0x00;
1268#endif /* CONFIG_X86_64 */ 855#endif /* CONFIG_X86_64 */
1269 856
1270 asm volatile ("lidt %0" : : "m" (*idt));
1271 asm volatile ("lgdt %0" : : "m" (*gdt));
1272
1273 asm volatile("cli"); 857 asm volatile("cli");
858 asm volatile ("lgdt %0" : : "m" (*gdt));
1274 859
1275 return boot_params; 860 return boot_params;
1276fail: 861fail:
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h
index e5b0a8f91c5f..81b6b652b46a 100644
--- a/arch/x86/boot/compressed/eboot.h
+++ b/arch/x86/boot/compressed/eboot.h
@@ -11,9 +11,6 @@
11 11
12#define DESC_TYPE_CODE_DATA (1 << 0) 12#define DESC_TYPE_CODE_DATA (1 << 0)
13 13
14#define EFI_PAGE_SIZE (1UL << EFI_PAGE_SHIFT)
15#define EFI_READ_CHUNK_SIZE (1024 * 1024)
16
17#define EFI_CONSOLE_OUT_DEVICE_GUID \ 14#define EFI_CONSOLE_OUT_DEVICE_GUID \
18 EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \ 15 EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x0, 0x90, 0x27, \
19 0x3f, 0xc1, 0x4d) 16 0x3f, 0xc1, 0x4d)
@@ -62,10 +59,4 @@ struct efi_uga_draw_protocol {
62 void *blt; 59 void *blt;
63}; 60};
64 61
65struct efi_simple_text_output_protocol {
66 void *reset;
67 void *output_string;
68 void *test_string;
69};
70
71#endif /* BOOT_COMPRESSED_EBOOT_H */ 62#endif /* BOOT_COMPRESSED_EBOOT_H */