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