linux/drivers/firmware/efi/libstub/arm-stub.c
<<
>>
Prefs
   1/*
   2 * EFI stub implementation that is shared by arm and arm64 architectures.
   3 * This should be #included by the EFI stub implementation files.
   4 *
   5 * Copyright (C) 2013,2014 Linaro Limited
   6 *     Roy Franz <roy.franz@linaro.org
   7 * Copyright (C) 2013 Red Hat, Inc.
   8 *     Mark Salter <msalter@redhat.com>
   9 *
  10 * This file is part of the Linux kernel, and is made available under the
  11 * terms of the GNU General Public License version 2.
  12 *
  13 */
  14
  15#include <linux/efi.h>
  16#include <linux/sort.h>
  17#include <asm/efi.h>
  18
  19#include "efistub.h"
  20
  21static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg)
  22{
  23        static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID;
  24        static efi_char16_t const var_name[] = {
  25                'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 };
  26
  27        efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable;
  28        unsigned long size = sizeof(u8);
  29        efi_status_t status;
  30        u8 val;
  31
  32        status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)&var_guid,
  33                          NULL, &size, &val);
  34
  35        switch (status) {
  36        case EFI_SUCCESS:
  37                return val;
  38        case EFI_NOT_FOUND:
  39                return 0;
  40        default:
  41                return 1;
  42        }
  43}
  44
  45efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg,
  46                             void *__image, void **__fh)
  47{
  48        efi_file_io_interface_t *io;
  49        efi_loaded_image_t *image = __image;
  50        efi_file_handle_t *fh;
  51        efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
  52        efi_status_t status;
  53        void *handle = (void *)(unsigned long)image->device_handle;
  54
  55        status = sys_table_arg->boottime->handle_protocol(handle,
  56                                 &fs_proto, (void **)&io);
  57        if (status != EFI_SUCCESS) {
  58                efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
  59                return status;
  60        }
  61
  62        status = io->open_volume(io, &fh);
  63        if (status != EFI_SUCCESS)
  64                efi_printk(sys_table_arg, "Failed to open volume\n");
  65
  66        *__fh = fh;
  67        return status;
  68}
  69
  70efi_status_t efi_file_close(void *handle)
  71{
  72        efi_file_handle_t *fh = handle;
  73
  74        return fh->close(handle);
  75}
  76
  77efi_status_t
  78efi_file_read(void *handle, unsigned long *size, void *addr)
  79{
  80        efi_file_handle_t *fh = handle;
  81
  82        return fh->read(handle, size, addr);
  83}
  84
  85
  86efi_status_t
  87efi_file_size(efi_system_table_t *sys_table_arg, void *__fh,
  88              efi_char16_t *filename_16, void **handle, u64 *file_sz)
  89{
  90        efi_file_handle_t *h, *fh = __fh;
  91        efi_file_info_t *info;
  92        efi_status_t status;
  93        efi_guid_t info_guid = EFI_FILE_INFO_ID;
  94        unsigned long info_sz;
  95
  96        status = fh->open(fh, &h, filename_16, EFI_FILE_MODE_READ, (u64)0);
  97        if (status != EFI_SUCCESS) {
  98                efi_printk(sys_table_arg, "Failed to open file: ");
  99                efi_char16_printk(sys_table_arg, filename_16);
 100                efi_printk(sys_table_arg, "\n");
 101                return status;
 102        }
 103
 104        *handle = h;
 105
 106        info_sz = 0;
 107        status = h->get_info(h, &info_guid, &info_sz, NULL);
 108        if (status != EFI_BUFFER_TOO_SMALL) {
 109                efi_printk(sys_table_arg, "Failed to get file info size\n");
 110                return status;
 111        }
 112
 113grow:
 114        status = sys_table_arg->boottime->allocate_pool(EFI_LOADER_DATA,
 115                                 info_sz, (void **)&info);
 116        if (status != EFI_SUCCESS) {
 117                efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
 118                return status;
 119        }
 120
 121        status = h->get_info(h, &info_guid, &info_sz,
 122                                                   info);
 123        if (status == EFI_BUFFER_TOO_SMALL) {
 124                sys_table_arg->boottime->free_pool(info);
 125                goto grow;
 126        }
 127
 128        *file_sz = info->file_size;
 129        sys_table_arg->boottime->free_pool(info);
 130
 131        if (status != EFI_SUCCESS)
 132                efi_printk(sys_table_arg, "Failed to get initrd info\n");
 133
 134        return status;
 135}
 136
 137
 138
 139void efi_char16_printk(efi_system_table_t *sys_table_arg,
 140                              efi_char16_t *str)
 141{
 142        struct efi_simple_text_output_protocol *out;
 143
 144        out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out;
 145        out->output_string(out, str);
 146}
 147
 148
 149/*
 150 * This function handles the architcture specific differences between arm and
 151 * arm64 regarding where the kernel image must be loaded and any memory that
 152 * must be reserved. On failure it is required to free all
 153 * all allocations it has made.
 154 */
 155efi_status_t handle_kernel_image(efi_system_table_t *sys_table,
 156                                 unsigned long *image_addr,
 157                                 unsigned long *image_size,
 158                                 unsigned long *reserve_addr,
 159                                 unsigned long *reserve_size,
 160                                 unsigned long dram_base,
 161                                 efi_loaded_image_t *image);
 162/*
 163 * EFI entry point for the arm/arm64 EFI stubs.  This is the entrypoint
 164 * that is described in the PE/COFF header.  Most of the code is the same
 165 * for both archictectures, with the arch-specific code provided in the
 166 * handle_kernel_image() function.
 167 */
 168unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
 169                               unsigned long *image_addr)
 170{
 171        efi_loaded_image_t *image;
 172        efi_status_t status;
 173        unsigned long image_size = 0;
 174        unsigned long dram_base;
 175        /* addr/point and size pairs for memory management*/
 176        unsigned long initrd_addr;
 177        u64 initrd_size = 0;
 178        unsigned long fdt_addr = 0;  /* Original DTB */
 179        unsigned long fdt_size = 0;
 180        char *cmdline_ptr = NULL;
 181        int cmdline_size = 0;
 182        unsigned long new_fdt_addr;
 183        efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
 184        unsigned long reserve_addr = 0;
 185        unsigned long reserve_size = 0;
 186
 187        /* Check if we were booted by the EFI firmware */
 188        if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
 189                goto fail;
 190
 191        pr_efi(sys_table, "Booting Linux Kernel...\n");
 192
 193        /*
 194         * Get a handle to the loaded image protocol.  This is used to get
 195         * information about the running image, such as size and the command
 196         * line.
 197         */
 198        status = sys_table->boottime->handle_protocol(handle,
 199                                        &loaded_image_proto, (void *)&image);
 200        if (status != EFI_SUCCESS) {
 201                pr_efi_err(sys_table, "Failed to get loaded image protocol\n");
 202                goto fail;
 203        }
 204
 205        dram_base = get_dram_base(sys_table);
 206        if (dram_base == EFI_ERROR) {
 207                pr_efi_err(sys_table, "Failed to find DRAM base\n");
 208                goto fail;
 209        }
 210        status = handle_kernel_image(sys_table, image_addr, &image_size,
 211                                     &reserve_addr,
 212                                     &reserve_size,
 213                                     dram_base, image);
 214        if (status != EFI_SUCCESS) {
 215                pr_efi_err(sys_table, "Failed to relocate kernel\n");
 216                goto fail;
 217        }
 218
 219        /*
 220         * Get the command line from EFI, using the LOADED_IMAGE
 221         * protocol. We are going to copy the command line into the
 222         * device tree, so this can be allocated anywhere.
 223         */
 224        cmdline_ptr = efi_convert_cmdline(sys_table, image, &cmdline_size);
 225        if (!cmdline_ptr) {
 226                pr_efi_err(sys_table, "getting command line via LOADED_IMAGE_PROTOCOL\n");
 227                goto fail_free_image;
 228        }
 229
 230        status = efi_parse_options(cmdline_ptr);
 231        if (status != EFI_SUCCESS)
 232                pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
 233
 234        /*
 235         * Unauthenticated device tree data is a security hazard, so
 236         * ignore 'dtb=' unless UEFI Secure Boot is disabled.
 237         */
 238        if (efi_secureboot_enabled(sys_table)) {
 239                pr_efi(sys_table, "UEFI Secure Boot is enabled.\n");
 240        } else {
 241                status = handle_cmdline_files(sys_table, image, cmdline_ptr,
 242                                              "dtb=",
 243                                              ~0UL, &fdt_addr, &fdt_size);
 244
 245                if (status != EFI_SUCCESS) {
 246                        pr_efi_err(sys_table, "Failed to load device tree!\n");
 247                        goto fail_free_cmdline;
 248                }
 249        }
 250
 251        if (fdt_addr) {
 252                pr_efi(sys_table, "Using DTB from command line\n");
 253        } else {
 254                /* Look for a device tree configuration table entry. */
 255                fdt_addr = (uintptr_t)get_fdt(sys_table, &fdt_size);
 256                if (fdt_addr)
 257                        pr_efi(sys_table, "Using DTB from configuration table\n");
 258        }
 259
 260        if (!fdt_addr)
 261                pr_efi(sys_table, "Generating empty DTB\n");
 262
 263        status = handle_cmdline_files(sys_table, image, cmdline_ptr,
 264                                      "initrd=", dram_base + SZ_512M,
 265                                      (unsigned long *)&initrd_addr,
 266                                      (unsigned long *)&initrd_size);
 267        if (status != EFI_SUCCESS)
 268                pr_efi_err(sys_table, "Failed initrd from command line!\n");
 269
 270        new_fdt_addr = fdt_addr;
 271        status = allocate_new_fdt_and_exit_boot(sys_table, handle,
 272                                &new_fdt_addr, dram_base + MAX_FDT_OFFSET,
 273                                initrd_addr, initrd_size, cmdline_ptr,
 274                                fdt_addr, fdt_size);
 275
 276        /*
 277         * If all went well, we need to return the FDT address to the
 278         * calling function so it can be passed to kernel as part of
 279         * the kernel boot protocol.
 280         */
 281        if (status == EFI_SUCCESS)
 282                return new_fdt_addr;
 283
 284        pr_efi_err(sys_table, "Failed to update FDT and exit boot services\n");
 285
 286        efi_free(sys_table, initrd_size, initrd_addr);
 287        efi_free(sys_table, fdt_size, fdt_addr);
 288
 289fail_free_cmdline:
 290        efi_free(sys_table, cmdline_size, (unsigned long)cmdline_ptr);
 291
 292fail_free_image:
 293        efi_free(sys_table, image_size, *image_addr);
 294        efi_free(sys_table, reserve_size, reserve_addr);
 295fail:
 296        return EFI_ERROR;
 297}
 298
 299/*
 300 * This is the base address at which to start allocating virtual memory ranges
 301 * for UEFI Runtime Services. This is in the low TTBR0 range so that we can use
 302 * any allocation we choose, and eliminate the risk of a conflict after kexec.
 303 * The value chosen is the largest non-zero power of 2 suitable for this purpose
 304 * both on 32-bit and 64-bit ARM CPUs, to maximize the likelihood that it can
 305 * be mapped efficiently.
 306 */
 307#define EFI_RT_VIRTUAL_BASE     0x40000000
 308
 309static int cmp_mem_desc(const void *l, const void *r)
 310{
 311        const efi_memory_desc_t *left = l, *right = r;
 312
 313        return (left->phys_addr > right->phys_addr) ? 1 : -1;
 314}
 315
 316/*
 317 * Returns whether region @left ends exactly where region @right starts,
 318 * or false if either argument is NULL.
 319 */
 320static bool regions_are_adjacent(efi_memory_desc_t *left,
 321                                 efi_memory_desc_t *right)
 322{
 323        u64 left_end;
 324
 325        if (left == NULL || right == NULL)
 326                return false;
 327
 328        left_end = left->phys_addr + left->num_pages * EFI_PAGE_SIZE;
 329
 330        return left_end == right->phys_addr;
 331}
 332
 333/*
 334 * Returns whether region @left and region @right have compatible memory type
 335 * mapping attributes, and are both EFI_MEMORY_RUNTIME regions.
 336 */
 337static bool regions_have_compatible_memory_type_attrs(efi_memory_desc_t *left,
 338                                                      efi_memory_desc_t *right)
 339{
 340        static const u64 mem_type_mask = EFI_MEMORY_WB | EFI_MEMORY_WT |
 341                                         EFI_MEMORY_WC | EFI_MEMORY_UC |
 342                                         EFI_MEMORY_RUNTIME;
 343
 344        return ((left->attribute ^ right->attribute) & mem_type_mask) == 0;
 345}
 346
 347/*
 348 * efi_get_virtmap() - create a virtual mapping for the EFI memory map
 349 *
 350 * This function populates the virt_addr fields of all memory region descriptors
 351 * in @memory_map whose EFI_MEMORY_RUNTIME attribute is set. Those descriptors
 352 * are also copied to @runtime_map, and their total count is returned in @count.
 353 */
 354void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
 355                     unsigned long desc_size, efi_memory_desc_t *runtime_map,
 356                     int *count)
 357{
 358        u64 efi_virt_base = EFI_RT_VIRTUAL_BASE;
 359        efi_memory_desc_t *in, *prev = NULL, *out = runtime_map;
 360        int l;
 361
 362        /*
 363         * To work around potential issues with the Properties Table feature
 364         * introduced in UEFI 2.5, which may split PE/COFF executable images
 365         * in memory into several RuntimeServicesCode and RuntimeServicesData
 366         * regions, we need to preserve the relative offsets between adjacent
 367         * EFI_MEMORY_RUNTIME regions with the same memory type attributes.
 368         * The easiest way to find adjacent regions is to sort the memory map
 369         * before traversing it.
 370         */
 371        sort(memory_map, map_size / desc_size, desc_size, cmp_mem_desc, NULL);
 372
 373        for (l = 0; l < map_size; l += desc_size, prev = in) {
 374                u64 paddr, size;
 375
 376                in = (void *)memory_map + l;
 377                if (!(in->attribute & EFI_MEMORY_RUNTIME))
 378                        continue;
 379
 380                paddr = in->phys_addr;
 381                size = in->num_pages * EFI_PAGE_SIZE;
 382
 383                /*
 384                 * Make the mapping compatible with 64k pages: this allows
 385                 * a 4k page size kernel to kexec a 64k page size kernel and
 386                 * vice versa.
 387                 */
 388                if (!regions_are_adjacent(prev, in) ||
 389                    !regions_have_compatible_memory_type_attrs(prev, in)) {
 390
 391                        paddr = round_down(in->phys_addr, SZ_64K);
 392                        size += in->phys_addr - paddr;
 393
 394                        /*
 395                         * Avoid wasting memory on PTEs by choosing a virtual
 396                         * base that is compatible with section mappings if this
 397                         * region has the appropriate size and physical
 398                         * alignment. (Sections are 2 MB on 4k granule kernels)
 399                         */
 400                        if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M)
 401                                efi_virt_base = round_up(efi_virt_base, SZ_2M);
 402                        else
 403                                efi_virt_base = round_up(efi_virt_base, SZ_64K);
 404                }
 405
 406                in->virt_addr = efi_virt_base + in->phys_addr - paddr;
 407                efi_virt_base += size;
 408
 409                memcpy(out, in, desc_size);
 410                out = (void *)out + desc_size;
 411                ++*count;
 412        }
 413}
 414