x86: EFI stub support for large memory maps
[linux-2.6-block.git] / arch / x86 / boot / compressed / eboot.c
CommitLineData
291f3632
MF
1/* -----------------------------------------------------------------------
2 *
3 * Copyright 2011 Intel Corporation; author Matt Fleming
4 *
5 * This file is part of the Linux kernel, and is made available under
6 * the terms of the GNU General Public License version 2.
7 *
8 * ----------------------------------------------------------------------- */
9
10#include <linux/efi.h>
dd5fc854 11#include <linux/pci.h>
291f3632
MF
12#include <asm/efi.h>
13#include <asm/setup.h>
14#include <asm/desc.h>
15
0f905a43
MF
16#undef memcpy /* Use memcpy from misc.c */
17
291f3632
MF
18#include "eboot.h"
19
20static efi_system_table_t *sys_table;
21
291f3632 22
7721da4c 23#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
291f3632 24
291f3632 25
291f3632
MF
26
27static void find_bits(unsigned long mask, u8 *pos, u8 *size)
28{
29 u8 first, len;
30
31 first = 0;
32 len = 0;
33
34 if (mask) {
35 while (!(mask & 0x1)) {
36 mask = mask >> 1;
37 first++;
38 }
39
40 while (mask & 0x1) {
41 mask = mask >> 1;
42 len++;
43 }
44 }
45
46 *pos = first;
47 *size = len;
48}
49
dd5fc854
MG
50static efi_status_t setup_efi_pci(struct boot_params *params)
51{
52 efi_pci_io_protocol *pci;
53 efi_status_t status;
54 void **pci_handle;
55 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
56 unsigned long nr_pci, size = 0;
57 int i;
58 struct setup_data *data;
59
bc754790 60 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
dd5fc854
MG
61
62 while (data && data->next)
bc754790 63 data = (struct setup_data *)(unsigned long)data->next;
dd5fc854
MG
64
65 status = efi_call_phys5(sys_table->boottime->locate_handle,
66 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
67 NULL, &size, pci_handle);
68
69 if (status == EFI_BUFFER_TOO_SMALL) {
70 status = efi_call_phys3(sys_table->boottime->allocate_pool,
71 EFI_LOADER_DATA, size, &pci_handle);
72
73 if (status != EFI_SUCCESS)
74 return status;
75
76 status = efi_call_phys5(sys_table->boottime->locate_handle,
77 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
78 NULL, &size, pci_handle);
79 }
80
81 if (status != EFI_SUCCESS)
82 goto free_handle;
83
84 nr_pci = size / sizeof(void *);
85 for (i = 0; i < nr_pci; i++) {
86 void *h = pci_handle[i];
87 uint64_t attributes;
88 struct pci_setup_rom *rom;
89
90 status = efi_call_phys3(sys_table->boottime->handle_protocol,
91 h, &pci_proto, &pci);
92
93 if (status != EFI_SUCCESS)
94 continue;
95
96 if (!pci)
97 continue;
98
b607e212 99#ifdef CONFIG_X86_64
dd5fc854
MG
100 status = efi_call_phys4(pci->attributes, pci,
101 EfiPciIoAttributeOperationGet, 0,
102 &attributes);
b607e212
DW
103#else
104 status = efi_call_phys5(pci->attributes, pci,
105 EfiPciIoAttributeOperationGet, 0, 0,
106 &attributes);
107#endif
dd5fc854
MG
108 if (status != EFI_SUCCESS)
109 continue;
110
dd5fc854
MG
111 if (!pci->romimage || !pci->romsize)
112 continue;
113
114 size = pci->romsize + sizeof(*rom);
115
116 status = efi_call_phys3(sys_table->boottime->allocate_pool,
117 EFI_LOADER_DATA, size, &rom);
118
119 if (status != EFI_SUCCESS)
120 continue;
121
122 rom->data.type = SETUP_PCI;
123 rom->data.len = size - sizeof(struct setup_data);
124 rom->data.next = 0;
125 rom->pcilen = pci->romsize;
126
127 status = efi_call_phys5(pci->pci.read, pci,
128 EfiPciIoWidthUint16, PCI_VENDOR_ID,
129 1, &(rom->vendor));
130
131 if (status != EFI_SUCCESS)
132 goto free_struct;
133
134 status = efi_call_phys5(pci->pci.read, pci,
135 EfiPciIoWidthUint16, PCI_DEVICE_ID,
136 1, &(rom->devid));
137
138 if (status != EFI_SUCCESS)
139 goto free_struct;
140
141 status = efi_call_phys5(pci->get_location, pci,
142 &(rom->segment), &(rom->bus),
143 &(rom->device), &(rom->function));
144
145 if (status != EFI_SUCCESS)
146 goto free_struct;
147
148 memcpy(rom->romdata, pci->romimage, pci->romsize);
149
150 if (data)
bc754790 151 data->next = (unsigned long)rom;
dd5fc854 152 else
bc754790 153 params->hdr.setup_data = (unsigned long)rom;
dd5fc854
MG
154
155 data = (struct setup_data *)rom;
156
157 continue;
158 free_struct:
159 efi_call_phys1(sys_table->boottime->free_pool, rom);
160 }
161
162free_handle:
163 efi_call_phys1(sys_table->boottime->free_pool, pci_handle);
164 return status;
165}
166
291f3632
MF
167/*
168 * See if we have Graphics Output Protocol
169 */
170static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
171 unsigned long size)
172{
173 struct efi_graphics_output_protocol *gop, *first_gop;
174 struct efi_pixel_bitmask pixel_info;
175 unsigned long nr_gops;
176 efi_status_t status;
177 void **gop_handle;
178 u16 width, height;
179 u32 fb_base, fb_size;
180 u32 pixels_per_scan_line;
181 int pixel_format;
182 int i;
183
184 status = efi_call_phys3(sys_table->boottime->allocate_pool,
185 EFI_LOADER_DATA, size, &gop_handle);
186 if (status != EFI_SUCCESS)
187 return status;
188
189 status = efi_call_phys5(sys_table->boottime->locate_handle,
190 EFI_LOCATE_BY_PROTOCOL, proto,
191 NULL, &size, gop_handle);
192 if (status != EFI_SUCCESS)
193 goto free_handle;
194
195 first_gop = NULL;
196
197 nr_gops = size / sizeof(void *);
198 for (i = 0; i < nr_gops; i++) {
199 struct efi_graphics_output_mode_info *info;
38cb5ef4
MG
200 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
201 bool conout_found = false;
202 void *dummy;
291f3632
MF
203 void *h = gop_handle[i];
204
205 status = efi_call_phys3(sys_table->boottime->handle_protocol,
206 h, proto, &gop);
207 if (status != EFI_SUCCESS)
208 continue;
209
38cb5ef4
MG
210 status = efi_call_phys3(sys_table->boottime->handle_protocol,
211 h, &conout_proto, &dummy);
212
213 if (status == EFI_SUCCESS)
214 conout_found = true;
291f3632
MF
215
216 status = efi_call_phys4(gop->query_mode, gop,
217 gop->mode->mode, &size, &info);
38cb5ef4 218 if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
291f3632 219 /*
38cb5ef4
MG
220 * Systems that use the UEFI Console Splitter may
221 * provide multiple GOP devices, not all of which are
222 * backed by real hardware. The workaround is to search
223 * for a GOP implementing the ConOut protocol, and if
224 * one isn't found, to just fall back to the first GOP.
291f3632
MF
225 */
226 width = info->horizontal_resolution;
227 height = info->vertical_resolution;
228 fb_base = gop->mode->frame_buffer_base;
229 fb_size = gop->mode->frame_buffer_size;
230 pixel_format = info->pixel_format;
231 pixel_info = info->pixel_information;
232 pixels_per_scan_line = info->pixels_per_scan_line;
233
234 /*
38cb5ef4 235 * Once we've found a GOP supporting ConOut,
291f3632
MF
236 * don't bother looking any further.
237 */
70a479cb 238 first_gop = gop;
38cb5ef4 239 if (conout_found)
291f3632 240 break;
291f3632
MF
241 }
242 }
243
244 /* Did we find any GOPs? */
245 if (!first_gop)
246 goto free_handle;
247
248 /* EFI framebuffer */
249 si->orig_video_isVGA = VIDEO_TYPE_EFI;
250
251 si->lfb_width = width;
252 si->lfb_height = height;
253 si->lfb_base = fb_base;
291f3632
MF
254 si->pages = 1;
255
256 if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
257 si->lfb_depth = 32;
258 si->lfb_linelength = pixels_per_scan_line * 4;
259 si->red_size = 8;
260 si->red_pos = 0;
261 si->green_size = 8;
262 si->green_pos = 8;
263 si->blue_size = 8;
264 si->blue_pos = 16;
265 si->rsvd_size = 8;
266 si->rsvd_pos = 24;
267 } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) {
268 si->lfb_depth = 32;
269 si->lfb_linelength = pixels_per_scan_line * 4;
270 si->red_size = 8;
271 si->red_pos = 16;
272 si->green_size = 8;
273 si->green_pos = 8;
274 si->blue_size = 8;
275 si->blue_pos = 0;
276 si->rsvd_size = 8;
277 si->rsvd_pos = 24;
278 } else if (pixel_format == PIXEL_BIT_MASK) {
279 find_bits(pixel_info.red_mask, &si->red_pos, &si->red_size);
280 find_bits(pixel_info.green_mask, &si->green_pos,
281 &si->green_size);
282 find_bits(pixel_info.blue_mask, &si->blue_pos, &si->blue_size);
283 find_bits(pixel_info.reserved_mask, &si->rsvd_pos,
284 &si->rsvd_size);
285 si->lfb_depth = si->red_size + si->green_size +
286 si->blue_size + si->rsvd_size;
287 si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8;
288 } else {
289 si->lfb_depth = 4;
290 si->lfb_linelength = si->lfb_width / 2;
291 si->red_size = 0;
292 si->red_pos = 0;
293 si->green_size = 0;
294 si->green_pos = 0;
295 si->blue_size = 0;
296 si->blue_pos = 0;
297 si->rsvd_size = 0;
298 si->rsvd_pos = 0;
299 }
300
e9b10953
MG
301 si->lfb_size = si->lfb_linelength * si->lfb_height;
302
f462ed93
MG
303 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
304
291f3632
MF
305free_handle:
306 efi_call_phys1(sys_table->boottime->free_pool, gop_handle);
307 return status;
308}
309
310/*
311 * See if we have Universal Graphics Adapter (UGA) protocol
312 */
313static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
314 unsigned long size)
315{
316 struct efi_uga_draw_protocol *uga, *first_uga;
317 unsigned long nr_ugas;
318 efi_status_t status;
319 u32 width, height;
320 void **uga_handle = NULL;
321 int i;
322
323 status = efi_call_phys3(sys_table->boottime->allocate_pool,
324 EFI_LOADER_DATA, size, &uga_handle);
325 if (status != EFI_SUCCESS)
326 return status;
327
328 status = efi_call_phys5(sys_table->boottime->locate_handle,
329 EFI_LOCATE_BY_PROTOCOL, uga_proto,
330 NULL, &size, uga_handle);
331 if (status != EFI_SUCCESS)
332 goto free_handle;
333
334 first_uga = NULL;
335
336 nr_ugas = size / sizeof(void *);
337 for (i = 0; i < nr_ugas; i++) {
338 efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
339 void *handle = uga_handle[i];
340 u32 w, h, depth, refresh;
341 void *pciio;
342
343 status = efi_call_phys3(sys_table->boottime->handle_protocol,
344 handle, uga_proto, &uga);
345 if (status != EFI_SUCCESS)
346 continue;
347
348 efi_call_phys3(sys_table->boottime->handle_protocol,
349 handle, &pciio_proto, &pciio);
350
351 status = efi_call_phys5(uga->get_mode, uga, &w, &h,
352 &depth, &refresh);
353 if (status == EFI_SUCCESS && (!first_uga || pciio)) {
354 width = w;
355 height = h;
356
357 /*
358 * Once we've found a UGA supporting PCIIO,
359 * don't bother looking any further.
360 */
361 if (pciio)
362 break;
363
364 first_uga = uga;
365 }
366 }
367
368 if (!first_uga)
369 goto free_handle;
370
371 /* EFI framebuffer */
372 si->orig_video_isVGA = VIDEO_TYPE_EFI;
373
374 si->lfb_depth = 32;
375 si->lfb_width = width;
376 si->lfb_height = height;
377
378 si->red_size = 8;
379 si->red_pos = 16;
380 si->green_size = 8;
381 si->green_pos = 8;
382 si->blue_size = 8;
383 si->blue_pos = 0;
384 si->rsvd_size = 8;
385 si->rsvd_pos = 24;
386
387
388free_handle:
389 efi_call_phys1(sys_table->boottime->free_pool, uga_handle);
390 return status;
391}
392
393void setup_graphics(struct boot_params *boot_params)
394{
395 efi_guid_t graphics_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
396 struct screen_info *si;
397 efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
398 efi_status_t status;
399 unsigned long size;
400 void **gop_handle = NULL;
401 void **uga_handle = NULL;
402
403 si = &boot_params->screen_info;
404 memset(si, 0, sizeof(*si));
405
406 size = 0;
407 status = efi_call_phys5(sys_table->boottime->locate_handle,
408 EFI_LOCATE_BY_PROTOCOL, &graphics_proto,
409 NULL, &size, gop_handle);
410 if (status == EFI_BUFFER_TOO_SMALL)
411 status = setup_gop(si, &graphics_proto, size);
412
413 if (status != EFI_SUCCESS) {
414 size = 0;
415 status = efi_call_phys5(sys_table->boottime->locate_handle,
416 EFI_LOCATE_BY_PROTOCOL, &uga_proto,
417 NULL, &size, uga_handle);
418 if (status == EFI_BUFFER_TOO_SMALL)
419 setup_uga(si, &uga_proto, size);
420 }
421}
422
291f3632
MF
423
424/*
425 * Because the x86 boot code expects to be passed a boot_params we
426 * need to create one ourselves (usually the bootloader would create
427 * one for us).
428 */
9ca8f72a 429struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table)
291f3632 430{
9ca8f72a
MF
431 struct boot_params *boot_params;
432 struct sys_desc_table *sdt;
433 struct apm_bios_info *bi;
434 struct setup_header *hdr;
435 struct efi_info *efi;
436 efi_loaded_image_t *image;
437 void *options;
9ca8f72a 438 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
291f3632
MF
439 int options_size = 0;
440 efi_status_t status;
5fef3870 441 char *cmdline_ptr;
291f3632
MF
442 u16 *s2;
443 u8 *s1;
444 int i;
46f4582e
RF
445 unsigned long ramdisk_addr;
446 unsigned long ramdisk_size;
291f3632 447
9ca8f72a
MF
448 sys_table = _table;
449
450 /* Check if we were booted by the EFI firmware */
451 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
452 return NULL;
453
454 status = efi_call_phys3(sys_table->boottime->handle_protocol,
455 handle, &proto, (void *)&image);
456 if (status != EFI_SUCCESS) {
876dc36a 457 efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
9ca8f72a
MF
458 return NULL;
459 }
460
40e4530a
RF
461 status = efi_low_alloc(sys_table, 0x4000, 1,
462 (unsigned long *)&boot_params);
9ca8f72a 463 if (status != EFI_SUCCESS) {
876dc36a 464 efi_printk(sys_table, "Failed to alloc lowmem for boot params\n");
9ca8f72a
MF
465 return NULL;
466 }
467
468 memset(boot_params, 0x0, 0x4000);
469
470 hdr = &boot_params->hdr;
471 efi = &boot_params->efi_info;
472 bi = &boot_params->apm_bios_info;
473 sdt = &boot_params->sys_desc_table;
474
475 /* Copy the second sector to boot_params */
476 memcpy(&hdr->jump, image->image_base + 512, 512);
477
478 /*
479 * Fill out some of the header fields ourselves because the
480 * EFI firmware loader doesn't load the first sector.
481 */
482 hdr->root_flags = 1;
483 hdr->vid_mode = 0xffff;
484 hdr->boot_flag = 0xAA55;
485
486 hdr->code32_start = (__u64)(unsigned long)image->image_base;
487
291f3632
MF
488 hdr->type_of_loader = 0x21;
489
490 /* Convert unicode cmdline to ascii */
5fef3870
RF
491 cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image,
492 &options_size);
493 if (!cmdline_ptr)
494 goto fail;
495 hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
291f3632
MF
496
497 hdr->ramdisk_image = 0;
498 hdr->ramdisk_size = 0;
499
291f3632
MF
500 /* Clear APM BIOS info */
501 memset(bi, 0, sizeof(*bi));
502
503 memset(sdt, 0, sizeof(*sdt));
504
46f4582e
RF
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);
9ca8f72a
MF
509 if (status != EFI_SUCCESS)
510 goto fail2;
46f4582e
RF
511 hdr->ramdisk_image = ramdisk_addr;
512 hdr->ramdisk_size = ramdisk_size;
9ca8f72a
MF
513
514 return boot_params;
515fail2:
0e1cadb0 516 efi_free(sys_table, options_size, hdr->cmd_line_ptr);
9ca8f72a 517fail:
40e4530a 518 efi_free(sys_table, 0x4000, (unsigned long)boot_params);
9ca8f72a
MF
519 return NULL;
520}
521
d2078d5a
LC
522static void add_e820ext(struct boot_params *params,
523 struct setup_data *e820ext, u32 nr_entries)
9ca8f72a 524{
d2078d5a 525 struct setup_data *data;
9ca8f72a 526 efi_status_t status;
d2078d5a 527 unsigned long size;
291f3632 528
d2078d5a
LC
529 e820ext->type = SETUP_E820_EXT;
530 e820ext->len = nr_entries * sizeof(struct e820entry);
531 e820ext->next = 0;
291f3632 532
d2078d5a 533 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
291f3632 534
d2078d5a
LC
535 while (data && data->next)
536 data = (struct setup_data *)(unsigned long)data->next;
d3768d88 537
d2078d5a
LC
538 if (data)
539 data->next = (unsigned long)e820ext;
540 else
541 params->hdr.setup_data = (unsigned long)e820ext;
542}
291f3632 543
d2078d5a
LC
544static efi_status_t setup_e820(struct boot_params *params,
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;
291f3632 553
291f3632 554 nr_entries = 0;
d2078d5a
LC
555 nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
556
557 for (i = 0; i < nr_desc; i++) {
291f3632
MF
558 efi_memory_desc_t *d;
559 unsigned int e820_type = 0;
d2078d5a 560 unsigned long m = efi->efi_memmap;
291f3632 561
d2078d5a 562 d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
291f3632
MF
563 switch (d->type) {
564 case EFI_RESERVED_TYPE:
565 case EFI_RUNTIME_SERVICES_CODE:
566 case EFI_RUNTIME_SERVICES_DATA:
567 case EFI_MEMORY_MAPPED_IO:
568 case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
569 case EFI_PAL_CODE:
570 e820_type = E820_RESERVED;
571 break;
572
573 case EFI_UNUSABLE_MEMORY:
574 e820_type = E820_UNUSABLE;
575 break;
576
577 case EFI_ACPI_RECLAIM_MEMORY:
578 e820_type = E820_ACPI;
579 break;
580
581 case EFI_LOADER_CODE:
582 case EFI_LOADER_DATA:
583 case EFI_BOOT_SERVICES_CODE:
584 case EFI_BOOT_SERVICES_DATA:
585 case EFI_CONVENTIONAL_MEMORY:
586 e820_type = E820_RAM;
587 break;
588
589 case EFI_ACPI_MEMORY_NVS:
590 e820_type = E820_NVS;
591 break;
592
593 default:
594 continue;
595 }
596
597 /* Merge adjacent mappings */
598 if (prev && prev->type == e820_type &&
d2078d5a 599 (prev->addr + prev->size) == d->phys_addr) {
291f3632 600 prev->size += d->num_pages << 12;
d2078d5a 601 continue;
291f3632 602 }
d2078d5a
LC
603
604 if (nr_entries == ARRAY_SIZE(params->e820_map)) {
605 u32 need = (nr_desc - i) * sizeof(struct e820entry) +
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;
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++;
291f3632
MF
620 }
621
d2078d5a
LC
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;
630
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;
654
655 return status;
656}
657
658static efi_status_t exit_boot(struct boot_params *boot_params,
659 void *handle)
660{
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;
667 efi_status_t status;
668 __u32 desc_version;
669 bool called_exit = false;
670 u8 nr_entries;
671 int i;
672
673 nr_desc = 0;
674 e820ext = NULL;
675 e820ext_size = 0;
676
677get_map:
678 status = efi_get_memory_map(sys_table, &mem_map, &map_sz, &desc_size,
679 &desc_version, &key);
680
681 if (status != EFI_SUCCESS)
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);
691 if (status != EFI_SUCCESS)
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 */
696 }
697
698 memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
699 efi->efi_systab = (unsigned long)sys_table;
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
709
710 /* Might as well exit boot services now */
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;
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;
291f3632
MF
735
736 return EFI_SUCCESS;
737
738free_mem_map:
ae8e9060 739 efi_call_phys1(sys_table->boottime->free_pool, mem_map);
291f3632
MF
740 return status;
741}
742
9ca8f72a
MF
743
744/*
745 * On success we return a pointer to a boot_params structure, and NULL
746 * on failure.
747 */
748struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
749 struct boot_params *boot_params)
750{
751 struct desc_ptr *gdt, *idt;
752 efi_loaded_image_t *image;
753 struct setup_header *hdr = &boot_params->hdr;
754 efi_status_t status;
755 struct desc_struct *desc;
756
757 sys_table = _table;
758
759 /* Check if we were booted by the EFI firmware */
760 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
761 goto fail;
762
763 setup_graphics(boot_params);
291f3632 764
dd5fc854
MG
765 setup_efi_pci(boot_params);
766
291f3632
MF
767 status = efi_call_phys3(sys_table->boottime->allocate_pool,
768 EFI_LOADER_DATA, sizeof(*gdt),
769 (void **)&gdt);
9fa7deda 770 if (status != EFI_SUCCESS) {
876dc36a 771 efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
291f3632 772 goto fail;
9fa7deda 773 }
291f3632
MF
774
775 gdt->size = 0x800;
40e4530a 776 status = efi_low_alloc(sys_table, gdt->size, 8,
876dc36a 777 (unsigned long *)&gdt->address);
9fa7deda 778 if (status != EFI_SUCCESS) {
876dc36a 779 efi_printk(sys_table, "Failed to alloc mem for gdt\n");
291f3632 780 goto fail;
9fa7deda 781 }
291f3632
MF
782
783 status = efi_call_phys3(sys_table->boottime->allocate_pool,
784 EFI_LOADER_DATA, sizeof(*idt),
785 (void **)&idt);
9fa7deda 786 if (status != EFI_SUCCESS) {
876dc36a 787 efi_printk(sys_table, "Failed to alloc mem for idt structure\n");
291f3632 788 goto fail;
9fa7deda 789 }
291f3632
MF
790
791 idt->size = 0;
792 idt->address = 0;
793
9ca8f72a
MF
794 /*
795 * If the kernel isn't already loaded at the preferred load
796 * address, relocate it.
797 */
798 if (hdr->pref_address != hdr->code32_start) {
4a9f3a7c
RF
799 unsigned long bzimage_addr = hdr->code32_start;
800 status = efi_relocate_kernel(sys_table, &bzimage_addr,
801 hdr->init_size, hdr->init_size,
802 hdr->pref_address,
803 hdr->kernel_alignment);
9ca8f72a
MF
804 if (status != EFI_SUCCESS)
805 goto fail;
4a9f3a7c
RF
806
807 hdr->pref_address = hdr->code32_start;
808 hdr->code32_start = bzimage_addr;
9ca8f72a
MF
809 }
810
811 status = exit_boot(boot_params, handle);
291f3632
MF
812 if (status != EFI_SUCCESS)
813 goto fail;
814
815 memset((char *)gdt->address, 0x0, gdt->size);
816 desc = (struct desc_struct *)gdt->address;
817
818 /* The first GDT is a dummy and the second is unused. */
819 desc += 2;
820
821 desc->limit0 = 0xffff;
822 desc->base0 = 0x0000;
823 desc->base1 = 0x0000;
824 desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
825 desc->s = DESC_TYPE_CODE_DATA;
826 desc->dpl = 0;
827 desc->p = 1;
828 desc->limit = 0xf;
829 desc->avl = 0;
830 desc->l = 0;
831 desc->d = SEG_OP_SIZE_32BIT;
832 desc->g = SEG_GRANULARITY_4KB;
833 desc->base2 = 0x00;
834
835 desc++;
836 desc->limit0 = 0xffff;
837 desc->base0 = 0x0000;
838 desc->base1 = 0x0000;
839 desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
840 desc->s = DESC_TYPE_CODE_DATA;
841 desc->dpl = 0;
842 desc->p = 1;
843 desc->limit = 0xf;
844 desc->avl = 0;
845 desc->l = 0;
846 desc->d = SEG_OP_SIZE_32BIT;
847 desc->g = SEG_GRANULARITY_4KB;
848 desc->base2 = 0x00;
849
850#ifdef CONFIG_X86_64
851 /* Task segment value */
852 desc++;
853 desc->limit0 = 0x0000;
854 desc->base0 = 0x0000;
855 desc->base1 = 0x0000;
856 desc->type = SEG_TYPE_TSS;
857 desc->s = 0;
858 desc->dpl = 0;
859 desc->p = 1;
860 desc->limit = 0x0;
861 desc->avl = 0;
862 desc->l = 0;
863 desc->d = 0;
864 desc->g = SEG_GRANULARITY_4KB;
865 desc->base2 = 0x00;
866#endif /* CONFIG_X86_64 */
867
868 asm volatile ("lidt %0" : : "m" (*idt));
869 asm volatile ("lgdt %0" : : "m" (*gdt));
870
871 asm volatile("cli");
872
873 return boot_params;
874fail:
875 return NULL;
876}