linux/drivers/firmware/efi/libstub/efi-stub-helper.c
<<
>>
Prefs
   1/*
   2 * Helper functions used by the EFI stub on multiple
   3 * architectures. This should be #included by the EFI stub
   4 * implementation files.
   5 *
   6 * Copyright 2011 Intel Corporation; author Matt Fleming
   7 *
   8 * This file is part of the Linux kernel, and is made available
   9 * under the terms of the GNU General Public License version 2.
  10 *
  11 */
  12
  13#include <linux/efi.h>
  14#include <asm/efi.h>
  15
  16#include "efistub.h"
  17
  18/*
  19 * Some firmware implementations have problems reading files in one go.
  20 * A read chunk size of 1MB seems to work for most platforms.
  21 *
  22 * Unfortunately, reading files in chunks triggers *other* bugs on some
  23 * platforms, so we provide a way to disable this workaround, which can
  24 * be done by passing "efi=nochunk" on the EFI boot stub command line.
  25 *
  26 * If you experience issues with initrd images being corrupt it's worth
  27 * trying efi=nochunk, but chunking is enabled by default because there
  28 * are far more machines that require the workaround than those that
  29 * break with it enabled.
  30 */
  31#define EFI_READ_CHUNK_SIZE     (1024 * 1024)
  32
  33static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
  34
  35/*
  36 * Allow the platform to override the allocation granularity: this allows
  37 * systems that have the capability to run with a larger page size to deal
  38 * with the allocations for initrd and fdt more efficiently.
  39 */
  40#ifndef EFI_ALLOC_ALIGN
  41#define EFI_ALLOC_ALIGN         EFI_PAGE_SIZE
  42#endif
  43
  44struct file_info {
  45        efi_file_handle_t *handle;
  46        u64 size;
  47};
  48
  49void efi_printk(efi_system_table_t *sys_table_arg, char *str)
  50{
  51        char *s8;
  52
  53        for (s8 = str; *s8; s8++) {
  54                efi_char16_t ch[2] = { 0 };
  55
  56                ch[0] = *s8;
  57                if (*s8 == '\n') {
  58                        efi_char16_t nl[2] = { '\r', 0 };
  59                        efi_char16_printk(sys_table_arg, nl);
  60                }
  61
  62                efi_char16_printk(sys_table_arg, ch);
  63        }
  64}
  65
  66efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
  67                                efi_memory_desc_t **map,
  68                                unsigned long *map_size,
  69                                unsigned long *desc_size,
  70                                u32 *desc_ver,
  71                                unsigned long *key_ptr)
  72{
  73        efi_memory_desc_t *m = NULL;
  74        efi_status_t status;
  75        unsigned long key;
  76        u32 desc_version;
  77
  78        *map_size = sizeof(*m) * 32;
  79again:
  80        /*
  81         * Add an additional efi_memory_desc_t because we're doing an
  82         * allocation which may be in a new descriptor region.
  83         */
  84        *map_size += sizeof(*m);
  85        status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
  86                                *map_size, (void **)&m);
  87        if (status != EFI_SUCCESS)
  88                goto fail;
  89
  90        *desc_size = 0;
  91        key = 0;
  92        status = efi_call_early(get_memory_map, map_size, m,
  93                                &key, desc_size, &desc_version);
  94        if (status == EFI_BUFFER_TOO_SMALL) {
  95                efi_call_early(free_pool, m);
  96                goto again;
  97        }
  98
  99        if (status != EFI_SUCCESS)
 100                efi_call_early(free_pool, m);
 101
 102        if (key_ptr && status == EFI_SUCCESS)
 103                *key_ptr = key;
 104        if (desc_ver && status == EFI_SUCCESS)
 105                *desc_ver = desc_version;
 106
 107fail:
 108        *map = m;
 109        return status;
 110}
 111
 112
 113unsigned long get_dram_base(efi_system_table_t *sys_table_arg)
 114{
 115        efi_status_t status;
 116        unsigned long map_size;
 117        unsigned long membase  = EFI_ERROR;
 118        struct efi_memory_map map;
 119        efi_memory_desc_t *md;
 120
 121        status = efi_get_memory_map(sys_table_arg, (efi_memory_desc_t **)&map.map,
 122                                    &map_size, &map.desc_size, NULL, NULL);
 123        if (status != EFI_SUCCESS)
 124                return membase;
 125
 126        map.map_end = map.map + map_size;
 127
 128        for_each_efi_memory_desc(&map, md)
 129                if (md->attribute & EFI_MEMORY_WB)
 130                        if (membase > md->phys_addr)
 131                                membase = md->phys_addr;
 132
 133        efi_call_early(free_pool, map.map);
 134
 135        return membase;
 136}
 137
 138/*
 139 * Allocate at the highest possible address that is not above 'max'.
 140 */
 141efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
 142                            unsigned long size, unsigned long align,
 143                            unsigned long *addr, unsigned long max)
 144{
 145        unsigned long map_size, desc_size;
 146        efi_memory_desc_t *map;
 147        efi_status_t status;
 148        unsigned long nr_pages;
 149        u64 max_addr = 0;
 150        int i;
 151
 152        status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
 153                                    NULL, NULL);
 154        if (status != EFI_SUCCESS)
 155                goto fail;
 156
 157        /*
 158         * Enforce minimum alignment that EFI requires when requesting
 159         * a specific address.  We are doing page-based allocations,
 160         * so we must be aligned to a page.
 161         */
 162        if (align < EFI_ALLOC_ALIGN)
 163                align = EFI_ALLOC_ALIGN;
 164
 165        nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
 166again:
 167        for (i = 0; i < map_size / desc_size; i++) {
 168                efi_memory_desc_t *desc;
 169                unsigned long m = (unsigned long)map;
 170                u64 start, end;
 171
 172                desc = (efi_memory_desc_t *)(m + (i * desc_size));
 173                if (desc->type != EFI_CONVENTIONAL_MEMORY)
 174                        continue;
 175
 176                if (desc->num_pages < nr_pages)
 177                        continue;
 178
 179                start = desc->phys_addr;
 180                end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
 181
 182                if (end > max)
 183                        end = max;
 184
 185                if ((start + size) > end)
 186                        continue;
 187
 188                if (round_down(end - size, align) < start)
 189                        continue;
 190
 191                start = round_down(end - size, align);
 192
 193                /*
 194                 * Don't allocate at 0x0. It will confuse code that
 195                 * checks pointers against NULL.
 196                 */
 197                if (start == 0x0)
 198                        continue;
 199
 200                if (start > max_addr)
 201                        max_addr = start;
 202        }
 203
 204        if (!max_addr)
 205                status = EFI_NOT_FOUND;
 206        else {
 207                status = efi_call_early(allocate_pages,
 208                                        EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
 209                                        nr_pages, &max_addr);
 210                if (status != EFI_SUCCESS) {
 211                        max = max_addr;
 212                        max_addr = 0;
 213                        goto again;
 214                }
 215
 216                *addr = max_addr;
 217        }
 218
 219        efi_call_early(free_pool, map);
 220fail:
 221        return status;
 222}
 223
 224/*
 225 * Allocate at the lowest possible address.
 226 */
 227efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
 228                           unsigned long size, unsigned long align,
 229                           unsigned long *addr)
 230{
 231        unsigned long map_size, desc_size;
 232        efi_memory_desc_t *map;
 233        efi_status_t status;
 234        unsigned long nr_pages;
 235        int i;
 236
 237        status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
 238                                    NULL, NULL);
 239        if (status != EFI_SUCCESS)
 240                goto fail;
 241
 242        /*
 243         * Enforce minimum alignment that EFI requires when requesting
 244         * a specific address.  We are doing page-based allocations,
 245         * so we must be aligned to a page.
 246         */
 247        if (align < EFI_ALLOC_ALIGN)
 248                align = EFI_ALLOC_ALIGN;
 249
 250        nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
 251        for (i = 0; i < map_size / desc_size; i++) {
 252                efi_memory_desc_t *desc;
 253                unsigned long m = (unsigned long)map;
 254                u64 start, end;
 255
 256                desc = (efi_memory_desc_t *)(m + (i * desc_size));
 257
 258                if (desc->type != EFI_CONVENTIONAL_MEMORY)
 259                        continue;
 260
 261                if (desc->num_pages < nr_pages)
 262                        continue;
 263
 264                start = desc->phys_addr;
 265                end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
 266
 267                /*
 268                 * Don't allocate at 0x0. It will confuse code that
 269                 * checks pointers against NULL. Skip the first 8
 270                 * bytes so we start at a nice even number.
 271                 */
 272                if (start == 0x0)
 273                        start += 8;
 274
 275                start = round_up(start, align);
 276                if ((start + size) > end)
 277                        continue;
 278
 279                status = efi_call_early(allocate_pages,
 280                                        EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
 281                                        nr_pages, &start);
 282                if (status == EFI_SUCCESS) {
 283                        *addr = start;
 284                        break;
 285                }
 286        }
 287
 288        if (i == map_size / desc_size)
 289                status = EFI_NOT_FOUND;
 290
 291        efi_call_early(free_pool, map);
 292fail:
 293        return status;
 294}
 295
 296void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
 297              unsigned long addr)
 298{
 299        unsigned long nr_pages;
 300
 301        if (!size)
 302                return;
 303
 304        nr_pages = round_up(size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
 305        efi_call_early(free_pages, addr, nr_pages);
 306}
 307
 308/*
 309 * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
 310 * option, e.g. efi=nochunk.
 311 *
 312 * It should be noted that efi= is parsed in two very different
 313 * environments, first in the early boot environment of the EFI boot
 314 * stub, and subsequently during the kernel boot.
 315 */
 316efi_status_t efi_parse_options(char *cmdline)
 317{
 318        char *str;
 319
 320        /*
 321         * If no EFI parameters were specified on the cmdline we've got
 322         * nothing to do.
 323         */
 324        str = strstr(cmdline, "efi=");
 325        if (!str)
 326                return EFI_SUCCESS;
 327
 328        /* Skip ahead to first argument */
 329        str += strlen("efi=");
 330
 331        /*
 332         * Remember, because efi= is also used by the kernel we need to
 333         * skip over arguments we don't understand.
 334         */
 335        while (*str) {
 336                if (!strncmp(str, "nochunk", 7)) {
 337                        str += strlen("nochunk");
 338                        __chunk_size = -1UL;
 339                }
 340
 341                /* Group words together, delimited by "," */
 342                while (*str && *str != ',')
 343                        str++;
 344
 345                if (*str == ',')
 346                        str++;
 347        }
 348
 349        return EFI_SUCCESS;
 350}
 351
 352/*
 353 * Check the cmdline for a LILO-style file= arguments.
 354 *
 355 * We only support loading a file from the same filesystem as
 356 * the kernel image.
 357 */
 358efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
 359                                  efi_loaded_image_t *image,
 360                                  char *cmd_line, char *option_string,
 361                                  unsigned long max_addr,
 362                                  unsigned long *load_addr,
 363                                  unsigned long *load_size)
 364{
 365        struct file_info *files;
 366        unsigned long file_addr;
 367        u64 file_size_total;
 368        efi_file_handle_t *fh = NULL;
 369        efi_status_t status;
 370        int nr_files;
 371        char *str;
 372        int i, j, k;
 373
 374        file_addr = 0;
 375        file_size_total = 0;
 376
 377        str = cmd_line;
 378
 379        j = 0;                  /* See close_handles */
 380
 381        if (!load_addr || !load_size)
 382                return EFI_INVALID_PARAMETER;
 383
 384        *load_addr = 0;
 385        *load_size = 0;
 386
 387        if (!str || !*str)
 388                return EFI_SUCCESS;
 389
 390        for (nr_files = 0; *str; nr_files++) {
 391                str = strstr(str, option_string);
 392                if (!str)
 393                        break;
 394
 395                str += strlen(option_string);
 396
 397                /* Skip any leading slashes */
 398                while (*str == '/' || *str == '\\')
 399                        str++;
 400
 401                while (*str && *str != ' ' && *str != '\n')
 402                        str++;
 403        }
 404
 405        if (!nr_files)
 406                return EFI_SUCCESS;
 407
 408        status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
 409                                nr_files * sizeof(*files), (void **)&files);
 410        if (status != EFI_SUCCESS) {
 411                pr_efi_err(sys_table_arg, "Failed to alloc mem for file handle list\n");
 412                goto fail;
 413        }
 414
 415        str = cmd_line;
 416        for (i = 0; i < nr_files; i++) {
 417                struct file_info *file;
 418                efi_char16_t filename_16[256];
 419                efi_char16_t *p;
 420
 421                str = strstr(str, option_string);
 422                if (!str)
 423                        break;
 424
 425                str += strlen(option_string);
 426
 427                file = &files[i];
 428                p = filename_16;
 429
 430                /* Skip any leading slashes */
 431                while (*str == '/' || *str == '\\')
 432                        str++;
 433
 434                while (*str && *str != ' ' && *str != '\n') {
 435                        if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
 436                                break;
 437
 438                        if (*str == '/') {
 439                                *p++ = '\\';
 440                                str++;
 441                        } else {
 442                                *p++ = *str++;
 443                        }
 444                }
 445
 446                *p = '\0';
 447
 448                /* Only open the volume once. */
 449                if (!i) {
 450                        status = efi_open_volume(sys_table_arg, image,
 451                                                 (void **)&fh);
 452                        if (status != EFI_SUCCESS)
 453                                goto free_files;
 454                }
 455
 456                status = efi_file_size(sys_table_arg, fh, filename_16,
 457                                       (void **)&file->handle, &file->size);
 458                if (status != EFI_SUCCESS)
 459                        goto close_handles;
 460
 461                file_size_total += file->size;
 462        }
 463
 464        if (file_size_total) {
 465                unsigned long addr;
 466
 467                /*
 468                 * Multiple files need to be at consecutive addresses in memory,
 469                 * so allocate enough memory for all the files.  This is used
 470                 * for loading multiple files.
 471                 */
 472                status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
 473                                    &file_addr, max_addr);
 474                if (status != EFI_SUCCESS) {
 475                        pr_efi_err(sys_table_arg, "Failed to alloc highmem for files\n");
 476                        goto close_handles;
 477                }
 478
 479                /* We've run out of free low memory. */
 480                if (file_addr > max_addr) {
 481                        pr_efi_err(sys_table_arg, "We've run out of free low memory\n");
 482                        status = EFI_INVALID_PARAMETER;
 483                        goto free_file_total;
 484                }
 485
 486                addr = file_addr;
 487                for (j = 0; j < nr_files; j++) {
 488                        unsigned long size;
 489
 490                        size = files[j].size;
 491                        while (size) {
 492                                unsigned long chunksize;
 493                                if (size > __chunk_size)
 494                                        chunksize = __chunk_size;
 495                                else
 496                                        chunksize = size;
 497
 498                                status = efi_file_read(files[j].handle,
 499                                                       &chunksize,
 500                                                       (void *)addr);
 501                                if (status != EFI_SUCCESS) {
 502                                        pr_efi_err(sys_table_arg, "Failed to read file\n");
 503                                        goto free_file_total;
 504                                }
 505                                addr += chunksize;
 506                                size -= chunksize;
 507                        }
 508
 509                        efi_file_close(files[j].handle);
 510                }
 511
 512        }
 513
 514        efi_call_early(free_pool, files);
 515
 516        *load_addr = file_addr;
 517        *load_size = file_size_total;
 518
 519        return status;
 520
 521free_file_total:
 522        efi_free(sys_table_arg, file_size_total, file_addr);
 523
 524close_handles:
 525        for (k = j; k < i; k++)
 526                efi_file_close(files[k].handle);
 527free_files:
 528        efi_call_early(free_pool, files);
 529fail:
 530        *load_addr = 0;
 531        *load_size = 0;
 532
 533        return status;
 534}
 535/*
 536 * Relocate a kernel image, either compressed or uncompressed.
 537 * In the ARM64 case, all kernel images are currently
 538 * uncompressed, and as such when we relocate it we need to
 539 * allocate additional space for the BSS segment. Any low
 540 * memory that this function should avoid needs to be
 541 * unavailable in the EFI memory map, as if the preferred
 542 * address is not available the lowest available address will
 543 * be used.
 544 */
 545efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
 546                                 unsigned long *image_addr,
 547                                 unsigned long image_size,
 548                                 unsigned long alloc_size,
 549                                 unsigned long preferred_addr,
 550                                 unsigned long alignment)
 551{
 552        unsigned long cur_image_addr;
 553        unsigned long new_addr = 0;
 554        efi_status_t status;
 555        unsigned long nr_pages;
 556        efi_physical_addr_t efi_addr = preferred_addr;
 557
 558        if (!image_addr || !image_size || !alloc_size)
 559                return EFI_INVALID_PARAMETER;
 560        if (alloc_size < image_size)
 561                return EFI_INVALID_PARAMETER;
 562
 563        cur_image_addr = *image_addr;
 564
 565        /*
 566         * The EFI firmware loader could have placed the kernel image
 567         * anywhere in memory, but the kernel has restrictions on the
 568         * max physical address it can run at.  Some architectures
 569         * also have a prefered address, so first try to relocate
 570         * to the preferred address.  If that fails, allocate as low
 571         * as possible while respecting the required alignment.
 572         */
 573        nr_pages = round_up(alloc_size, EFI_ALLOC_ALIGN) / EFI_PAGE_SIZE;
 574        status = efi_call_early(allocate_pages,
 575                                EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
 576                                nr_pages, &efi_addr);
 577        new_addr = efi_addr;
 578        /*
 579         * If preferred address allocation failed allocate as low as
 580         * possible.
 581         */
 582        if (status != EFI_SUCCESS) {
 583                status = efi_low_alloc(sys_table_arg, alloc_size, alignment,
 584                                       &new_addr);
 585        }
 586        if (status != EFI_SUCCESS) {
 587                pr_efi_err(sys_table_arg, "Failed to allocate usable memory for kernel.\n");
 588                return status;
 589        }
 590
 591        /*
 592         * We know source/dest won't overlap since both memory ranges
 593         * have been allocated by UEFI, so we can safely use memcpy.
 594         */
 595        memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
 596
 597        /* Return the new address of the relocated image. */
 598        *image_addr = new_addr;
 599
 600        return status;
 601}
 602
 603/*
 604 * Get the number of UTF-8 bytes corresponding to an UTF-16 character.
 605 * This overestimates for surrogates, but that is okay.
 606 */
 607static int efi_utf8_bytes(u16 c)
 608{
 609        return 1 + (c >= 0x80) + (c >= 0x800);
 610}
 611
 612/*
 613 * Convert an UTF-16 string, not necessarily null terminated, to UTF-8.
 614 */
 615static u8 *efi_utf16_to_utf8(u8 *dst, const u16 *src, int n)
 616{
 617        unsigned int c;
 618
 619        while (n--) {
 620                c = *src++;
 621                if (n && c >= 0xd800 && c <= 0xdbff &&
 622                    *src >= 0xdc00 && *src <= 0xdfff) {
 623                        c = 0x10000 + ((c & 0x3ff) << 10) + (*src & 0x3ff);
 624                        src++;
 625                        n--;
 626                }
 627                if (c >= 0xd800 && c <= 0xdfff)
 628                        c = 0xfffd; /* Unmatched surrogate */
 629                if (c < 0x80) {
 630                        *dst++ = c;
 631                        continue;
 632                }
 633                if (c < 0x800) {
 634                        *dst++ = 0xc0 + (c >> 6);
 635                        goto t1;
 636                }
 637                if (c < 0x10000) {
 638                        *dst++ = 0xe0 + (c >> 12);
 639                        goto t2;
 640                }
 641                *dst++ = 0xf0 + (c >> 18);
 642                *dst++ = 0x80 + ((c >> 12) & 0x3f);
 643        t2:
 644                *dst++ = 0x80 + ((c >> 6) & 0x3f);
 645        t1:
 646                *dst++ = 0x80 + (c & 0x3f);
 647        }
 648
 649        return dst;
 650}
 651
 652#ifndef MAX_CMDLINE_ADDRESS
 653#define MAX_CMDLINE_ADDRESS     ULONG_MAX
 654#endif
 655
 656/*
 657 * Convert the unicode UEFI command line to ASCII to pass to kernel.
 658 * Size of memory allocated return in *cmd_line_len.
 659 * Returns NULL on error.
 660 */
 661char *efi_convert_cmdline(efi_system_table_t *sys_table_arg,
 662                          efi_loaded_image_t *image,
 663                          int *cmd_line_len)
 664{
 665        const u16 *s2;
 666        u8 *s1 = NULL;
 667        unsigned long cmdline_addr = 0;
 668        int load_options_chars = image->load_options_size / 2; /* UTF-16 */
 669        const u16 *options = image->load_options;
 670        int options_bytes = 0;  /* UTF-8 bytes */
 671        int options_chars = 0;  /* UTF-16 chars */
 672        efi_status_t status;
 673        u16 zero = 0;
 674
 675        if (options) {
 676                s2 = options;
 677                while (*s2 && *s2 != '\n'
 678                       && options_chars < load_options_chars) {
 679                        options_bytes += efi_utf8_bytes(*s2++);
 680                        options_chars++;
 681                }
 682        }
 683
 684        if (!options_chars) {
 685                /* No command line options, so return empty string*/
 686                options = &zero;
 687        }
 688
 689        options_bytes++;        /* NUL termination */
 690
 691        status = efi_high_alloc(sys_table_arg, options_bytes, 0,
 692                                &cmdline_addr, MAX_CMDLINE_ADDRESS);
 693        if (status != EFI_SUCCESS)
 694                return NULL;
 695
 696        s1 = (u8 *)cmdline_addr;
 697        s2 = (const u16 *)options;
 698
 699        s1 = efi_utf16_to_utf8(s1, s2, options_chars);
 700        *s1 = '\0';
 701
 702        *cmd_line_len = options_bytes;
 703        return (char *)cmdline_addr;
 704}
 705