Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright 2012 Intel Corporation
0004  * Author: Josh Triplett <josh@joshtriplett.org>
0005  *
0006  * Based on the bgrt driver:
0007  * Copyright 2012 Red Hat, Inc <mjg@redhat.com>
0008  * Author: Matthew Garrett
0009  */
0010 
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012 
0013 #include <linux/kernel.h>
0014 #include <linux/init.h>
0015 #include <linux/acpi.h>
0016 #include <linux/efi.h>
0017 #include <linux/efi-bgrt.h>
0018 
0019 struct acpi_table_bgrt bgrt_tab;
0020 size_t bgrt_image_size;
0021 
0022 struct bmp_header {
0023     u16 id;
0024     u32 size;
0025 } __packed;
0026 
0027 void __init efi_bgrt_init(struct acpi_table_header *table)
0028 {
0029     void *image;
0030     struct bmp_header bmp_header;
0031     struct acpi_table_bgrt *bgrt = &bgrt_tab;
0032 
0033     if (acpi_disabled)
0034         return;
0035 
0036     if (!efi_enabled(EFI_MEMMAP))
0037         return;
0038 
0039     if (table->length < sizeof(bgrt_tab)) {
0040         pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
0041                table->length, sizeof(bgrt_tab));
0042         return;
0043     }
0044     *bgrt = *(struct acpi_table_bgrt *)table;
0045     /*
0046      * Only version 1 is defined but some older laptops (seen on Lenovo
0047      * Ivy Bridge models) have a correct version 1 BGRT table with the
0048      * version set to 0, so we accept version 0 and 1.
0049      */
0050     if (bgrt->version > 1) {
0051         pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
0052                bgrt->version);
0053         goto out;
0054     }
0055     if (bgrt->image_type != 0) {
0056         pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
0057                bgrt->image_type);
0058         goto out;
0059     }
0060     if (!bgrt->image_address) {
0061         pr_notice("Ignoring BGRT: null image address\n");
0062         goto out;
0063     }
0064 
0065     if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
0066         pr_notice("Ignoring BGRT: invalid image address\n");
0067         goto out;
0068     }
0069     image = early_memremap(bgrt->image_address, sizeof(bmp_header));
0070     if (!image) {
0071         pr_notice("Ignoring BGRT: failed to map image header memory\n");
0072         goto out;
0073     }
0074 
0075     memcpy(&bmp_header, image, sizeof(bmp_header));
0076     early_memunmap(image, sizeof(bmp_header));
0077     if (bmp_header.id != 0x4d42) {
0078         pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
0079             bmp_header.id);
0080         goto out;
0081     }
0082     bgrt_image_size = bmp_header.size;
0083     efi_mem_reserve(bgrt->image_address, bgrt_image_size);
0084 
0085     return;
0086 out:
0087     memset(bgrt, 0, sizeof(bgrt_tab));
0088 }