efi: Move common EFI stub code from x86 arch code to common location
[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;
438 u32 load_options_size;
439 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
291f3632
MF
440 int options_size = 0;
441 efi_status_t status;
291f3632 442 unsigned long cmdline;
291f3632
MF
443 u16 *s2;
444 u8 *s1;
445 int i;
446
9ca8f72a
MF
447 sys_table = _table;
448
449 /* Check if we were booted by the EFI firmware */
450 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
451 return NULL;
452
453 status = efi_call_phys3(sys_table->boottime->handle_protocol,
454 handle, &proto, (void *)&image);
455 if (status != EFI_SUCCESS) {
456 efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
457 return NULL;
458 }
459
460 status = low_alloc(0x4000, 1, (unsigned long *)&boot_params);
461 if (status != EFI_SUCCESS) {
462 efi_printk("Failed to alloc lowmem for boot params\n");
463 return NULL;
464 }
465
466 memset(boot_params, 0x0, 0x4000);
467
468 hdr = &boot_params->hdr;
469 efi = &boot_params->efi_info;
470 bi = &boot_params->apm_bios_info;
471 sdt = &boot_params->sys_desc_table;
472
473 /* Copy the second sector to boot_params */
474 memcpy(&hdr->jump, image->image_base + 512, 512);
475
476 /*
477 * Fill out some of the header fields ourselves because the
478 * EFI firmware loader doesn't load the first sector.
479 */
480 hdr->root_flags = 1;
481 hdr->vid_mode = 0xffff;
482 hdr->boot_flag = 0xAA55;
483
484 hdr->code32_start = (__u64)(unsigned long)image->image_base;
485
291f3632
MF
486 hdr->type_of_loader = 0x21;
487
488 /* Convert unicode cmdline to ascii */
9ca8f72a
MF
489 options = image->load_options;
490 load_options_size = image->load_options_size / 2; /* ASCII */
291f3632
MF
491 cmdline = 0;
492 s2 = (u16 *)options;
493
494 if (s2) {
495 while (*s2 && *s2 != '\n' && options_size < load_options_size) {
496 s2++;
497 options_size++;
498 }
499
500 if (options_size) {
501 if (options_size > hdr->cmdline_size)
502 options_size = hdr->cmdline_size;
503
504 options_size++; /* NUL termination */
505
506 status = low_alloc(options_size, 1, &cmdline);
9fa7deda
MF
507 if (status != EFI_SUCCESS) {
508 efi_printk("Failed to alloc mem for cmdline\n");
291f3632 509 goto fail;
9fa7deda 510 }
291f3632
MF
511
512 s1 = (u8 *)(unsigned long)cmdline;
513 s2 = (u16 *)options;
514
515 for (i = 0; i < options_size - 1; i++)
516 *s1++ = *s2++;
517
518 *s1 = '\0';
519 }
520 }
521
522 hdr->cmd_line_ptr = cmdline;
523
524 hdr->ramdisk_image = 0;
525 hdr->ramdisk_size = 0;
526
291f3632
MF
527 /* Clear APM BIOS info */
528 memset(bi, 0, sizeof(*bi));
529
530 memset(sdt, 0, sizeof(*sdt));
531
9ca8f72a
MF
532 status = handle_ramdisks(image, hdr);
533 if (status != EFI_SUCCESS)
534 goto fail2;
535
536 return boot_params;
537fail2:
538 if (options_size)
539 low_free(options_size, hdr->cmd_line_ptr);
540fail:
541 low_free(0x4000, (unsigned long)boot_params);
542 return NULL;
543}
544
545static efi_status_t exit_boot(struct boot_params *boot_params,
546 void *handle)
547{
548 struct efi_info *efi = &boot_params->efi_info;
549 struct e820entry *e820_map = &boot_params->e820_map[0];
550 struct e820entry *prev = NULL;
551 unsigned long size, key, desc_size, _size;
552 efi_memory_desc_t *mem_map;
553 efi_status_t status;
554 __u32 desc_version;
d3768d88 555 bool called_exit = false;
9ca8f72a
MF
556 u8 nr_entries;
557 int i;
291f3632
MF
558
559 size = sizeof(*mem_map) * 32;
560
561again:
d3768d88 562 size += sizeof(*mem_map) * 2;
291f3632
MF
563 _size = size;
564 status = low_alloc(size, 1, (unsigned long *)&mem_map);
565 if (status != EFI_SUCCESS)
9ca8f72a 566 return status;
291f3632 567
d3768d88 568get_map:
291f3632
MF
569 status = efi_call_phys5(sys_table->boottime->get_memory_map, &size,
570 mem_map, &key, &desc_size, &desc_version);
571 if (status == EFI_BUFFER_TOO_SMALL) {
572 low_free(_size, (unsigned long)mem_map);
573 goto again;
574 }
575
576 if (status != EFI_SUCCESS)
577 goto free_mem_map;
578
9ca8f72a 579 memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
291f3632
MF
580 efi->efi_systab = (unsigned long)sys_table;
581 efi->efi_memdesc_size = desc_size;
582 efi->efi_memdesc_version = desc_version;
583 efi->efi_memmap = (unsigned long)mem_map;
584 efi->efi_memmap_size = size;
585
586#ifdef CONFIG_X86_64
587 efi->efi_systab_hi = (unsigned long)sys_table >> 32;
588 efi->efi_memmap_hi = (unsigned long)mem_map >> 32;
589#endif
590
591 /* Might as well exit boot services now */
592 status = efi_call_phys2(sys_table->boottime->exit_boot_services,
593 handle, key);
d3768d88
ZB
594 if (status != EFI_SUCCESS) {
595 /*
596 * ExitBootServices() will fail if any of the event
597 * handlers change the memory map. In which case, we
598 * must be prepared to retry, but only once so that
599 * we're guaranteed to exit on repeated failures instead
600 * of spinning forever.
601 */
602 if (called_exit)
603 goto free_mem_map;
604
605 called_exit = true;
606 goto get_map;
607 }
291f3632
MF
608
609 /* Historic? */
610 boot_params->alt_mem_k = 32 * 1024;
611
612 /*
613 * Convert the EFI memory map to E820.
614 */
615 nr_entries = 0;
616 for (i = 0; i < size / desc_size; i++) {
617 efi_memory_desc_t *d;
618 unsigned int e820_type = 0;
619 unsigned long m = (unsigned long)mem_map;
620
621 d = (efi_memory_desc_t *)(m + (i * desc_size));
622 switch (d->type) {
623 case EFI_RESERVED_TYPE:
624 case EFI_RUNTIME_SERVICES_CODE:
625 case EFI_RUNTIME_SERVICES_DATA:
626 case EFI_MEMORY_MAPPED_IO:
627 case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
628 case EFI_PAL_CODE:
629 e820_type = E820_RESERVED;
630 break;
631
632 case EFI_UNUSABLE_MEMORY:
633 e820_type = E820_UNUSABLE;
634 break;
635
636 case EFI_ACPI_RECLAIM_MEMORY:
637 e820_type = E820_ACPI;
638 break;
639
640 case EFI_LOADER_CODE:
641 case EFI_LOADER_DATA:
642 case EFI_BOOT_SERVICES_CODE:
643 case EFI_BOOT_SERVICES_DATA:
644 case EFI_CONVENTIONAL_MEMORY:
645 e820_type = E820_RAM;
646 break;
647
648 case EFI_ACPI_MEMORY_NVS:
649 e820_type = E820_NVS;
650 break;
651
652 default:
653 continue;
654 }
655
656 /* Merge adjacent mappings */
657 if (prev && prev->type == e820_type &&
658 (prev->addr + prev->size) == d->phys_addr)
659 prev->size += d->num_pages << 12;
660 else {
661 e820_map->addr = d->phys_addr;
662 e820_map->size = d->num_pages << 12;
663 e820_map->type = e820_type;
664 prev = e820_map++;
665 nr_entries++;
666 }
667 }
668
669 boot_params->e820_entries = nr_entries;
670
671 return EFI_SUCCESS;
672
673free_mem_map:
674 low_free(_size, (unsigned long)mem_map);
291f3632
MF
675 return status;
676}
677
9ca8f72a 678static efi_status_t relocate_kernel(struct setup_header *hdr)
291f3632 679{
291f3632 680 unsigned long start, nr_pages;
291f3632 681 efi_status_t status;
e31be363 682
291f3632
MF
683 /*
684 * The EFI firmware loader could have placed the kernel image
685 * anywhere in memory, but the kernel has various restrictions
686 * on the max physical address it can run at. Attempt to move
687 * the kernel to boot_params.pref_address, or as low as
688 * possible.
689 */
690 start = hdr->pref_address;
691 nr_pages = round_up(hdr->init_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
692
693 status = efi_call_phys4(sys_table->boottime->allocate_pages,
694 EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
695 nr_pages, &start);
696 if (status != EFI_SUCCESS) {
697 status = low_alloc(hdr->init_size, hdr->kernel_alignment,
698 &start);
9ca8f72a 699 if (status != EFI_SUCCESS)
9fa7deda 700 efi_printk("Failed to alloc mem for kernel\n");
291f3632
MF
701 }
702
9ca8f72a
MF
703 if (status == EFI_SUCCESS)
704 memcpy((void *)start, (void *)(unsigned long)hdr->code32_start,
705 hdr->init_size);
706
707 hdr->pref_address = hdr->code32_start;
291f3632 708 hdr->code32_start = (__u32)start;
291f3632 709
9ca8f72a
MF
710 return status;
711}
712
713/*
714 * On success we return a pointer to a boot_params structure, and NULL
715 * on failure.
716 */
717struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
718 struct boot_params *boot_params)
719{
720 struct desc_ptr *gdt, *idt;
721 efi_loaded_image_t *image;
722 struct setup_header *hdr = &boot_params->hdr;
723 efi_status_t status;
724 struct desc_struct *desc;
725
726 sys_table = _table;
727
728 /* Check if we were booted by the EFI firmware */
729 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
730 goto fail;
731
732 setup_graphics(boot_params);
291f3632 733
dd5fc854
MG
734 setup_efi_pci(boot_params);
735
291f3632
MF
736 status = efi_call_phys3(sys_table->boottime->allocate_pool,
737 EFI_LOADER_DATA, sizeof(*gdt),
738 (void **)&gdt);
9fa7deda
MF
739 if (status != EFI_SUCCESS) {
740 efi_printk("Failed to alloc mem for gdt structure\n");
291f3632 741 goto fail;
9fa7deda 742 }
291f3632
MF
743
744 gdt->size = 0x800;
745 status = low_alloc(gdt->size, 8, (unsigned long *)&gdt->address);
9fa7deda
MF
746 if (status != EFI_SUCCESS) {
747 efi_printk("Failed to alloc mem for gdt\n");
291f3632 748 goto fail;
9fa7deda 749 }
291f3632
MF
750
751 status = efi_call_phys3(sys_table->boottime->allocate_pool,
752 EFI_LOADER_DATA, sizeof(*idt),
753 (void **)&idt);
9fa7deda
MF
754 if (status != EFI_SUCCESS) {
755 efi_printk("Failed to alloc mem for idt structure\n");
291f3632 756 goto fail;
9fa7deda 757 }
291f3632
MF
758
759 idt->size = 0;
760 idt->address = 0;
761
9ca8f72a
MF
762 /*
763 * If the kernel isn't already loaded at the preferred load
764 * address, relocate it.
765 */
766 if (hdr->pref_address != hdr->code32_start) {
767 status = relocate_kernel(hdr);
768
769 if (status != EFI_SUCCESS)
770 goto fail;
771 }
772
773 status = exit_boot(boot_params, handle);
291f3632
MF
774 if (status != EFI_SUCCESS)
775 goto fail;
776
777 memset((char *)gdt->address, 0x0, gdt->size);
778 desc = (struct desc_struct *)gdt->address;
779
780 /* The first GDT is a dummy and the second is unused. */
781 desc += 2;
782
783 desc->limit0 = 0xffff;
784 desc->base0 = 0x0000;
785 desc->base1 = 0x0000;
786 desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
787 desc->s = DESC_TYPE_CODE_DATA;
788 desc->dpl = 0;
789 desc->p = 1;
790 desc->limit = 0xf;
791 desc->avl = 0;
792 desc->l = 0;
793 desc->d = SEG_OP_SIZE_32BIT;
794 desc->g = SEG_GRANULARITY_4KB;
795 desc->base2 = 0x00;
796
797 desc++;
798 desc->limit0 = 0xffff;
799 desc->base0 = 0x0000;
800 desc->base1 = 0x0000;
801 desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
802 desc->s = DESC_TYPE_CODE_DATA;
803 desc->dpl = 0;
804 desc->p = 1;
805 desc->limit = 0xf;
806 desc->avl = 0;
807 desc->l = 0;
808 desc->d = SEG_OP_SIZE_32BIT;
809 desc->g = SEG_GRANULARITY_4KB;
810 desc->base2 = 0x00;
811
812#ifdef CONFIG_X86_64
813 /* Task segment value */
814 desc++;
815 desc->limit0 = 0x0000;
816 desc->base0 = 0x0000;
817 desc->base1 = 0x0000;
818 desc->type = SEG_TYPE_TSS;
819 desc->s = 0;
820 desc->dpl = 0;
821 desc->p = 1;
822 desc->limit = 0x0;
823 desc->avl = 0;
824 desc->l = 0;
825 desc->d = 0;
826 desc->g = SEG_GRANULARITY_4KB;
827 desc->base2 = 0x00;
828#endif /* CONFIG_X86_64 */
829
830 asm volatile ("lidt %0" : : "m" (*idt));
831 asm volatile ("lgdt %0" : : "m" (*gdt));
832
833 asm volatile("cli");
834
835 return boot_params;
836fail:
837 return NULL;
838}