efi-bgrt.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. void *__initdata bgrt_image;
  21. size_t __initdata bgrt_image_size;
  22. struct bmp_header {
  23. u16 id;
  24. u32 size;
  25. } __packed;
  26. void __init efi_bgrt_init(void)
  27. {
  28. acpi_status status;
  29. void *image;
  30. struct bmp_header bmp_header;
  31. if (acpi_disabled)
  32. return;
  33. status = acpi_get_table("BGRT", 0,
  34. (struct acpi_table_header **)&bgrt_tab);
  35. if (ACPI_FAILURE(status))
  36. return;
  37. if (bgrt_tab->header.length < sizeof(*bgrt_tab)) {
  38. pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
  39. bgrt_tab->header.length, sizeof(*bgrt_tab));
  40. return;
  41. }
  42. if (bgrt_tab->version != 1) {
  43. pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
  44. bgrt_tab->version);
  45. return;
  46. }
  47. if (bgrt_tab->status & 0xfe) {
  48. pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n",
  49. bgrt_tab->status);
  50. return;
  51. }
  52. if (bgrt_tab->image_type != 0) {
  53. pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
  54. bgrt_tab->image_type);
  55. return;
  56. }
  57. if (!bgrt_tab->image_address) {
  58. pr_notice("Ignoring BGRT: null image address\n");
  59. return;
  60. }
  61. image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB);
  62. if (!image) {
  63. pr_notice("Ignoring BGRT: failed to map image header memory\n");
  64. return;
  65. }
  66. memcpy(&bmp_header, image, sizeof(bmp_header));
  67. memunmap(image);
  68. if (bmp_header.id != 0x4d42) {
  69. pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
  70. bmp_header.id);
  71. return;
  72. }
  73. bgrt_image_size = bmp_header.size;
  74. bgrt_image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB);
  75. if (!bgrt_image) {
  76. pr_notice("Ignoring BGRT: failed to map image memory\n");
  77. bgrt_image = NULL;
  78. return;
  79. }
  80. efi_mem_reserve(bgrt_tab->image_address, bgrt_image_size);
  81. }