Merge branch 'arm/common' into next
[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
522static efi_status_t exit_boot(struct boot_params *boot_params,
523 void *handle)
524{
525 struct efi_info *efi = &boot_params->efi_info;
526 struct e820entry *e820_map = &boot_params->e820_map[0];
527 struct e820entry *prev = NULL;
528 unsigned long size, key, desc_size, _size;
529 efi_memory_desc_t *mem_map;
530 efi_status_t status;
531 __u32 desc_version;
d3768d88 532 bool called_exit = false;
9ca8f72a
MF
533 u8 nr_entries;
534 int i;
291f3632 535
d3768d88 536get_map:
ae8e9060
RF
537 status = efi_get_memory_map(sys_table, &mem_map, &size, &desc_size,
538 &desc_version, &key);
291f3632
MF
539
540 if (status != EFI_SUCCESS)
ae8e9060 541 return status;
291f3632 542
9ca8f72a 543 memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
291f3632
MF
544 efi->efi_systab = (unsigned long)sys_table;
545 efi->efi_memdesc_size = desc_size;
546 efi->efi_memdesc_version = desc_version;
547 efi->efi_memmap = (unsigned long)mem_map;
548 efi->efi_memmap_size = size;
549
550#ifdef CONFIG_X86_64
551 efi->efi_systab_hi = (unsigned long)sys_table >> 32;
552 efi->efi_memmap_hi = (unsigned long)mem_map >> 32;
553#endif
554
555 /* Might as well exit boot services now */
556 status = efi_call_phys2(sys_table->boottime->exit_boot_services,
557 handle, key);
d3768d88
ZB
558 if (status != EFI_SUCCESS) {
559 /*
560 * ExitBootServices() will fail if any of the event
561 * handlers change the memory map. In which case, we
562 * must be prepared to retry, but only once so that
563 * we're guaranteed to exit on repeated failures instead
564 * of spinning forever.
565 */
566 if (called_exit)
567 goto free_mem_map;
568
569 called_exit = true;
ae8e9060 570 efi_call_phys1(sys_table->boottime->free_pool, mem_map);
d3768d88
ZB
571 goto get_map;
572 }
291f3632
MF
573
574 /* Historic? */
575 boot_params->alt_mem_k = 32 * 1024;
576
577 /*
578 * Convert the EFI memory map to E820.
579 */
580 nr_entries = 0;
581 for (i = 0; i < size / desc_size; i++) {
582 efi_memory_desc_t *d;
583 unsigned int e820_type = 0;
584 unsigned long m = (unsigned long)mem_map;
585
586 d = (efi_memory_desc_t *)(m + (i * desc_size));
587 switch (d->type) {
588 case EFI_RESERVED_TYPE:
589 case EFI_RUNTIME_SERVICES_CODE:
590 case EFI_RUNTIME_SERVICES_DATA:
591 case EFI_MEMORY_MAPPED_IO:
592 case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
593 case EFI_PAL_CODE:
594 e820_type = E820_RESERVED;
595 break;
596
597 case EFI_UNUSABLE_MEMORY:
598 e820_type = E820_UNUSABLE;
599 break;
600
601 case EFI_ACPI_RECLAIM_MEMORY:
602 e820_type = E820_ACPI;
603 break;
604
605 case EFI_LOADER_CODE:
606 case EFI_LOADER_DATA:
607 case EFI_BOOT_SERVICES_CODE:
608 case EFI_BOOT_SERVICES_DATA:
609 case EFI_CONVENTIONAL_MEMORY:
610 e820_type = E820_RAM;
611 break;
612
613 case EFI_ACPI_MEMORY_NVS:
614 e820_type = E820_NVS;
615 break;
616
617 default:
618 continue;
619 }
620
621 /* Merge adjacent mappings */
622 if (prev && prev->type == e820_type &&
623 (prev->addr + prev->size) == d->phys_addr)
624 prev->size += d->num_pages << 12;
625 else {
626 e820_map->addr = d->phys_addr;
627 e820_map->size = d->num_pages << 12;
628 e820_map->type = e820_type;
629 prev = e820_map++;
630 nr_entries++;
631 }
632 }
633
634 boot_params->e820_entries = nr_entries;
635
636 return EFI_SUCCESS;
637
638free_mem_map:
ae8e9060 639 efi_call_phys1(sys_table->boottime->free_pool, mem_map);
291f3632
MF
640 return status;
641}
642
9ca8f72a
MF
643
644/*
645 * On success we return a pointer to a boot_params structure, and NULL
646 * on failure.
647 */
648struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
649 struct boot_params *boot_params)
650{
651 struct desc_ptr *gdt, *idt;
652 efi_loaded_image_t *image;
653 struct setup_header *hdr = &boot_params->hdr;
654 efi_status_t status;
655 struct desc_struct *desc;
656
657 sys_table = _table;
658
659 /* Check if we were booted by the EFI firmware */
660 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
661 goto fail;
662
663 setup_graphics(boot_params);
291f3632 664
dd5fc854
MG
665 setup_efi_pci(boot_params);
666
291f3632
MF
667 status = efi_call_phys3(sys_table->boottime->allocate_pool,
668 EFI_LOADER_DATA, sizeof(*gdt),
669 (void **)&gdt);
9fa7deda 670 if (status != EFI_SUCCESS) {
876dc36a 671 efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
291f3632 672 goto fail;
9fa7deda 673 }
291f3632
MF
674
675 gdt->size = 0x800;
40e4530a 676 status = efi_low_alloc(sys_table, gdt->size, 8,
876dc36a 677 (unsigned long *)&gdt->address);
9fa7deda 678 if (status != EFI_SUCCESS) {
876dc36a 679 efi_printk(sys_table, "Failed to alloc mem for gdt\n");
291f3632 680 goto fail;
9fa7deda 681 }
291f3632
MF
682
683 status = efi_call_phys3(sys_table->boottime->allocate_pool,
684 EFI_LOADER_DATA, sizeof(*idt),
685 (void **)&idt);
9fa7deda 686 if (status != EFI_SUCCESS) {
876dc36a 687 efi_printk(sys_table, "Failed to alloc mem for idt structure\n");
291f3632 688 goto fail;
9fa7deda 689 }
291f3632
MF
690
691 idt->size = 0;
692 idt->address = 0;
693
9ca8f72a
MF
694 /*
695 * If the kernel isn't already loaded at the preferred load
696 * address, relocate it.
697 */
698 if (hdr->pref_address != hdr->code32_start) {
4a9f3a7c
RF
699 unsigned long bzimage_addr = hdr->code32_start;
700 status = efi_relocate_kernel(sys_table, &bzimage_addr,
701 hdr->init_size, hdr->init_size,
702 hdr->pref_address,
703 hdr->kernel_alignment);
9ca8f72a
MF
704 if (status != EFI_SUCCESS)
705 goto fail;
4a9f3a7c
RF
706
707 hdr->pref_address = hdr->code32_start;
708 hdr->code32_start = bzimage_addr;
9ca8f72a
MF
709 }
710
711 status = exit_boot(boot_params, handle);
291f3632
MF
712 if (status != EFI_SUCCESS)
713 goto fail;
714
715 memset((char *)gdt->address, 0x0, gdt->size);
716 desc = (struct desc_struct *)gdt->address;
717
718 /* The first GDT is a dummy and the second is unused. */
719 desc += 2;
720
721 desc->limit0 = 0xffff;
722 desc->base0 = 0x0000;
723 desc->base1 = 0x0000;
724 desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
725 desc->s = DESC_TYPE_CODE_DATA;
726 desc->dpl = 0;
727 desc->p = 1;
728 desc->limit = 0xf;
729 desc->avl = 0;
730 desc->l = 0;
731 desc->d = SEG_OP_SIZE_32BIT;
732 desc->g = SEG_GRANULARITY_4KB;
733 desc->base2 = 0x00;
734
735 desc++;
736 desc->limit0 = 0xffff;
737 desc->base0 = 0x0000;
738 desc->base1 = 0x0000;
739 desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
740 desc->s = DESC_TYPE_CODE_DATA;
741 desc->dpl = 0;
742 desc->p = 1;
743 desc->limit = 0xf;
744 desc->avl = 0;
745 desc->l = 0;
746 desc->d = SEG_OP_SIZE_32BIT;
747 desc->g = SEG_GRANULARITY_4KB;
748 desc->base2 = 0x00;
749
750#ifdef CONFIG_X86_64
751 /* Task segment value */
752 desc++;
753 desc->limit0 = 0x0000;
754 desc->base0 = 0x0000;
755 desc->base1 = 0x0000;
756 desc->type = SEG_TYPE_TSS;
757 desc->s = 0;
758 desc->dpl = 0;
759 desc->p = 1;
760 desc->limit = 0x0;
761 desc->avl = 0;
762 desc->l = 0;
763 desc->d = 0;
764 desc->g = SEG_GRANULARITY_4KB;
765 desc->base2 = 0x00;
766#endif /* CONFIG_X86_64 */
767
768 asm volatile ("lidt %0" : : "m" (*idt));
769 asm volatile ("lgdt %0" : : "m" (*gdt));
770
771 asm volatile("cli");
772
773 return boot_params;
774fail:
775 return NULL;
776}