linux/drivers/firmware/efi/efi-bgrt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2012 Intel Corporation
   4 * Author: Josh Triplett <josh@joshtriplett.org>
   5 *
   6 * Based on the bgrt driver:
   7 * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
   8 * Author: Matthew Garrett
   9 */
  10
  11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/acpi.h>
  16#include <linux/efi.h>
  17#include <linux/efi-bgrt.h>
  18
  19struct acpi_table_bgrt bgrt_tab;
  20size_t bgrt_image_size;
  21
  22struct bmp_header {
  23        u16 id;
  24        u32 size;
  25} __packed;
  26
  27void __init efi_bgrt_init(struct acpi_table_header *table)
  28{
  29        void *image;
  30        struct bmp_header bmp_header;
  31        struct acpi_table_bgrt *bgrt = &bgrt_tab;
  32
  33        if (acpi_disabled)
  34                return;
  35
  36        if (!efi_enabled(EFI_MEMMAP))
  37                return;
  38
  39        if (table->length < sizeof(bgrt_tab)) {
  40                pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
  41                       table->length, sizeof(bgrt_tab));
  42                return;
  43        }
  44        *bgrt = *(struct acpi_table_bgrt *)table;
  45        /*
  46         * Only version 1 is defined but some older laptops (seen on Lenovo
  47         * Ivy Bridge models) have a correct version 1 BGRT table with the
  48         * version set to 0, so we accept version 0 and 1.
  49         */
  50        if (bgrt->version > 1) {
  51                pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
  52                       bgrt->version);
  53                goto out;
  54        }
  55        if (bgrt->image_type != 0) {
  56                pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
  57                       bgrt->image_type);
  58                goto out;
  59        }
  60        if (!bgrt->image_address) {
  61                pr_notice("Ignoring BGRT: null image address\n");
  62                goto out;
  63        }
  64
  65        if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
  66                pr_notice("Ignoring BGRT: invalid image address\n");
  67                goto out;
  68        }
  69        image = early_memremap(bgrt->image_address, sizeof(bmp_header));
  70        if (!image) {
  71                pr_notice("Ignoring BGRT: failed to map image header memory\n");
  72                goto out;
  73        }
  74
  75        memcpy(&bmp_header, image, sizeof(bmp_header));
  76        early_memunmap(image, sizeof(bmp_header));
  77        if (bmp_header.id != 0x4d42) {
  78                pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
  79                        bmp_header.id);
  80                goto out;
  81        }
  82        bgrt_image_size = bmp_header.size;
  83        efi_mem_reserve(bgrt->image_address, bgrt_image_size);
  84
  85        return;
  86out:
  87        memset(bgrt, 0, sizeof(bgrt_tab));
  88}
  89