linux/drivers/firmware/efi/efi-bgrt.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 Intel Corporation
   3 * Author: Josh Triplett <josh@joshtriplett.org>
   4 *
   5 * Based on the bgrt driver:
   6 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
   7 * Author: Matthew Garrett
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15
  16#include <linux/kernel.h>
  17#include <linux/init.h>
  18#include <linux/acpi.h>
  19#include <linux/efi.h>
  20#include <linux/efi-bgrt.h>
  21
  22struct acpi_table_bgrt bgrt_tab;
  23size_t __initdata bgrt_image_size;
  24
  25struct bmp_header {
  26        u16 id;
  27        u32 size;
  28} __packed;
  29
  30void __init efi_bgrt_init(struct acpi_table_header *table)
  31{
  32        void *image;
  33        struct bmp_header bmp_header;
  34        struct acpi_table_bgrt *bgrt = &bgrt_tab;
  35
  36        if (acpi_disabled)
  37                return;
  38
  39        if (!efi_enabled(EFI_MEMMAP))
  40                return;
  41
  42        if (table->length < sizeof(bgrt_tab)) {
  43                pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
  44                       table->length, sizeof(bgrt_tab));
  45                return;
  46        }
  47        *bgrt = *(struct acpi_table_bgrt *)table;
  48        if (bgrt->version != 1) {
  49                pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
  50                       bgrt->version);
  51                goto out;
  52        }
  53        if (bgrt->status & 0xfe) {
  54                pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n",
  55                       bgrt->status);
  56                goto out;
  57        }
  58        if (bgrt->image_type != 0) {
  59                pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
  60                       bgrt->image_type);
  61                goto out;
  62        }
  63        if (!bgrt->image_address) {
  64                pr_notice("Ignoring BGRT: null image address\n");
  65                goto out;
  66        }
  67
  68        if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
  69                pr_notice("Ignoring BGRT: invalid image address\n");
  70                goto out;
  71        }
  72        image = early_memremap(bgrt->image_address, sizeof(bmp_header));
  73        if (!image) {
  74                pr_notice("Ignoring BGRT: failed to map image header memory\n");
  75                goto out;
  76        }
  77
  78        memcpy(&bmp_header, image, sizeof(bmp_header));
  79        early_memunmap(image, sizeof(bmp_header));
  80        if (bmp_header.id != 0x4d42) {
  81                pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
  82                        bmp_header.id);
  83                goto out;
  84        }
  85        bgrt_image_size = bmp_header.size;
  86        efi_mem_reserve(bgrt->image_address, bgrt_image_size);
  87
  88        return;
  89out:
  90        memset(bgrt, 0, sizeof(bgrt_tab));
  91}
  92