Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.18-rc1 1496 lines 37 kB view raw
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> 11#include <linux/pci.h> 12#include <asm/efi.h> 13#include <asm/setup.h> 14#include <asm/desc.h> 15 16#undef memcpy /* Use memcpy from misc.c */ 17 18#include "eboot.h" 19 20static efi_system_table_t *sys_table; 21 22static struct efi_config *efi_early; 23 24#define efi_call_early(f, ...) \ 25 efi_early->call(efi_early->f, __VA_ARGS__); 26 27#define BOOT_SERVICES(bits) \ 28static void setup_boot_services##bits(struct efi_config *c) \ 29{ \ 30 efi_system_table_##bits##_t *table; \ 31 efi_boot_services_##bits##_t *bt; \ 32 \ 33 table = (typeof(table))sys_table; \ 34 \ 35 c->text_output = table->con_out; \ 36 \ 37 bt = (typeof(bt))(unsigned long)(table->boottime); \ 38 \ 39 c->allocate_pool = bt->allocate_pool; \ 40 c->allocate_pages = bt->allocate_pages; \ 41 c->get_memory_map = bt->get_memory_map; \ 42 c->free_pool = bt->free_pool; \ 43 c->free_pages = bt->free_pages; \ 44 c->locate_handle = bt->locate_handle; \ 45 c->handle_protocol = bt->handle_protocol; \ 46 c->exit_boot_services = bt->exit_boot_services; \ 47} 48BOOT_SERVICES(32); 49BOOT_SERVICES(64); 50 51void efi_char16_printk(efi_system_table_t *, efi_char16_t *); 52 53static efi_status_t 54__file_size32(void *__fh, efi_char16_t *filename_16, 55 void **handle, u64 *file_sz) 56{ 57 efi_file_handle_32_t *h, *fh = __fh; 58 efi_file_info_t *info; 59 efi_status_t status; 60 efi_guid_t info_guid = EFI_FILE_INFO_ID; 61 u32 info_sz; 62 63 status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, 64 EFI_FILE_MODE_READ, (u64)0); 65 if (status != EFI_SUCCESS) { 66 efi_printk(sys_table, "Failed to open file: "); 67 efi_char16_printk(sys_table, filename_16); 68 efi_printk(sys_table, "\n"); 69 return status; 70 } 71 72 *handle = h; 73 74 info_sz = 0; 75 status = efi_early->call((unsigned long)h->get_info, h, &info_guid, 76 &info_sz, NULL); 77 if (status != EFI_BUFFER_TOO_SMALL) { 78 efi_printk(sys_table, "Failed to get file info size\n"); 79 return status; 80 } 81 82grow: 83 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 84 info_sz, (void **)&info); 85 if (status != EFI_SUCCESS) { 86 efi_printk(sys_table, "Failed to alloc mem for file info\n"); 87 return status; 88 } 89 90 status = efi_early->call((unsigned long)h->get_info, h, &info_guid, 91 &info_sz, info); 92 if (status == EFI_BUFFER_TOO_SMALL) { 93 efi_call_early(free_pool, info); 94 goto grow; 95 } 96 97 *file_sz = info->file_size; 98 efi_call_early(free_pool, info); 99 100 if (status != EFI_SUCCESS) 101 efi_printk(sys_table, "Failed to get initrd info\n"); 102 103 return status; 104} 105 106static efi_status_t 107__file_size64(void *__fh, efi_char16_t *filename_16, 108 void **handle, u64 *file_sz) 109{ 110 efi_file_handle_64_t *h, *fh = __fh; 111 efi_file_info_t *info; 112 efi_status_t status; 113 efi_guid_t info_guid = EFI_FILE_INFO_ID; 114 u64 info_sz; 115 116 status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16, 117 EFI_FILE_MODE_READ, (u64)0); 118 if (status != EFI_SUCCESS) { 119 efi_printk(sys_table, "Failed to open file: "); 120 efi_char16_printk(sys_table, filename_16); 121 efi_printk(sys_table, "\n"); 122 return status; 123 } 124 125 *handle = h; 126 127 info_sz = 0; 128 status = efi_early->call((unsigned long)h->get_info, h, &info_guid, 129 &info_sz, NULL); 130 if (status != EFI_BUFFER_TOO_SMALL) { 131 efi_printk(sys_table, "Failed to get file info size\n"); 132 return status; 133 } 134 135grow: 136 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 137 info_sz, (void **)&info); 138 if (status != EFI_SUCCESS) { 139 efi_printk(sys_table, "Failed to alloc mem for file info\n"); 140 return status; 141 } 142 143 status = efi_early->call((unsigned long)h->get_info, h, &info_guid, 144 &info_sz, info); 145 if (status == EFI_BUFFER_TOO_SMALL) { 146 efi_call_early(free_pool, info); 147 goto grow; 148 } 149 150 *file_sz = info->file_size; 151 efi_call_early(free_pool, info); 152 153 if (status != EFI_SUCCESS) 154 efi_printk(sys_table, "Failed to get initrd info\n"); 155 156 return status; 157} 158efi_status_t 159efi_file_size(efi_system_table_t *sys_table, void *__fh, 160 efi_char16_t *filename_16, void **handle, u64 *file_sz) 161{ 162 if (efi_early->is64) 163 return __file_size64(__fh, filename_16, handle, file_sz); 164 165 return __file_size32(__fh, filename_16, handle, file_sz); 166} 167 168efi_status_t 169efi_file_read(void *handle, unsigned long *size, void *addr) 170{ 171 unsigned long func; 172 173 if (efi_early->is64) { 174 efi_file_handle_64_t *fh = handle; 175 176 func = (unsigned long)fh->read; 177 return efi_early->call(func, handle, size, addr); 178 } else { 179 efi_file_handle_32_t *fh = handle; 180 181 func = (unsigned long)fh->read; 182 return efi_early->call(func, handle, size, addr); 183 } 184} 185 186efi_status_t efi_file_close(void *handle) 187{ 188 if (efi_early->is64) { 189 efi_file_handle_64_t *fh = handle; 190 191 return efi_early->call((unsigned long)fh->close, handle); 192 } else { 193 efi_file_handle_32_t *fh = handle; 194 195 return efi_early->call((unsigned long)fh->close, handle); 196 } 197} 198 199static inline efi_status_t __open_volume32(void *__image, void **__fh) 200{ 201 efi_file_io_interface_t *io; 202 efi_loaded_image_32_t *image = __image; 203 efi_file_handle_32_t *fh; 204 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; 205 efi_status_t status; 206 void *handle = (void *)(unsigned long)image->device_handle; 207 unsigned long func; 208 209 status = efi_call_early(handle_protocol, handle, 210 &fs_proto, (void **)&io); 211 if (status != EFI_SUCCESS) { 212 efi_printk(sys_table, "Failed to handle fs_proto\n"); 213 return status; 214 } 215 216 func = (unsigned long)io->open_volume; 217 status = efi_early->call(func, io, &fh); 218 if (status != EFI_SUCCESS) 219 efi_printk(sys_table, "Failed to open volume\n"); 220 221 *__fh = fh; 222 return status; 223} 224 225static inline efi_status_t __open_volume64(void *__image, void **__fh) 226{ 227 efi_file_io_interface_t *io; 228 efi_loaded_image_64_t *image = __image; 229 efi_file_handle_64_t *fh; 230 efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID; 231 efi_status_t status; 232 void *handle = (void *)(unsigned long)image->device_handle; 233 unsigned long func; 234 235 status = efi_call_early(handle_protocol, handle, 236 &fs_proto, (void **)&io); 237 if (status != EFI_SUCCESS) { 238 efi_printk(sys_table, "Failed to handle fs_proto\n"); 239 return status; 240 } 241 242 func = (unsigned long)io->open_volume; 243 status = efi_early->call(func, io, &fh); 244 if (status != EFI_SUCCESS) 245 efi_printk(sys_table, "Failed to open volume\n"); 246 247 *__fh = fh; 248 return status; 249} 250 251efi_status_t 252efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) 253{ 254 if (efi_early->is64) 255 return __open_volume64(__image, __fh); 256 257 return __open_volume32(__image, __fh); 258} 259 260void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) 261{ 262 unsigned long output_string; 263 size_t offset; 264 265 if (efi_early->is64) { 266 struct efi_simple_text_output_protocol_64 *out; 267 u64 *func; 268 269 offset = offsetof(typeof(*out), output_string); 270 output_string = efi_early->text_output + offset; 271 out = (typeof(out))(unsigned long)efi_early->text_output; 272 func = (u64 *)output_string; 273 274 efi_early->call(*func, out, str); 275 } else { 276 struct efi_simple_text_output_protocol_32 *out; 277 u32 *func; 278 279 offset = offsetof(typeof(*out), output_string); 280 output_string = efi_early->text_output + offset; 281 out = (typeof(out))(unsigned long)efi_early->text_output; 282 func = (u32 *)output_string; 283 284 efi_early->call(*func, out, str); 285 } 286} 287 288#include "../../../../drivers/firmware/efi/libstub/efi-stub-helper.c" 289 290static void find_bits(unsigned long mask, u8 *pos, u8 *size) 291{ 292 u8 first, len; 293 294 first = 0; 295 len = 0; 296 297 if (mask) { 298 while (!(mask & 0x1)) { 299 mask = mask >> 1; 300 first++; 301 } 302 303 while (mask & 0x1) { 304 mask = mask >> 1; 305 len++; 306 } 307 } 308 309 *pos = first; 310 *size = len; 311} 312 313static efi_status_t 314__setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) 315{ 316 struct pci_setup_rom *rom = NULL; 317 efi_status_t status; 318 unsigned long size; 319 uint64_t attributes; 320 321 status = efi_early->call(pci->attributes, pci, 322 EfiPciIoAttributeOperationGet, 0, 0, 323 &attributes); 324 if (status != EFI_SUCCESS) 325 return status; 326 327 if (!pci->romimage || !pci->romsize) 328 return EFI_INVALID_PARAMETER; 329 330 size = pci->romsize + sizeof(*rom); 331 332 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); 333 if (status != EFI_SUCCESS) 334 return status; 335 336 memset(rom, 0, sizeof(*rom)); 337 338 rom->data.type = SETUP_PCI; 339 rom->data.len = size - sizeof(struct setup_data); 340 rom->data.next = 0; 341 rom->pcilen = pci->romsize; 342 *__rom = rom; 343 344 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 345 PCI_VENDOR_ID, 1, &(rom->vendor)); 346 347 if (status != EFI_SUCCESS) 348 goto free_struct; 349 350 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 351 PCI_DEVICE_ID, 1, &(rom->devid)); 352 353 if (status != EFI_SUCCESS) 354 goto free_struct; 355 356 status = efi_early->call(pci->get_location, pci, &(rom->segment), 357 &(rom->bus), &(rom->device), &(rom->function)); 358 359 if (status != EFI_SUCCESS) 360 goto free_struct; 361 362 memcpy(rom->romdata, pci->romimage, pci->romsize); 363 return status; 364 365free_struct: 366 efi_call_early(free_pool, rom); 367 return status; 368} 369 370static void 371setup_efi_pci32(struct boot_params *params, void **pci_handle, 372 unsigned long size) 373{ 374 efi_pci_io_protocol_32 *pci = NULL; 375 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; 376 u32 *handles = (u32 *)(unsigned long)pci_handle; 377 efi_status_t status; 378 unsigned long nr_pci; 379 struct setup_data *data; 380 int i; 381 382 data = (struct setup_data *)(unsigned long)params->hdr.setup_data; 383 384 while (data && data->next) 385 data = (struct setup_data *)(unsigned long)data->next; 386 387 nr_pci = size / sizeof(u32); 388 for (i = 0; i < nr_pci; i++) { 389 struct pci_setup_rom *rom = NULL; 390 u32 h = handles[i]; 391 392 status = efi_call_early(handle_protocol, h, 393 &pci_proto, (void **)&pci); 394 395 if (status != EFI_SUCCESS) 396 continue; 397 398 if (!pci) 399 continue; 400 401 status = __setup_efi_pci32(pci, &rom); 402 if (status != EFI_SUCCESS) 403 continue; 404 405 if (data) 406 data->next = (unsigned long)rom; 407 else 408 params->hdr.setup_data = (unsigned long)rom; 409 410 data = (struct setup_data *)rom; 411 412 } 413} 414 415static efi_status_t 416__setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) 417{ 418 struct pci_setup_rom *rom; 419 efi_status_t status; 420 unsigned long size; 421 uint64_t attributes; 422 423 status = efi_early->call(pci->attributes, pci, 424 EfiPciIoAttributeOperationGet, 0, 425 &attributes); 426 if (status != EFI_SUCCESS) 427 return status; 428 429 if (!pci->romimage || !pci->romsize) 430 return EFI_INVALID_PARAMETER; 431 432 size = pci->romsize + sizeof(*rom); 433 434 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); 435 if (status != EFI_SUCCESS) 436 return status; 437 438 rom->data.type = SETUP_PCI; 439 rom->data.len = size - sizeof(struct setup_data); 440 rom->data.next = 0; 441 rom->pcilen = pci->romsize; 442 *__rom = rom; 443 444 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 445 PCI_VENDOR_ID, 1, &(rom->vendor)); 446 447 if (status != EFI_SUCCESS) 448 goto free_struct; 449 450 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 451 PCI_DEVICE_ID, 1, &(rom->devid)); 452 453 if (status != EFI_SUCCESS) 454 goto free_struct; 455 456 status = efi_early->call(pci->get_location, pci, &(rom->segment), 457 &(rom->bus), &(rom->device), &(rom->function)); 458 459 if (status != EFI_SUCCESS) 460 goto free_struct; 461 462 memcpy(rom->romdata, pci->romimage, pci->romsize); 463 return status; 464 465free_struct: 466 efi_call_early(free_pool, rom); 467 return status; 468 469} 470 471static void 472setup_efi_pci64(struct boot_params *params, void **pci_handle, 473 unsigned long size) 474{ 475 efi_pci_io_protocol_64 *pci = NULL; 476 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; 477 u64 *handles = (u64 *)(unsigned long)pci_handle; 478 efi_status_t status; 479 unsigned long nr_pci; 480 struct setup_data *data; 481 int i; 482 483 data = (struct setup_data *)(unsigned long)params->hdr.setup_data; 484 485 while (data && data->next) 486 data = (struct setup_data *)(unsigned long)data->next; 487 488 nr_pci = size / sizeof(u64); 489 for (i = 0; i < nr_pci; i++) { 490 struct pci_setup_rom *rom = NULL; 491 u64 h = handles[i]; 492 493 status = efi_call_early(handle_protocol, h, 494 &pci_proto, (void **)&pci); 495 496 if (status != EFI_SUCCESS) 497 continue; 498 499 if (!pci) 500 continue; 501 502 status = __setup_efi_pci64(pci, &rom); 503 if (status != EFI_SUCCESS) 504 continue; 505 506 if (data) 507 data->next = (unsigned long)rom; 508 else 509 params->hdr.setup_data = (unsigned long)rom; 510 511 data = (struct setup_data *)rom; 512 513 } 514} 515 516/* 517 * There's no way to return an informative status from this function, 518 * because any analysis (and printing of error messages) needs to be 519 * done directly at the EFI function call-site. 520 * 521 * For example, EFI_INVALID_PARAMETER could indicate a bug or maybe we 522 * just didn't find any PCI devices, but there's no way to tell outside 523 * the context of the call. 524 */ 525static void setup_efi_pci(struct boot_params *params) 526{ 527 efi_status_t status; 528 void **pci_handle = NULL; 529 efi_guid_t pci_proto = EFI_PCI_IO_PROTOCOL_GUID; 530 unsigned long size = 0; 531 532 status = efi_call_early(locate_handle, 533 EFI_LOCATE_BY_PROTOCOL, 534 &pci_proto, NULL, &size, pci_handle); 535 536 if (status == EFI_BUFFER_TOO_SMALL) { 537 status = efi_call_early(allocate_pool, 538 EFI_LOADER_DATA, 539 size, (void **)&pci_handle); 540 541 if (status != EFI_SUCCESS) 542 return; 543 544 status = efi_call_early(locate_handle, 545 EFI_LOCATE_BY_PROTOCOL, &pci_proto, 546 NULL, &size, pci_handle); 547 } 548 549 if (status != EFI_SUCCESS) 550 goto free_handle; 551 552 if (efi_early->is64) 553 setup_efi_pci64(params, pci_handle, size); 554 else 555 setup_efi_pci32(params, pci_handle, size); 556 557free_handle: 558 efi_call_early(free_pool, pci_handle); 559} 560 561static void 562setup_pixel_info(struct screen_info *si, u32 pixels_per_scan_line, 563 struct efi_pixel_bitmask pixel_info, int pixel_format) 564{ 565 if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) { 566 si->lfb_depth = 32; 567 si->lfb_linelength = pixels_per_scan_line * 4; 568 si->red_size = 8; 569 si->red_pos = 0; 570 si->green_size = 8; 571 si->green_pos = 8; 572 si->blue_size = 8; 573 si->blue_pos = 16; 574 si->rsvd_size = 8; 575 si->rsvd_pos = 24; 576 } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) { 577 si->lfb_depth = 32; 578 si->lfb_linelength = pixels_per_scan_line * 4; 579 si->red_size = 8; 580 si->red_pos = 16; 581 si->green_size = 8; 582 si->green_pos = 8; 583 si->blue_size = 8; 584 si->blue_pos = 0; 585 si->rsvd_size = 8; 586 si->rsvd_pos = 24; 587 } else if (pixel_format == PIXEL_BIT_MASK) { 588 find_bits(pixel_info.red_mask, &si->red_pos, &si->red_size); 589 find_bits(pixel_info.green_mask, &si->green_pos, 590 &si->green_size); 591 find_bits(pixel_info.blue_mask, &si->blue_pos, &si->blue_size); 592 find_bits(pixel_info.reserved_mask, &si->rsvd_pos, 593 &si->rsvd_size); 594 si->lfb_depth = si->red_size + si->green_size + 595 si->blue_size + si->rsvd_size; 596 si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8; 597 } else { 598 si->lfb_depth = 4; 599 si->lfb_linelength = si->lfb_width / 2; 600 si->red_size = 0; 601 si->red_pos = 0; 602 si->green_size = 0; 603 si->green_pos = 0; 604 si->blue_size = 0; 605 si->blue_pos = 0; 606 si->rsvd_size = 0; 607 si->rsvd_pos = 0; 608 } 609} 610 611static efi_status_t 612__gop_query32(struct efi_graphics_output_protocol_32 *gop32, 613 struct efi_graphics_output_mode_info **info, 614 unsigned long *size, u32 *fb_base) 615{ 616 struct efi_graphics_output_protocol_mode_32 *mode; 617 efi_status_t status; 618 unsigned long m; 619 620 m = gop32->mode; 621 mode = (struct efi_graphics_output_protocol_mode_32 *)m; 622 623 status = efi_early->call(gop32->query_mode, gop32, 624 mode->mode, size, info); 625 if (status != EFI_SUCCESS) 626 return status; 627 628 *fb_base = mode->frame_buffer_base; 629 return status; 630} 631 632static efi_status_t 633setup_gop32(struct screen_info *si, efi_guid_t *proto, 634 unsigned long size, void **gop_handle) 635{ 636 struct efi_graphics_output_protocol_32 *gop32, *first_gop; 637 unsigned long nr_gops; 638 u16 width, height; 639 u32 pixels_per_scan_line; 640 u32 fb_base; 641 struct efi_pixel_bitmask pixel_info; 642 int pixel_format; 643 efi_status_t status; 644 u32 *handles = (u32 *)(unsigned long)gop_handle; 645 int i; 646 647 first_gop = NULL; 648 gop32 = NULL; 649 650 nr_gops = size / sizeof(u32); 651 for (i = 0; i < nr_gops; i++) { 652 struct efi_graphics_output_mode_info *info = NULL; 653 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; 654 bool conout_found = false; 655 void *dummy = NULL; 656 u32 h = handles[i]; 657 658 status = efi_call_early(handle_protocol, h, 659 proto, (void **)&gop32); 660 if (status != EFI_SUCCESS) 661 continue; 662 663 status = efi_call_early(handle_protocol, h, 664 &conout_proto, &dummy); 665 if (status == EFI_SUCCESS) 666 conout_found = true; 667 668 status = __gop_query32(gop32, &info, &size, &fb_base); 669 if (status == EFI_SUCCESS && (!first_gop || conout_found)) { 670 /* 671 * Systems that use the UEFI Console Splitter may 672 * provide multiple GOP devices, not all of which are 673 * backed by real hardware. The workaround is to search 674 * for a GOP implementing the ConOut protocol, and if 675 * one isn't found, to just fall back to the first GOP. 676 */ 677 width = info->horizontal_resolution; 678 height = info->vertical_resolution; 679 pixel_format = info->pixel_format; 680 pixel_info = info->pixel_information; 681 pixels_per_scan_line = info->pixels_per_scan_line; 682 683 /* 684 * Once we've found a GOP supporting ConOut, 685 * don't bother looking any further. 686 */ 687 first_gop = gop32; 688 if (conout_found) 689 break; 690 } 691 } 692 693 /* Did we find any GOPs? */ 694 if (!first_gop) 695 goto out; 696 697 /* EFI framebuffer */ 698 si->orig_video_isVGA = VIDEO_TYPE_EFI; 699 700 si->lfb_width = width; 701 si->lfb_height = height; 702 si->lfb_base = fb_base; 703 si->pages = 1; 704 705 setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); 706 707 si->lfb_size = si->lfb_linelength * si->lfb_height; 708 709 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; 710out: 711 return status; 712} 713 714static efi_status_t 715__gop_query64(struct efi_graphics_output_protocol_64 *gop64, 716 struct efi_graphics_output_mode_info **info, 717 unsigned long *size, u32 *fb_base) 718{ 719 struct efi_graphics_output_protocol_mode_64 *mode; 720 efi_status_t status; 721 unsigned long m; 722 723 m = gop64->mode; 724 mode = (struct efi_graphics_output_protocol_mode_64 *)m; 725 726 status = efi_early->call(gop64->query_mode, gop64, 727 mode->mode, size, info); 728 if (status != EFI_SUCCESS) 729 return status; 730 731 *fb_base = mode->frame_buffer_base; 732 return status; 733} 734 735static efi_status_t 736setup_gop64(struct screen_info *si, efi_guid_t *proto, 737 unsigned long size, void **gop_handle) 738{ 739 struct efi_graphics_output_protocol_64 *gop64, *first_gop; 740 unsigned long nr_gops; 741 u16 width, height; 742 u32 pixels_per_scan_line; 743 u32 fb_base; 744 struct efi_pixel_bitmask pixel_info; 745 int pixel_format; 746 efi_status_t status; 747 u64 *handles = (u64 *)(unsigned long)gop_handle; 748 int i; 749 750 first_gop = NULL; 751 gop64 = NULL; 752 753 nr_gops = size / sizeof(u64); 754 for (i = 0; i < nr_gops; i++) { 755 struct efi_graphics_output_mode_info *info = NULL; 756 efi_guid_t conout_proto = EFI_CONSOLE_OUT_DEVICE_GUID; 757 bool conout_found = false; 758 void *dummy = NULL; 759 u64 h = handles[i]; 760 761 status = efi_call_early(handle_protocol, h, 762 proto, (void **)&gop64); 763 if (status != EFI_SUCCESS) 764 continue; 765 766 status = efi_call_early(handle_protocol, h, 767 &conout_proto, &dummy); 768 if (status == EFI_SUCCESS) 769 conout_found = true; 770 771 status = __gop_query64(gop64, &info, &size, &fb_base); 772 if (status == EFI_SUCCESS && (!first_gop || conout_found)) { 773 /* 774 * Systems that use the UEFI Console Splitter may 775 * provide multiple GOP devices, not all of which are 776 * backed by real hardware. The workaround is to search 777 * for a GOP implementing the ConOut protocol, and if 778 * one isn't found, to just fall back to the first GOP. 779 */ 780 width = info->horizontal_resolution; 781 height = info->vertical_resolution; 782 pixel_format = info->pixel_format; 783 pixel_info = info->pixel_information; 784 pixels_per_scan_line = info->pixels_per_scan_line; 785 786 /* 787 * Once we've found a GOP supporting ConOut, 788 * don't bother looking any further. 789 */ 790 first_gop = gop64; 791 if (conout_found) 792 break; 793 } 794 } 795 796 /* Did we find any GOPs? */ 797 if (!first_gop) 798 goto out; 799 800 /* EFI framebuffer */ 801 si->orig_video_isVGA = VIDEO_TYPE_EFI; 802 803 si->lfb_width = width; 804 si->lfb_height = height; 805 si->lfb_base = fb_base; 806 si->pages = 1; 807 808 setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); 809 810 si->lfb_size = si->lfb_linelength * si->lfb_height; 811 812 si->capabilities |= VIDEO_CAPABILITY_SKIP_QUIRKS; 813out: 814 return status; 815} 816 817/* 818 * See if we have Graphics Output Protocol 819 */ 820static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto, 821 unsigned long size) 822{ 823 efi_status_t status; 824 void **gop_handle = NULL; 825 826 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 827 size, (void **)&gop_handle); 828 if (status != EFI_SUCCESS) 829 return status; 830 831 status = efi_call_early(locate_handle, 832 EFI_LOCATE_BY_PROTOCOL, 833 proto, NULL, &size, gop_handle); 834 if (status != EFI_SUCCESS) 835 goto free_handle; 836 837 if (efi_early->is64) 838 status = setup_gop64(si, proto, size, gop_handle); 839 else 840 status = setup_gop32(si, proto, size, gop_handle); 841 842free_handle: 843 efi_call_early(free_pool, gop_handle); 844 return status; 845} 846 847static efi_status_t 848setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height) 849{ 850 struct efi_uga_draw_protocol *uga = NULL, *first_uga; 851 efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID; 852 unsigned long nr_ugas; 853 u32 *handles = (u32 *)uga_handle;; 854 efi_status_t status; 855 int i; 856 857 first_uga = NULL; 858 nr_ugas = size / sizeof(u32); 859 for (i = 0; i < nr_ugas; i++) { 860 efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID; 861 u32 w, h, depth, refresh; 862 void *pciio; 863 u32 handle = handles[i]; 864 865 status = efi_call_early(handle_protocol, handle, 866 &uga_proto, (void **)&uga); 867 if (status != EFI_SUCCESS) 868 continue; 869 870 efi_call_early(handle_protocol, handle, &pciio_proto, &pciio); 871 872 status = efi_early->call((unsigned long)uga->get_mode, uga, 873 &w, &h, &depth, &refresh); 874 if (status == EFI_SUCCESS && (!first_uga || pciio)) { 875 *width = w; 876 *height = h; 877 878 /* 879 * Once we've found a UGA supporting PCIIO, 880 * don't bother looking any further. 881 */ 882 if (pciio) 883 break; 884 885 first_uga = uga; 886 } 887 } 888 889 return status; 890} 891 892static efi_status_t 893setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height) 894{ 895 struct efi_uga_draw_protocol *uga = NULL, *first_uga; 896 efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID; 897 unsigned long nr_ugas; 898 u64 *handles = (u64 *)uga_handle;; 899 efi_status_t status; 900 int i; 901 902 first_uga = NULL; 903 nr_ugas = size / sizeof(u64); 904 for (i = 0; i < nr_ugas; i++) { 905 efi_guid_t pciio_proto = EFI_PCI_IO_PROTOCOL_GUID; 906 u32 w, h, depth, refresh; 907 void *pciio; 908 u64 handle = handles[i]; 909 910 status = efi_call_early(handle_protocol, handle, 911 &uga_proto, (void **)&uga); 912 if (status != EFI_SUCCESS) 913 continue; 914 915 efi_call_early(handle_protocol, handle, &pciio_proto, &pciio); 916 917 status = efi_early->call((unsigned long)uga->get_mode, uga, 918 &w, &h, &depth, &refresh); 919 if (status == EFI_SUCCESS && (!first_uga || pciio)) { 920 *width = w; 921 *height = h; 922 923 /* 924 * Once we've found a UGA supporting PCIIO, 925 * don't bother looking any further. 926 */ 927 if (pciio) 928 break; 929 930 first_uga = uga; 931 } 932 } 933 934 return status; 935} 936 937/* 938 * See if we have Universal Graphics Adapter (UGA) protocol 939 */ 940static efi_status_t setup_uga(struct screen_info *si, efi_guid_t *uga_proto, 941 unsigned long size) 942{ 943 efi_status_t status; 944 u32 width, height; 945 void **uga_handle = NULL; 946 947 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 948 size, (void **)&uga_handle); 949 if (status != EFI_SUCCESS) 950 return status; 951 952 status = efi_call_early(locate_handle, 953 EFI_LOCATE_BY_PROTOCOL, 954 uga_proto, NULL, &size, uga_handle); 955 if (status != EFI_SUCCESS) 956 goto free_handle; 957 958 height = 0; 959 width = 0; 960 961 if (efi_early->is64) 962 status = setup_uga64(uga_handle, size, &width, &height); 963 else 964 status = setup_uga32(uga_handle, size, &width, &height); 965 966 if (!width && !height) 967 goto free_handle; 968 969 /* EFI framebuffer */ 970 si->orig_video_isVGA = VIDEO_TYPE_EFI; 971 972 si->lfb_depth = 32; 973 si->lfb_width = width; 974 si->lfb_height = height; 975 976 si->red_size = 8; 977 si->red_pos = 16; 978 si->green_size = 8; 979 si->green_pos = 8; 980 si->blue_size = 8; 981 si->blue_pos = 0; 982 si->rsvd_size = 8; 983 si->rsvd_pos = 24; 984 985free_handle: 986 efi_call_early(free_pool, uga_handle); 987 return status; 988} 989 990void setup_graphics(struct boot_params *boot_params) 991{ 992 efi_guid_t graphics_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; 993 struct screen_info *si; 994 efi_guid_t uga_proto = EFI_UGA_PROTOCOL_GUID; 995 efi_status_t status; 996 unsigned long size; 997 void **gop_handle = NULL; 998 void **uga_handle = NULL; 999 1000 si = &boot_params->screen_info; 1001 memset(si, 0, sizeof(*si)); 1002 1003 size = 0; 1004 status = efi_call_early(locate_handle, 1005 EFI_LOCATE_BY_PROTOCOL, 1006 &graphics_proto, NULL, &size, gop_handle); 1007 if (status == EFI_BUFFER_TOO_SMALL) 1008 status = setup_gop(si, &graphics_proto, size); 1009 1010 if (status != EFI_SUCCESS) { 1011 size = 0; 1012 status = efi_call_early(locate_handle, 1013 EFI_LOCATE_BY_PROTOCOL, 1014 &uga_proto, NULL, &size, uga_handle); 1015 if (status == EFI_BUFFER_TOO_SMALL) 1016 setup_uga(si, &uga_proto, size); 1017 } 1018} 1019 1020/* 1021 * Because the x86 boot code expects to be passed a boot_params we 1022 * need to create one ourselves (usually the bootloader would create 1023 * one for us). 1024 * 1025 * The caller is responsible for filling out ->code32_start in the 1026 * returned boot_params. 1027 */ 1028struct boot_params *make_boot_params(struct efi_config *c) 1029{ 1030 struct boot_params *boot_params; 1031 struct sys_desc_table *sdt; 1032 struct apm_bios_info *bi; 1033 struct setup_header *hdr; 1034 struct efi_info *efi; 1035 efi_loaded_image_t *image; 1036 void *options, *handle; 1037 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; 1038 int options_size = 0; 1039 efi_status_t status; 1040 char *cmdline_ptr; 1041 u16 *s2; 1042 u8 *s1; 1043 int i; 1044 unsigned long ramdisk_addr; 1045 unsigned long ramdisk_size; 1046 1047 efi_early = c; 1048 sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; 1049 handle = (void *)(unsigned long)efi_early->image_handle; 1050 1051 /* Check if we were booted by the EFI firmware */ 1052 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 1053 return NULL; 1054 1055 if (efi_early->is64) 1056 setup_boot_services64(efi_early); 1057 else 1058 setup_boot_services32(efi_early); 1059 1060 status = efi_call_early(handle_protocol, handle, 1061 &proto, (void *)&image); 1062 if (status != EFI_SUCCESS) { 1063 efi_printk(sys_table, "Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); 1064 return NULL; 1065 } 1066 1067 status = efi_low_alloc(sys_table, 0x4000, 1, 1068 (unsigned long *)&boot_params); 1069 if (status != EFI_SUCCESS) { 1070 efi_printk(sys_table, "Failed to alloc lowmem for boot params\n"); 1071 return NULL; 1072 } 1073 1074 memset(boot_params, 0x0, 0x4000); 1075 1076 hdr = &boot_params->hdr; 1077 efi = &boot_params->efi_info; 1078 bi = &boot_params->apm_bios_info; 1079 sdt = &boot_params->sys_desc_table; 1080 1081 /* Copy the second sector to boot_params */ 1082 memcpy(&hdr->jump, image->image_base + 512, 512); 1083 1084 /* 1085 * Fill out some of the header fields ourselves because the 1086 * EFI firmware loader doesn't load the first sector. 1087 */ 1088 hdr->root_flags = 1; 1089 hdr->vid_mode = 0xffff; 1090 hdr->boot_flag = 0xAA55; 1091 1092 hdr->type_of_loader = 0x21; 1093 1094 /* Convert unicode cmdline to ascii */ 1095 cmdline_ptr = efi_convert_cmdline(sys_table, image, &options_size); 1096 if (!cmdline_ptr) 1097 goto fail; 1098 hdr->cmd_line_ptr = (unsigned long)cmdline_ptr; 1099 1100 hdr->ramdisk_image = 0; 1101 hdr->ramdisk_size = 0; 1102 1103 /* Clear APM BIOS info */ 1104 memset(bi, 0, sizeof(*bi)); 1105 1106 memset(sdt, 0, sizeof(*sdt)); 1107 1108 status = handle_cmdline_files(sys_table, image, 1109 (char *)(unsigned long)hdr->cmd_line_ptr, 1110 "initrd=", hdr->initrd_addr_max, 1111 &ramdisk_addr, &ramdisk_size); 1112 1113 if (status != EFI_SUCCESS && 1114 hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) { 1115 efi_printk(sys_table, "Trying to load files to higher address\n"); 1116 status = handle_cmdline_files(sys_table, image, 1117 (char *)(unsigned long)hdr->cmd_line_ptr, 1118 "initrd=", -1UL, 1119 &ramdisk_addr, &ramdisk_size); 1120 } 1121 1122 if (status != EFI_SUCCESS) 1123 goto fail2; 1124 hdr->ramdisk_image = ramdisk_addr & 0xffffffff; 1125 hdr->ramdisk_size = ramdisk_size & 0xffffffff; 1126 boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32; 1127 boot_params->ext_ramdisk_size = (u64)ramdisk_size >> 32; 1128 1129 return boot_params; 1130fail2: 1131 efi_free(sys_table, options_size, hdr->cmd_line_ptr); 1132fail: 1133 efi_free(sys_table, 0x4000, (unsigned long)boot_params); 1134 return NULL; 1135} 1136 1137static void add_e820ext(struct boot_params *params, 1138 struct setup_data *e820ext, u32 nr_entries) 1139{ 1140 struct setup_data *data; 1141 efi_status_t status; 1142 unsigned long size; 1143 1144 e820ext->type = SETUP_E820_EXT; 1145 e820ext->len = nr_entries * sizeof(struct e820entry); 1146 e820ext->next = 0; 1147 1148 data = (struct setup_data *)(unsigned long)params->hdr.setup_data; 1149 1150 while (data && data->next) 1151 data = (struct setup_data *)(unsigned long)data->next; 1152 1153 if (data) 1154 data->next = (unsigned long)e820ext; 1155 else 1156 params->hdr.setup_data = (unsigned long)e820ext; 1157} 1158 1159static efi_status_t setup_e820(struct boot_params *params, 1160 struct setup_data *e820ext, u32 e820ext_size) 1161{ 1162 struct e820entry *e820_map = &params->e820_map[0]; 1163 struct efi_info *efi = &params->efi_info; 1164 struct e820entry *prev = NULL; 1165 u32 nr_entries; 1166 u32 nr_desc; 1167 int i; 1168 1169 nr_entries = 0; 1170 nr_desc = efi->efi_memmap_size / efi->efi_memdesc_size; 1171 1172 for (i = 0; i < nr_desc; i++) { 1173 efi_memory_desc_t *d; 1174 unsigned int e820_type = 0; 1175 unsigned long m = efi->efi_memmap; 1176 1177 d = (efi_memory_desc_t *)(m + (i * efi->efi_memdesc_size)); 1178 switch (d->type) { 1179 case EFI_RESERVED_TYPE: 1180 case EFI_RUNTIME_SERVICES_CODE: 1181 case EFI_RUNTIME_SERVICES_DATA: 1182 case EFI_MEMORY_MAPPED_IO: 1183 case EFI_MEMORY_MAPPED_IO_PORT_SPACE: 1184 case EFI_PAL_CODE: 1185 e820_type = E820_RESERVED; 1186 break; 1187 1188 case EFI_UNUSABLE_MEMORY: 1189 e820_type = E820_UNUSABLE; 1190 break; 1191 1192 case EFI_ACPI_RECLAIM_MEMORY: 1193 e820_type = E820_ACPI; 1194 break; 1195 1196 case EFI_LOADER_CODE: 1197 case EFI_LOADER_DATA: 1198 case EFI_BOOT_SERVICES_CODE: 1199 case EFI_BOOT_SERVICES_DATA: 1200 case EFI_CONVENTIONAL_MEMORY: 1201 e820_type = E820_RAM; 1202 break; 1203 1204 case EFI_ACPI_MEMORY_NVS: 1205 e820_type = E820_NVS; 1206 break; 1207 1208 default: 1209 continue; 1210 } 1211 1212 /* Merge adjacent mappings */ 1213 if (prev && prev->type == e820_type && 1214 (prev->addr + prev->size) == d->phys_addr) { 1215 prev->size += d->num_pages << 12; 1216 continue; 1217 } 1218 1219 if (nr_entries == ARRAY_SIZE(params->e820_map)) { 1220 u32 need = (nr_desc - i) * sizeof(struct e820entry) + 1221 sizeof(struct setup_data); 1222 1223 if (!e820ext || e820ext_size < need) 1224 return EFI_BUFFER_TOO_SMALL; 1225 1226 /* boot_params map full, switch to e820 extended */ 1227 e820_map = (struct e820entry *)e820ext->data; 1228 } 1229 1230 e820_map->addr = d->phys_addr; 1231 e820_map->size = d->num_pages << PAGE_SHIFT; 1232 e820_map->type = e820_type; 1233 prev = e820_map++; 1234 nr_entries++; 1235 } 1236 1237 if (nr_entries > ARRAY_SIZE(params->e820_map)) { 1238 u32 nr_e820ext = nr_entries - ARRAY_SIZE(params->e820_map); 1239 1240 add_e820ext(params, e820ext, nr_e820ext); 1241 nr_entries -= nr_e820ext; 1242 } 1243 1244 params->e820_entries = (u8)nr_entries; 1245 1246 return EFI_SUCCESS; 1247} 1248 1249static efi_status_t alloc_e820ext(u32 nr_desc, struct setup_data **e820ext, 1250 u32 *e820ext_size) 1251{ 1252 efi_status_t status; 1253 unsigned long size; 1254 1255 size = sizeof(struct setup_data) + 1256 sizeof(struct e820entry) * nr_desc; 1257 1258 if (*e820ext) { 1259 efi_call_early(free_pool, *e820ext); 1260 *e820ext = NULL; 1261 *e820ext_size = 0; 1262 } 1263 1264 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 1265 size, (void **)e820ext); 1266 if (status == EFI_SUCCESS) 1267 *e820ext_size = size; 1268 1269 return status; 1270} 1271 1272static efi_status_t exit_boot(struct boot_params *boot_params, 1273 void *handle, bool is64) 1274{ 1275 struct efi_info *efi = &boot_params->efi_info; 1276 unsigned long map_sz, key, desc_size; 1277 efi_memory_desc_t *mem_map; 1278 struct setup_data *e820ext; 1279 const char *signature; 1280 __u32 e820ext_size; 1281 __u32 nr_desc, prev_nr_desc; 1282 efi_status_t status; 1283 __u32 desc_version; 1284 bool called_exit = false; 1285 u8 nr_entries; 1286 int i; 1287 1288 nr_desc = 0; 1289 e820ext = NULL; 1290 e820ext_size = 0; 1291 1292get_map: 1293 status = efi_get_memory_map(sys_table, &mem_map, &map_sz, &desc_size, 1294 &desc_version, &key); 1295 1296 if (status != EFI_SUCCESS) 1297 return status; 1298 1299 prev_nr_desc = nr_desc; 1300 nr_desc = map_sz / desc_size; 1301 if (nr_desc > prev_nr_desc && 1302 nr_desc > ARRAY_SIZE(boot_params->e820_map)) { 1303 u32 nr_e820ext = nr_desc - ARRAY_SIZE(boot_params->e820_map); 1304 1305 status = alloc_e820ext(nr_e820ext, &e820ext, &e820ext_size); 1306 if (status != EFI_SUCCESS) 1307 goto free_mem_map; 1308 1309 efi_call_early(free_pool, mem_map); 1310 goto get_map; /* Allocated memory, get map again */ 1311 } 1312 1313 signature = is64 ? EFI64_LOADER_SIGNATURE : EFI32_LOADER_SIGNATURE; 1314 memcpy(&efi->efi_loader_signature, signature, sizeof(__u32)); 1315 1316 efi->efi_systab = (unsigned long)sys_table; 1317 efi->efi_memdesc_size = desc_size; 1318 efi->efi_memdesc_version = desc_version; 1319 efi->efi_memmap = (unsigned long)mem_map; 1320 efi->efi_memmap_size = map_sz; 1321 1322#ifdef CONFIG_X86_64 1323 efi->efi_systab_hi = (unsigned long)sys_table >> 32; 1324 efi->efi_memmap_hi = (unsigned long)mem_map >> 32; 1325#endif 1326 1327 /* Might as well exit boot services now */ 1328 status = efi_call_early(exit_boot_services, handle, key); 1329 if (status != EFI_SUCCESS) { 1330 /* 1331 * ExitBootServices() will fail if any of the event 1332 * handlers change the memory map. In which case, we 1333 * must be prepared to retry, but only once so that 1334 * we're guaranteed to exit on repeated failures instead 1335 * of spinning forever. 1336 */ 1337 if (called_exit) 1338 goto free_mem_map; 1339 1340 called_exit = true; 1341 efi_call_early(free_pool, mem_map); 1342 goto get_map; 1343 } 1344 1345 /* Historic? */ 1346 boot_params->alt_mem_k = 32 * 1024; 1347 1348 status = setup_e820(boot_params, e820ext, e820ext_size); 1349 if (status != EFI_SUCCESS) 1350 return status; 1351 1352 return EFI_SUCCESS; 1353 1354free_mem_map: 1355 efi_call_early(free_pool, mem_map); 1356 return status; 1357} 1358 1359/* 1360 * On success we return a pointer to a boot_params structure, and NULL 1361 * on failure. 1362 */ 1363struct boot_params *efi_main(struct efi_config *c, 1364 struct boot_params *boot_params) 1365{ 1366 struct desc_ptr *gdt = NULL; 1367 efi_loaded_image_t *image; 1368 struct setup_header *hdr = &boot_params->hdr; 1369 efi_status_t status; 1370 struct desc_struct *desc; 1371 void *handle; 1372 efi_system_table_t *_table; 1373 bool is64; 1374 1375 efi_early = c; 1376 1377 _table = (efi_system_table_t *)(unsigned long)efi_early->table; 1378 handle = (void *)(unsigned long)efi_early->image_handle; 1379 is64 = efi_early->is64; 1380 1381 sys_table = _table; 1382 1383 /* Check if we were booted by the EFI firmware */ 1384 if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) 1385 goto fail; 1386 1387 if (is64) 1388 setup_boot_services64(efi_early); 1389 else 1390 setup_boot_services32(efi_early); 1391 1392 setup_graphics(boot_params); 1393 1394 setup_efi_pci(boot_params); 1395 1396 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, 1397 sizeof(*gdt), (void **)&gdt); 1398 if (status != EFI_SUCCESS) { 1399 efi_printk(sys_table, "Failed to alloc mem for gdt structure\n"); 1400 goto fail; 1401 } 1402 1403 gdt->size = 0x800; 1404 status = efi_low_alloc(sys_table, gdt->size, 8, 1405 (unsigned long *)&gdt->address); 1406 if (status != EFI_SUCCESS) { 1407 efi_printk(sys_table, "Failed to alloc mem for gdt\n"); 1408 goto fail; 1409 } 1410 1411 /* 1412 * If the kernel isn't already loaded at the preferred load 1413 * address, relocate it. 1414 */ 1415 if (hdr->pref_address != hdr->code32_start) { 1416 unsigned long bzimage_addr = hdr->code32_start; 1417 status = efi_relocate_kernel(sys_table, &bzimage_addr, 1418 hdr->init_size, hdr->init_size, 1419 hdr->pref_address, 1420 hdr->kernel_alignment); 1421 if (status != EFI_SUCCESS) { 1422 efi_printk(sys_table, "efi_relocate_kernel() failed!\n"); 1423 goto fail; 1424 } 1425 1426 hdr->pref_address = hdr->code32_start; 1427 hdr->code32_start = bzimage_addr; 1428 } 1429 1430 status = exit_boot(boot_params, handle, is64); 1431 if (status != EFI_SUCCESS) { 1432 efi_printk(sys_table, "exit_boot() failed!\n"); 1433 goto fail; 1434 } 1435 1436 memset((char *)gdt->address, 0x0, gdt->size); 1437 desc = (struct desc_struct *)gdt->address; 1438 1439 /* The first GDT is a dummy and the second is unused. */ 1440 desc += 2; 1441 1442 desc->limit0 = 0xffff; 1443 desc->base0 = 0x0000; 1444 desc->base1 = 0x0000; 1445 desc->type = SEG_TYPE_CODE | SEG_TYPE_EXEC_READ; 1446 desc->s = DESC_TYPE_CODE_DATA; 1447 desc->dpl = 0; 1448 desc->p = 1; 1449 desc->limit = 0xf; 1450 desc->avl = 0; 1451 desc->l = 0; 1452 desc->d = SEG_OP_SIZE_32BIT; 1453 desc->g = SEG_GRANULARITY_4KB; 1454 desc->base2 = 0x00; 1455 1456 desc++; 1457 desc->limit0 = 0xffff; 1458 desc->base0 = 0x0000; 1459 desc->base1 = 0x0000; 1460 desc->type = SEG_TYPE_DATA | SEG_TYPE_READ_WRITE; 1461 desc->s = DESC_TYPE_CODE_DATA; 1462 desc->dpl = 0; 1463 desc->p = 1; 1464 desc->limit = 0xf; 1465 desc->avl = 0; 1466 desc->l = 0; 1467 desc->d = SEG_OP_SIZE_32BIT; 1468 desc->g = SEG_GRANULARITY_4KB; 1469 desc->base2 = 0x00; 1470 1471#ifdef CONFIG_X86_64 1472 /* Task segment value */ 1473 desc++; 1474 desc->limit0 = 0x0000; 1475 desc->base0 = 0x0000; 1476 desc->base1 = 0x0000; 1477 desc->type = SEG_TYPE_TSS; 1478 desc->s = 0; 1479 desc->dpl = 0; 1480 desc->p = 1; 1481 desc->limit = 0x0; 1482 desc->avl = 0; 1483 desc->l = 0; 1484 desc->d = 0; 1485 desc->g = SEG_GRANULARITY_4KB; 1486 desc->base2 = 0x00; 1487#endif /* CONFIG_X86_64 */ 1488 1489 asm volatile("cli"); 1490 asm volatile ("lgdt %0" : : "m" (*gdt)); 1491 1492 return boot_params; 1493fail: 1494 efi_printk(sys_table, "efi_main() failed!\n"); 1495 return NULL; 1496}