efi-bgrt.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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)
  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 = ioremap(bgrt_tab->image_address, sizeof(bmp_header));
  46. ioremapped = true;
  47. if (!image)
  48. return;
  49. }
  50. memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
  51. if (ioremapped)
  52. iounmap(image);
  53. bgrt_image_size = bmp_header.size;
  54. bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
  55. if (!bgrt_image)
  56. return;
  57. if (ioremapped) {
  58. image = ioremap(bgrt_tab->image_address, bmp_header.size);
  59. if (!image) {
  60. kfree(bgrt_image);
  61. bgrt_image = NULL;
  62. return;
  63. }
  64. }
  65. memcpy_fromio(bgrt_image, image, bgrt_image_size);
  66. if (ioremapped)
  67. iounmap(image);
  68. }