efi-bgrt.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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/acpi.h>
  15. #include <linux/efi.h>
  16. #include <linux/efi-bgrt.h>
  17. struct acpi_table_bgrt *bgrt_tab;
  18. void *bgrt_image;
  19. size_t bgrt_image_size;
  20. struct bmp_header {
  21. u16 id;
  22. u32 size;
  23. } __packed;
  24. void efi_bgrt_init(void)
  25. {
  26. acpi_status status;
  27. void __iomem *image;
  28. bool ioremapped = false;
  29. struct bmp_header bmp_header;
  30. if (acpi_disabled)
  31. return;
  32. status = acpi_get_table("BGRT", 0,
  33. (struct acpi_table_header **)&bgrt_tab);
  34. if (ACPI_FAILURE(status))
  35. return;
  36. if (bgrt_tab->version != 1)
  37. return;
  38. if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
  39. return;
  40. image = efi_lookup_mapped_addr(bgrt_tab->image_address);
  41. if (!image) {
  42. image = ioremap(bgrt_tab->image_address, sizeof(bmp_header));
  43. ioremapped = true;
  44. if (!image)
  45. return;
  46. }
  47. memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
  48. if (ioremapped)
  49. iounmap(image);
  50. bgrt_image_size = bmp_header.size;
  51. bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL);
  52. if (!bgrt_image)
  53. return;
  54. if (ioremapped) {
  55. image = ioremap(bgrt_tab->image_address, bmp_header.size);
  56. if (!image) {
  57. kfree(bgrt_image);
  58. bgrt_image = NULL;
  59. return;
  60. }
  61. }
  62. memcpy_fromio(bgrt_image, image, bgrt_image_size);
  63. if (ioremapped)
  64. iounmap(image);
  65. }