0001
0002
0003
0004
0005
0006
0007
0008
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
0047
0048
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 }