efi-bgrt.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  14. #include <linux/kernel.h>
  15. #include <linux/init.h>
  16. #include <linux/acpi.h>
  17. #include <linux/efi.h>
  18. #include <linux/efi-bgrt.h>
  19. struct acpi_table_bgrt bgrt_tab;
  20. size_t bgrt_image_size;
  21. struct bmp_header {
  22. u16 id;
  23. u32 size;
  24. } __packed;
  25. void __init efi_bgrt_init(struct acpi_table_header *table)
  26. {
  27. void *image;
  28. struct bmp_header bmp_header;
  29. struct acpi_table_bgrt *bgrt = &bgrt_tab;
  30. if (acpi_disabled)
  31. return;
  32. if (!efi_enabled(EFI_MEMMAP))
  33. return;
  34. if (table->length < sizeof(bgrt_tab)) {
  35. pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
  36. table->length, sizeof(bgrt_tab));
  37. return;
  38. }
  39. *bgrt = *(struct acpi_table_bgrt *)table;
  40. if (bgrt->version != 1) {
  41. pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
  42. bgrt->version);
  43. goto out;
  44. }
  45. if (bgrt->image_type != 0) {
  46. pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
  47. bgrt->image_type);
  48. goto out;
  49. }
  50. if (!bgrt->image_address) {
  51. pr_notice("Ignoring BGRT: null image address\n");
  52. goto out;
  53. }
  54. if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
  55. pr_notice("Ignoring BGRT: invalid image address\n");
  56. goto out;
  57. }
  58. image = early_memremap(bgrt->image_address, sizeof(bmp_header));
  59. if (!image) {
  60. pr_notice("Ignoring BGRT: failed to map image header memory\n");
  61. goto out;
  62. }
  63. memcpy(&bmp_header, image, sizeof(bmp_header));
  64. early_memunmap(image, sizeof(bmp_header));
  65. if (bmp_header.id != 0x4d42) {
  66. pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
  67. bmp_header.id);
  68. goto out;
  69. }
  70. bgrt_image_size = bmp_header.size;
  71. efi_mem_reserve(bgrt->image_address, bgrt_image_size);
  72. return;
  73. out:
  74. memset(bgrt, 0, sizeof(bgrt_tab));
  75. }