x86/efi: Add early thunk code to go from 64-bit to 32-bit
[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
54b52d87
MF
22static struct efi_config *efi_early;
23
24#define BOOT_SERVICES(bits) \
25static void setup_boot_services##bits(struct efi_config *c) \
26{ \
27 efi_system_table_##bits##_t *table; \
28 efi_boot_services_##bits##_t *bt; \
29 \
30 table = (typeof(table))sys_table; \
31 \
32 c->text_output = table->con_out; \
33 \
34 bt = (typeof(bt))(unsigned long)(table->boottime); \
35 \
36 c->allocate_pool = bt->allocate_pool; \
37 c->allocate_pages = bt->allocate_pages; \
38 c->get_memory_map = bt->get_memory_map; \
39 c->free_pool = bt->free_pool; \
40 c->free_pages = bt->free_pages; \
41 c->locate_handle = bt->locate_handle; \
42 c->handle_protocol = bt->handle_protocol; \
43 c->exit_boot_services = bt->exit_boot_services; \
44}
45BOOT_SERVICES(32);
46BOOT_SERVICES(64);
291f3632 47
54b52d87
MF
48static void efi_printk(efi_system_table_t *, char *);
49static void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
50
51static efi_status_t
52efi_file_size(efi_system_table_t *sys_table, void *__fh,
53 efi_char16_t *filename_16, void **handle, u64 *file_sz)
54{
55 efi_file_handle_t *h, *fh = __fh;
56 efi_file_info_t *info;
57 efi_status_t status;
58 efi_guid_t info_guid = EFI_FILE_INFO_ID;
59 u32 info_sz;
60
61 status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
62 EFI_FILE_MODE_READ, (u64)0);
63 if (status != EFI_SUCCESS) {
64 efi_printk(sys_table, "Failed to open file: ");
65 efi_char16_printk(sys_table, filename_16);
66 efi_printk(sys_table, "\n");
67 return status;
68 }
69
70 *handle = h;
71
72 info_sz = 0;
73 status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
74 &info_sz, NULL);
75 if (status != EFI_BUFFER_TOO_SMALL) {
76 efi_printk(sys_table, "Failed to get file info size\n");
77 return status;
78 }
79
80grow:
81 status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
82 info_sz, (void **)&info);
83 if (status != EFI_SUCCESS) {
84 efi_printk(sys_table, "Failed to alloc mem for file info\n");
85 return status;
86 }
87
88 status = efi_early->call((unsigned long)h->get_info, h, &info_guid,
89 &info_sz, info);
90 if (status == EFI_BUFFER_TOO_SMALL) {
91 efi_early->call(efi_early->free_pool, info);
92 goto grow;
93 }
94
95 *file_sz = info->file_size;
96 efi_early->call(efi_early->free_pool, info);
97
98 if (status != EFI_SUCCESS)
99 efi_printk(sys_table, "Failed to get initrd info\n");
100
101 return status;
102}
103
104static inline efi_status_t
105efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr)
106{
107 efi_file_handle_t *fh = __fh;
108 return efi_early->call((unsigned long)fh->read, handle, size, addr);
109}
110
111static inline efi_status_t efi_file_close(void *__fh, void *handle)
112{
113 efi_file_handle_t *fh = __fh;
291f3632 114
54b52d87
MF
115 return efi_early->call((unsigned long)fh->close, handle);
116}
117
118static inline efi_status_t
119efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh)
120{
121 efi_file_io_interface_t *io;
122 efi_loaded_image_t *image = __image;
123 efi_file_handle_t *fh;
124 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
125 efi_status_t status;
126 void *handle = (void *)(unsigned long)image->device_handle;
127 u32 func;
128
129 status = efi_early->call(efi_early->handle_protocol, handle,
130 &fs_proto, (void **)&io);
131 if (status != EFI_SUCCESS) {
132 efi_printk(sys_table, "Failed to handle fs_proto\n");
133 return status;
134 }
291f3632 135
54b52d87
MF
136 func = (unsigned long)io->open_volume;
137 status = efi_early->call(func, io, &fh);
138 if (status != EFI_SUCCESS)
139 efi_printk(sys_table, "Failed to open volume\n");
140
141 *__fh = fh;
142 return status;
143}
144
145static inline void
146efi_char16_printk(efi_system_table_t *table, efi_char16_t *str)
147{
148 struct efi_simple_text_output_protocol *out;
149 unsigned long output_string;
150 size_t offset;
151 unsigned long *func;
152
153 offset = offsetof(typeof(*out), output_string);
154 output_string = efi_early->text_output + offset;
155 func = (unsigned long *)output_string;
156
157 efi_early->call(*func, efi_early->text_output, str);
158}
159
160#include "../../../../drivers/firmware/efi/efi-stub-helper.c"
291f3632
MF
161
162static void find_bits(unsigned long mask, u8 *pos, u8 *size)
163{
164 u8 first, len;
165
166 first = 0;
167 len = 0;
168
169 if (mask) {
170 while (!(mask & 0x1)) {
171 mask = mask >> 1;
172 first++;
173 }
174
175 while (mask & 0x1) {
176 mask = mask >> 1;
177 len++;
178 }
179 }
180
181 *pos = first;
182 *size = len;
183}
184
dd5fc854
MG
185static efi_status_t setup_efi_pci(struct boot_params *params)
186{
187 efi_pci_io_protocol *pci;
188 efi_status_t status;
54b52d87 189 void **pci_handle = NULL;
dd5fc854
MG
190 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID;
191 unsigned long nr_pci, size = 0;
192 int i;
193 struct setup_data *data;
194
bc754790 195 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
dd5fc854
MG
196
197 while (data && data->next)
bc754790 198 data = (struct setup_data *)(unsigned long)data->next;
dd5fc854 199
54b52d87
MF
200 status = efi_early->call(efi_early->locate_handle,
201 EFI_LOCATE_BY_PROTOCOL,
202 &pci_proto, NULL, &size, pci_handle);
dd5fc854
MG
203
204 if (status == EFI_BUFFER_TOO_SMALL) {
54b52d87
MF
205 status = efi_early->call(efi_early->allocate_pool,
206 EFI_LOADER_DATA,
207 size, (void **)&pci_handle);
dd5fc854
MG
208
209 if (status != EFI_SUCCESS)
210 return status;
211
54b52d87
MF
212 status = efi_early->call(efi_early->locate_handle,
213 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
214 NULL, &size, pci_handle);
dd5fc854
MG
215 }
216
217 if (status != EFI_SUCCESS)
218 goto free_handle;
219
220 nr_pci = size / sizeof(void *);
221 for (i = 0; i < nr_pci; i++) {
222 void *h = pci_handle[i];
223 uint64_t attributes;
224 struct pci_setup_rom *rom;
225
54b52d87
MF
226 status = efi_early->call(efi_early->handle_protocol, h,
227 &pci_proto, (void **)&pci);
dd5fc854
MG
228
229 if (status != EFI_SUCCESS)
230 continue;
231
232 if (!pci)
233 continue;
234
b607e212 235#ifdef CONFIG_X86_64
54b52d87
MF
236 status = efi_early->call((unsigned long)pci->attributes, pci,
237 EfiPciIoAttributeOperationGet, 0,
238 &attributes);
b607e212 239#else
54b52d87
MF
240 status = efi_early->call((unsigned long)pci->attributes, pci,
241 EfiPciIoAttributeOperationGet, 0, 0,
242 &attributes);
b607e212 243#endif
dd5fc854
MG
244 if (status != EFI_SUCCESS)
245 continue;
246
dd5fc854
MG
247 if (!pci->romimage || !pci->romsize)
248 continue;
249
250 size = pci->romsize + sizeof(*rom);
251
54b52d87
MF
252 status = efi_early->call(efi_early->allocate_pool,
253 EFI_LOADER_DATA, size, &rom);
dd5fc854
MG
254
255 if (status != EFI_SUCCESS)
256 continue;
257
258 rom->data.type = SETUP_PCI;
259 rom->data.len = size - sizeof(struct setup_data);
260 rom->data.next = 0;
261 rom->pcilen = pci->romsize;
262
54b52d87
MF
263 status = efi_early->call((unsigned long)pci->pci.read, pci,
264 EfiPciIoWidthUint16, PCI_VENDOR_ID,
265 1, &(rom->vendor));
dd5fc854
MG
266
267 if (status != EFI_SUCCESS)
268 goto free_struct;
269
54b52d87
MF
270 status = efi_early->call((unsigned long)pci->pci.read, pci,
271 EfiPciIoWidthUint16, PCI_DEVICE_ID,
272 1, &(rom->devid));
dd5fc854
MG
273
274 if (status != EFI_SUCCESS)
275 goto free_struct;
276
54b52d87
MF
277 status = efi_early->call((unsigned long)pci->get_location, pci,
278 &(rom->segment), &(rom->bus),
279 &(rom->device), &(rom->function));
dd5fc854
MG
280
281 if (status != EFI_SUCCESS)
282 goto free_struct;
283
284 memcpy(rom->romdata, pci->romimage, pci->romsize);
285
286 if (data)
bc754790 287 data->next = (unsigned long)rom;
dd5fc854 288 else
bc754790 289 params->hdr.setup_data = (unsigned long)rom;
dd5fc854
MG
290
291 data = (struct setup_data *)rom;
292
293 continue;
294 free_struct:
54b52d87 295 efi_early->call(efi_early->free_pool, rom);
dd5fc854
MG
296 }
297
298free_handle:
54b52d87 299 efi_early->call(efi_early->free_pool, pci_handle);
dd5fc854
MG
300 return status;
301}
302
291f3632
MF
303/*
304 * See if we have Graphics Output Protocol
305 */
306static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
307 unsigned long size)
308{
309 struct efi_graphics_output_protocol *gop, *first_gop;
310 struct efi_pixel_bitmask pixel_info;
311 unsigned long nr_gops;
312 efi_status_t status;
54b52d87 313 void **gop_handle = NULL;
291f3632
MF
314 u16 width, height;
315 u32 fb_base, fb_size;
316 u32 pixels_per_scan_line;
317 int pixel_format;
318 int i;
319
54b52d87
MF
320 status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
321 size, (void **)&gop_handle);
291f3632
MF
322 if (status != EFI_SUCCESS)
323 return status;
324
54b52d87
MF
325 status = efi_early->call(efi_early->locate_handle,
326 EFI_LOCATE_BY_PROTOCOL,
327 proto, NULL, &size, gop_handle);
291f3632
MF
328 if (status != EFI_SUCCESS)
329 goto free_handle;
330
331 first_gop = NULL;
332
333 nr_gops = size / sizeof(void *);
334 for (i = 0; i < nr_gops; i++) {
335 struct efi_graphics_output_mode_info *info;
38cb5ef4
MG
336 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID;
337 bool conout_found = false;
338 void *dummy;
291f3632
MF
339 void *h = gop_handle[i];
340
54b52d87
MF
341 status = efi_early->call(efi_early->handle_protocol, h,
342 proto, (void **)&gop);
291f3632
MF
343 if (status != EFI_SUCCESS)
344 continue;
345
54b52d87
MF
346 status = efi_early->call(efi_early->handle_protocol, h,
347 &conout_proto, &dummy);
38cb5ef4
MG
348 if (status == EFI_SUCCESS)
349 conout_found = true;
291f3632 350
54b52d87
MF
351 status = efi_early->call((unsigned long)gop->query_mode, gop,
352 gop->mode->mode, &size, &info);
38cb5ef4 353 if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
291f3632 354 /*
38cb5ef4
MG
355 * Systems that use the UEFI Console Splitter may
356 * provide multiple GOP devices, not all of which are
357 * backed by real hardware. The workaround is to search
358 * for a GOP implementing the ConOut protocol, and if
359 * one isn't found, to just fall back to the first GOP.
291f3632
MF
360 */
361 width = info->horizontal_resolution;
362 height = info->vertical_resolution;
363 fb_base = gop->mode->frame_buffer_base;
364 fb_size = gop->mode->frame_buffer_size;
365 pixel_format = info->pixel_format;
366 pixel_info = info->pixel_information;
367 pixels_per_scan_line = info->pixels_per_scan_line;
368
369 /*
38cb5ef4 370 * Once we've found a GOP supporting ConOut,
291f3632
MF
371 * don't bother looking any further.
372 */
70a479cb 373 first_gop = gop;
38cb5ef4 374 if (conout_found)
291f3632 375 break;
291f3632
MF
376 }
377 }
378
379 /* Did we find any GOPs? */
380 if (!first_gop)
381 goto free_handle;
382
383 /* EFI framebuffer */
384 si->orig_video_isVGA = VIDEO_TYPE_EFI;
385
386 si->lfb_width = width;
387 si->lfb_height = height;
388 si->lfb_base = fb_base;
291f3632
MF
389 si->pages = 1;
390
391 if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) {
392 si->lfb_depth = 32;
393 si->lfb_linelength = pixels_per_scan_line * 4;
394 si->red_size = 8;
395 si->red_pos = 0;
396 si->green_size = 8;
397 si->green_pos = 8;
398 si->blue_size = 8;
399 si->blue_pos = 16;
400 si->rsvd_size = 8;
401 si->rsvd_pos = 24;
402 } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) {
403 si->lfb_depth = 32;
404 si->lfb_linelength = pixels_per_scan_line * 4;
405 si->red_size = 8;
406 si->red_pos = 16;
407 si->green_size = 8;
408 si->green_pos = 8;
409 si->blue_size = 8;
410 si->blue_pos = 0;
411 si->rsvd_size = 8;
412 si->rsvd_pos = 24;
413 } else if (pixel_format == PIXEL_BIT_MASK) {
414 find_bits(pixel_info.red_mask, &si->red_pos, &si->red_size);
415 find_bits(pixel_info.green_mask, &si->green_pos,
416 &si->green_size);
417 find_bits(pixel_info.blue_mask, &si->blue_pos, &si->blue_size);
418 find_bits(pixel_info.reserved_mask, &si->rsvd_pos,
419 &si->rsvd_size);
420 si->lfb_depth = si->red_size + si->green_size +
421 si->blue_size + si->rsvd_size;
422 si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8;
423 } else {
424 si->lfb_depth = 4;
425 si->lfb_linelength = si->lfb_width / 2;
426 si->red_size = 0;
427 si->red_pos = 0;
428 si->green_size = 0;
429 si->green_pos = 0;
430 si->blue_size = 0;
431 si->blue_pos = 0;
432 si->rsvd_size = 0;
433 si->rsvd_pos = 0;
434 }
435
e9b10953
MG
436 si->lfb_size = si->lfb_linelength * si->lfb_height;
437
f462ed93
MG
438 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS;
439
291f3632 440free_handle:
54b52d87 441 efi_early->call(efi_early->free_pool, gop_handle);
291f3632
MF
442 return status;
443}
444
445/*
446 * See if we have Universal Graphics Adapter (UGA) protocol
447 */
448static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto,
449 unsigned long size)
450{
451 struct efi_uga_draw_protocol *uga, *first_uga;
452 unsigned long nr_ugas;
453 efi_status_t status;
454 u32 width, height;
455 void **uga_handle = NULL;
456 int i;
457
54b52d87
MF
458 status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
459 size, (void **)&uga_handle);
291f3632
MF
460 if (status != EFI_SUCCESS)
461 return status;
462
54b52d87
MF
463 status = efi_early->call(efi_early->locate_handle,
464 EFI_LOCATE_BY_PROTOCOL,
465 uga_proto, NULL, &size, uga_handle);
291f3632
MF
466 if (status != EFI_SUCCESS)
467 goto free_handle;
468
469 first_uga = NULL;
470
471 nr_ugas = size / sizeof(void *);
472 for (i = 0; i < nr_ugas; i++) {
473 efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID;
474 void *handle = uga_handle[i];
475 u32 w, h, depth, refresh;
476 void *pciio;
477
54b52d87
MF
478 status = efi_early->call(efi_early->handle_protocol, handle,
479 uga_proto, (void **)&uga);
291f3632
MF
480 if (status != EFI_SUCCESS)
481 continue;
482
54b52d87
MF
483 efi_early->call(efi_early->handle_protocol, handle,
484 &pciio_proto, &pciio);
291f3632 485
54b52d87
MF
486 status = efi_early->call((unsigned long)uga->get_mode, uga,
487 &w, &h, &depth, &refresh);
291f3632
MF
488 if (status == EFI_SUCCESS && (!first_uga || pciio)) {
489 width = w;
490 height = h;
491
492 /*
493 * Once we've found a UGA supporting PCIIO,
494 * don't bother looking any further.
495 */
496 if (pciio)
497 break;
498
499 first_uga = uga;
500 }
501 }
502
503 if (!first_uga)
504 goto free_handle;
505
506 /* EFI framebuffer */
507 si->orig_video_isVGA = VIDEO_TYPE_EFI;
508
509 si->lfb_depth = 32;
510 si->lfb_width = width;
511 si->lfb_height = height;
512
513 si->red_size = 8;
514 si->red_pos = 16;
515 si->green_size = 8;
516 si->green_pos = 8;
517 si->blue_size = 8;
518 si->blue_pos = 0;
519 si->rsvd_size = 8;
520 si->rsvd_pos = 24;
521
522
523free_handle:
54b52d87 524 efi_early->call(efi_early->free_pool, uga_handle);
291f3632
MF
525 return status;
526}
527
528void setup_graphics(struct boot_params *boot_params)
529{
530 efi_guid_t graphics_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
531 struct screen_info *si;
532 efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID;
533 efi_status_t status;
534 unsigned long size;
535 void **gop_handle = NULL;
536 void **uga_handle = NULL;
537
538 si = &boot_params->screen_info;
539 memset(si, 0, sizeof(*si));
540
541 size = 0;
54b52d87
MF
542 status = efi_early->call(efi_early->locate_handle,
543 EFI_LOCATE_BY_PROTOCOL,
544 &graphics_proto, NULL, &size, gop_handle);
291f3632
MF
545 if (status == EFI_BUFFER_TOO_SMALL)
546 status = setup_gop(si, &graphics_proto, size);
547
548 if (status != EFI_SUCCESS) {
549 size = 0;
54b52d87
MF
550 status = efi_early->call(efi_early->locate_handle,
551 EFI_LOCATE_BY_PROTOCOL,
552 &uga_proto, NULL, &size, uga_handle);
291f3632
MF
553 if (status == EFI_BUFFER_TOO_SMALL)
554 setup_uga(si, &uga_proto, size);
555 }
556}
557
291f3632
MF
558/*
559 * Because the x86 boot code expects to be passed a boot_params we
560 * need to create one ourselves (usually the bootloader would create
561 * one for us).
562 */
54b52d87 563struct boot_params *make_boot_params(struct efi_config *c)
291f3632 564{
9ca8f72a
MF
565 struct boot_params *boot_params;
566 struct sys_desc_table *sdt;
567 struct apm_bios_info *bi;
568 struct setup_header *hdr;
569 struct efi_info *efi;
570 efi_loaded_image_t *image;
54b52d87 571 void *options, *handle;
9ca8f72a 572 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
291f3632
MF
573 int options_size = 0;
574 efi_status_t status;
5fef3870 575 char *cmdline_ptr;
291f3632
MF
576 u16 *s2;
577 u8 *s1;
578 int i;
46f4582e
RF
579 unsigned long ramdisk_addr;
580 unsigned long ramdisk_size;
291f3632 581
54b52d87
MF
582 efi_early = c;
583 sys_table = (efi_system_table_t *)(unsigned long)efi_early->table;
584 handle = (void *)(unsigned long)efi_early->image_handle;
9ca8f72a
MF
585
586 /* Check if we were booted by the EFI firmware */
587 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
588 return NULL;
589
54b52d87
MF
590 if (efi_early->is64)
591 setup_boot_services64(efi_early);
592 else
593 setup_boot_services32(efi_early);
594
595 status = efi_early->call(efi_early->handle_protocol, handle,
596 &proto, (void *)&image);
9ca8f72a 597 if (status != EFI_SUCCESS) {
876dc36a 598 efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
9ca8f72a
MF
599 return NULL;
600 }
601
40e4530a
RF
602 status = efi_low_alloc(sys_table, 0x4000, 1,
603 (unsigned long *)&boot_params);
9ca8f72a 604 if (status != EFI_SUCCESS) {
876dc36a 605 efi_printk(sys_table, "Failed to alloc lowmem for boot params\n");
9ca8f72a
MF
606 return NULL;
607 }
608
609 memset(boot_params, 0x0, 0x4000);
610
611 hdr = &boot_params->hdr;
612 efi = &boot_params->efi_info;
613 bi = &boot_params->apm_bios_info;
614 sdt = &boot_params->sys_desc_table;
615
616 /* Copy the second sector to boot_params */
617 memcpy(&hdr->jump, image->image_base + 512, 512);
618
619 /*
620 * Fill out some of the header fields ourselves because the
621 * EFI firmware loader doesn't load the first sector.
622 */
623 hdr->root_flags = 1;
624 hdr->vid_mode = 0xffff;
625 hdr->boot_flag = 0xAA55;
626
627 hdr->code32_start = (__u64)(unsigned long)image->image_base;
628
291f3632
MF
629 hdr->type_of_loader = 0x21;
630
631 /* Convert unicode cmdline to ascii */
5fef3870
RF
632 cmdline_ptr = efi_convert_cmdline_to_ascii(sys_table, image,
633 &options_size);
634 if (!cmdline_ptr)
635 goto fail;
636 hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
291f3632
MF
637
638 hdr->ramdisk_image = 0;
639 hdr->ramdisk_size = 0;
640
291f3632
MF
641 /* Clear APM BIOS info */
642 memset(bi, 0, sizeof(*bi));
643
644 memset(sdt, 0, sizeof(*sdt));
645
46f4582e
RF
646 status = handle_cmdline_files(sys_table, image,
647 (char *)(unsigned long)hdr->cmd_line_ptr,
648 "initrd=", hdr->initrd_addr_max,
649 &ramdisk_addr, &ramdisk_size);
9ca8f72a
MF
650 if (status != EFI_SUCCESS)
651 goto fail2;
46f4582e
RF
652 hdr->ramdisk_image = ramdisk_addr;
653 hdr->ramdisk_size = ramdisk_size;
9ca8f72a
MF
654
655 return boot_params;
656fail2:
0e1cadb0 657 efi_free(sys_table, options_size, hdr->cmd_line_ptr);
9ca8f72a 658fail:
40e4530a 659 efi_free(sys_table, 0x4000, (unsigned long)boot_params);
9ca8f72a
MF
660 return NULL;
661}
662
d2078d5a
LC
663static void add_e820ext(struct boot_params *params,
664 struct setup_data *e820ext, u32 nr_entries)
9ca8f72a 665{
d2078d5a 666 struct setup_data *data;
9ca8f72a 667 efi_status_t status;
d2078d5a 668 unsigned long size;
291f3632 669
d2078d5a
LC
670 e820ext->type = SETUP_E820_EXT;
671 e820ext->len = nr_entries * sizeof(struct e820entry);
672 e820ext->next = 0;
291f3632 673
d2078d5a 674 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
291f3632 675
d2078d5a
LC
676 while (data && data->next)
677 data = (struct setup_data *)(unsigned long)data->next;
d3768d88 678
d2078d5a
LC
679 if (data)
680 data->next = (unsigned long)e820ext;
681 else
682 params->hdr.setup_data = (unsigned long)e820ext;
683}
291f3632 684
d2078d5a
LC
685static efi_status_t setup_e820(struct boot_params *params,
686 struct setup_data *e820ext, u32 e820ext_size)
687{
688 struct e820entry *e820_map = &params->e820_map[0];
689 struct efi_info *efi = &params->efi_info;
690 struct e820entry *prev = NULL;
691 u32 nr_entries;
692 u32 nr_desc;
693 int i;
291f3632 694
291f3632 695 nr_entries = 0;
d2078d5a
LC
696 nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size;
697
698 for (i = 0; i < nr_desc; i++) {
291f3632
MF
699 efi_memory_desc_t *d;
700 unsigned int e820_type = 0;
d2078d5a 701 unsigned long m = efi->efi_memmap;
291f3632 702
d2078d5a 703 d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size));
291f3632
MF
704 switch (d->type) {
705 case EFI_RESERVED_TYPE:
706 case EFI_RUNTIME_SERVICES_CODE:
707 case EFI_RUNTIME_SERVICES_DATA:
708 case EFI_MEMORY_MAPPED_IO:
709 case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
710 case EFI_PAL_CODE:
711 e820_type = E820_RESERVED;
712 break;
713
714 case EFI_UNUSABLE_MEMORY:
715 e820_type = E820_UNUSABLE;
716 break;
717
718 case EFI_ACPI_RECLAIM_MEMORY:
719 e820_type = E820_ACPI;
720 break;
721
722 case EFI_LOADER_CODE:
723 case EFI_LOADER_DATA:
724 case EFI_BOOT_SERVICES_CODE:
725 case EFI_BOOT_SERVICES_DATA:
726 case EFI_CONVENTIONAL_MEMORY:
727 e820_type = E820_RAM;
728 break;
729
730 case EFI_ACPI_MEMORY_NVS:
731 e820_type = E820_NVS;
732 break;
733
734 default:
735 continue;
736 }
737
738 /* Merge adjacent mappings */
739 if (prev && prev->type == e820_type &&
d2078d5a 740 (prev->addr + prev->size) == d->phys_addr) {
291f3632 741 prev->size += d->num_pages << 12;
d2078d5a 742 continue;
291f3632 743 }
d2078d5a
LC
744
745 if (nr_entries == ARRAY_SIZE(params->e820_map)) {
746 u32 need = (nr_desc - i) * sizeof(struct e820entry) +
747 sizeof(struct setup_data);
748
749 if (!e820ext || e820ext_size < need)
750 return EFI_BUFFER_TOO_SMALL;
751
752 /* boot_params map full, switch to e820 extended */
753 e820_map = (struct e820entry *)e820ext->data;
754 }
755
756 e820_map->addr = d->phys_addr;
757 e820_map->size = d->num_pages << PAGE_SHIFT;
758 e820_map->type = e820_type;
759 prev = e820_map++;
760 nr_entries++;
291f3632
MF
761 }
762
d2078d5a
LC
763 if (nr_entries > ARRAY_SIZE(params->e820_map)) {
764 u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map);
765
766 add_e820ext(params, e820ext, nr_e820ext);
767 nr_entries -= nr_e820ext;
768 }
769
770 params->e820_entries = (u8)nr_entries;
771
772 return EFI_SUCCESS;
773}
774
775static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext,
776 u32 *e820ext_size)
777{
778 efi_status_t status;
779 unsigned long size;
780
781 size = sizeof(struct setup_data) +
782 sizeof(struct e820entry) * nr_desc;
783
784 if (*e820ext) {
54b52d87 785 efi_early->call(efi_early->free_pool, *e820ext);
d2078d5a
LC
786 *e820ext = NULL;
787 *e820ext_size = 0;
788 }
789
54b52d87
MF
790 status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
791 size, (void **)e820ext);
d2078d5a
LC
792 if (status == EFI_SUCCESS)
793 *e820ext_size = size;
794
795 return status;
796}
797
798static efi_status_t exit_boot(struct boot_params *boot_params,
799 void *handle)
800{
801 struct efi_info *efi = &boot_params->efi_info;
802 unsigned long map_sz, key, desc_size;
803 efi_memory_desc_t *mem_map;
804 struct setup_data *e820ext;
805 __u32 e820ext_size;
806 __u32 nr_desc, prev_nr_desc;
807 efi_status_t status;
808 __u32 desc_version;
809 bool called_exit = false;
810 u8 nr_entries;
811 int i;
812
813 nr_desc = 0;
814 e820ext = NULL;
815 e820ext_size = 0;
816
817get_map:
818 status = efi_get_memory_map(sys_table, &mem_map, &map_sz, &desc_size,
819 &desc_version, &key);
820
821 if (status != EFI_SUCCESS)
822 return status;
823
824 prev_nr_desc = nr_desc;
825 nr_desc = map_sz / desc_size;
826 if (nr_desc > prev_nr_desc &&
827 nr_desc > ARRAY_SIZE(boot_params->e820_map)) {
828 u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params->e820_map);
829
830 status = alloc_e820ext(nr_e820ext, &e820ext, &e820ext_size);
831 if (status != EFI_SUCCESS)
832 goto free_mem_map;
833
54b52d87 834 efi_early->call(efi_early->free_pool, mem_map);
d2078d5a
LC
835 goto get_map; /* Allocated memory, get map again */
836 }
837
838 memcpy(&efi->efi_loader_signature, EFI_LOADER_SIGNATURE, sizeof(__u32));
839 efi->efi_systab = (unsigned long)sys_table;
840 efi->efi_memdesc_size = desc_size;
841 efi->efi_memdesc_version = desc_version;
842 efi->efi_memmap = (unsigned long)mem_map;
843 efi->efi_memmap_size = map_sz;
844
845#ifdef CONFIG_X86_64
846 efi->efi_systab_hi = (unsigned long)sys_table >> 32;
847 efi->efi_memmap_hi = (unsigned long)mem_map >> 32;
848#endif
849
850 /* Might as well exit boot services now */
54b52d87 851 status = efi_early->call(efi_early->exit_boot_services, handle, key);
d2078d5a
LC
852 if (status != EFI_SUCCESS) {
853 /*
854 * ExitBootServices() will fail if any of the event
855 * handlers change the memory map. In which case, we
856 * must be prepared to retry, but only once so that
857 * we're guaranteed to exit on repeated failures instead
858 * of spinning forever.
859 */
860 if (called_exit)
861 goto free_mem_map;
862
863 called_exit = true;
54b52d87 864 efi_early->call(efi_early->free_pool, mem_map);
d2078d5a
LC
865 goto get_map;
866 }
867
868 /* Historic? */
869 boot_params->alt_mem_k = 32 * 1024;
870
871 status = setup_e820(boot_params, e820ext, e820ext_size);
872 if (status != EFI_SUCCESS)
873 return status;
291f3632
MF
874
875 return EFI_SUCCESS;
876
877free_mem_map:
54b52d87 878 efi_early->call(efi_early->free_pool, mem_map);
291f3632
MF
879 return status;
880}
881
9ca8f72a
MF
882/*
883 * On success we return a pointer to a boot_params structure, and NULL
884 * on failure.
885 */
54b52d87 886struct boot_params *efi_main(struct efi_config *c,
9ca8f72a
MF
887 struct boot_params *boot_params)
888{
54b52d87 889 struct desc_ptr *gdt = NULL;
9ca8f72a
MF
890 efi_loaded_image_t *image;
891 struct setup_header *hdr = &boot_params->hdr;
892 efi_status_t status;
893 struct desc_struct *desc;
54b52d87
MF
894 void *handle;
895 efi_system_table_t *_table;
896 bool is64;
897
898 efi_early = c;
899
900 _table = (efi_system_table_t *)(unsigned long)efi_early->table;
901 handle = (void *)(unsigned long)efi_early->image_handle;
902 is64 = efi_early->is64;
9ca8f72a
MF
903
904 sys_table = _table;
905
906 /* Check if we were booted by the EFI firmware */
907 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
908 goto fail;
909
54b52d87
MF
910 if (is64)
911 setup_boot_services64(efi_early);
912 else
913 setup_boot_services32(efi_early);
914
9ca8f72a 915 setup_graphics(boot_params);
291f3632 916
dd5fc854
MG
917 setup_efi_pci(boot_params);
918
54b52d87
MF
919 status = efi_early->call(efi_early->allocate_pool, EFI_LOADER_DATA,
920 sizeof(*gdt), (void **)&gdt);
9fa7deda 921 if (status != EFI_SUCCESS) {
876dc36a 922 efi_printk(sys_table, "Failed to alloc mem for gdt structure\n");
291f3632 923 goto fail;
9fa7deda 924 }
291f3632
MF
925
926 gdt->size = 0x800;
40e4530a 927 status = efi_low_alloc(sys_table, gdt->size, 8,
876dc36a 928 (unsigned long *)&gdt->address);
9fa7deda 929 if (status != EFI_SUCCESS) {
876dc36a 930 efi_printk(sys_table, "Failed to alloc mem for gdt\n");
291f3632 931 goto fail;
9fa7deda 932 }
291f3632 933
9ca8f72a
MF
934 /*
935 * If the kernel isn't already loaded at the preferred load
936 * address, relocate it.
937 */
938 if (hdr->pref_address != hdr->code32_start) {
4a9f3a7c
RF
939 unsigned long bzimage_addr = hdr->code32_start;
940 status = efi_relocate_kernel(sys_table, &bzimage_addr,
941 hdr->init_size, hdr->init_size,
942 hdr->pref_address,
943 hdr->kernel_alignment);
9ca8f72a
MF
944 if (status != EFI_SUCCESS)
945 goto fail;
4a9f3a7c
RF
946
947 hdr->pref_address = hdr->code32_start;
948 hdr->code32_start = bzimage_addr;
9ca8f72a
MF
949 }
950
951 status = exit_boot(boot_params, handle);
291f3632
MF
952 if (status != EFI_SUCCESS)
953 goto fail;
954
955 memset((char *)gdt->address, 0x0, gdt->size);
956 desc = (struct desc_struct *)gdt->address;
957
958 /* The first GDT is a dummy and the second is unused. */
959 desc += 2;
960
961 desc->limit0 = 0xffff;
962 desc->base0 = 0x0000;
963 desc->base1 = 0x0000;
964 desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ;
965 desc->s = DESC_TYPE_CODE_DATA;
966 desc->dpl = 0;
967 desc->p = 1;
968 desc->limit = 0xf;
969 desc->avl = 0;
970 desc->l = 0;
971 desc->d = SEG_OP_SIZE_32BIT;
972 desc->g = SEG_GRANULARITY_4KB;
973 desc->base2 = 0x00;
974
975 desc++;
976 desc->limit0 = 0xffff;
977 desc->base0 = 0x0000;
978 desc->base1 = 0x0000;
979 desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE;
980 desc->s = DESC_TYPE_CODE_DATA;
981 desc->dpl = 0;
982 desc->p = 1;
983 desc->limit = 0xf;
984 desc->avl = 0;
985 desc->l = 0;
986 desc->d = SEG_OP_SIZE_32BIT;
987 desc->g = SEG_GRANULARITY_4KB;
988 desc->base2 = 0x00;
989
990#ifdef CONFIG_X86_64
991 /* Task segment value */
992 desc++;
993 desc->limit0 = 0x0000;
994 desc->base0 = 0x0000;
995 desc->base1 = 0x0000;
996 desc->type = SEG_TYPE_TSS;
997 desc->s = 0;
998 desc->dpl = 0;
999 desc->p = 1;
1000 desc->limit = 0x0;
1001 desc->avl = 0;
1002 desc->l = 0;
1003 desc->d = 0;
1004 desc->g = SEG_GRANULARITY_4KB;
1005 desc->base2 = 0x00;
1006#endif /* CONFIG_X86_64 */
1007
291f3632 1008 asm volatile("cli");
0ce6cda2 1009 asm volatile ("lgdt %0" : : "m" (*gdt));
291f3632
MF
1010
1011 return boot_params;
1012fail:
1013 return NULL;
1014}