efi-bgrt.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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. #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. struct acpi_table_bgrt *bgrt_tab;
  19. void *__initdata bgrt_image;
  20. size_t __initdata bgrt_image_size;
  21. struct bmp_header {
  22. u16 id;
  23. u32 size;
  24. } __packed;
  25. void __init efi_bgrt_init(void)
  26. {
  27. acpi_status status;
  28. void __iomem *image;
  29. bool ioremapped = false;
  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. return;
  39. if (bgrt_tab->version != 1 || bgrt_tab->status != 1)
  40. return;
  41. if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
  42. return;
  43. image = efi_lookup_mapped_addr(bgrt_tab->image_address);
  44. if (!image) {
  45. image = early_memremap(bgrt_tab->image_address,
  46. sizeof(bmp_header));
  47. ioremapped = true;
  48. if (!image)
  49. return;
  50. }
  51. memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
  52. if (ioremapped)
  53. early_iounmap(image, sizeof(bmp_header));
  54. bgrt_image_size = bmp_header.size;
  55. bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
  56. if (!bgrt_image)
  57. return;
  58. if (ioremapped) {
  59. image = early_memremap(bgrt_tab->image_address,
  60. bmp_header.size);
  61. if (!image) {
  62. kfree(bgrt_image);
  63. bgrt_image = NULL;
  64. return;
  65. }
  66. }
  67. memcpy_fromio(bgrt_image, image, bgrt_image_size);
  68. if (ioremapped)
  69. early_iounmap(image, bmp_header.size);
  70. }