iscsi_ibft_find.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright 2007-2010 Red Hat, Inc.
  4. * by Peter Jones <[email protected]>
  5. * Copyright 2007 IBM, Inc.
  6. * by Konrad Rzeszutek <[email protected]>
  7. * Copyright 2008
  8. * by Konrad Rzeszutek <[email protected]>
  9. *
  10. * This code finds the iSCSI Boot Format Table.
  11. */
  12. #include <linux/memblock.h>
  13. #include <linux/blkdev.h>
  14. #include <linux/ctype.h>
  15. #include <linux/device.h>
  16. #include <linux/efi.h>
  17. #include <linux/err.h>
  18. #include <linux/init.h>
  19. #include <linux/limits.h>
  20. #include <linux/module.h>
  21. #include <linux/pci.h>
  22. #include <linux/stat.h>
  23. #include <linux/string.h>
  24. #include <linux/types.h>
  25. #include <linux/acpi.h>
  26. #include <linux/iscsi_ibft.h>
  27. #include <asm/mmzone.h>
  28. /*
  29. * Physical location of iSCSI Boot Format Table.
  30. */
  31. phys_addr_t ibft_phys_addr;
  32. EXPORT_SYMBOL_GPL(ibft_phys_addr);
  33. static const struct {
  34. char *sign;
  35. } ibft_signs[] = {
  36. { "iBFT" },
  37. { "BIFT" }, /* Broadcom iSCSI Offload */
  38. };
  39. #define IBFT_SIGN_LEN 4
  40. #define IBFT_START 0x80000 /* 512kB */
  41. #define IBFT_END 0x100000 /* 1MB */
  42. #define VGA_MEM 0xA0000 /* VGA buffer */
  43. #define VGA_SIZE 0x20000 /* 128kB */
  44. /*
  45. * Routine used to find and reserve the iSCSI Boot Format Table
  46. */
  47. void __init reserve_ibft_region(void)
  48. {
  49. unsigned long pos;
  50. unsigned int len = 0;
  51. void *virt;
  52. int i;
  53. ibft_phys_addr = 0;
  54. /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
  55. * only use ACPI for this
  56. */
  57. if (efi_enabled(EFI_BOOT))
  58. return;
  59. for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
  60. /* The table can't be inside the VGA BIOS reserved space,
  61. * so skip that area */
  62. if (pos == VGA_MEM)
  63. pos += VGA_SIZE;
  64. virt = isa_bus_to_virt(pos);
  65. for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) {
  66. if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) ==
  67. 0) {
  68. unsigned long *addr =
  69. (unsigned long *)isa_bus_to_virt(pos + 4);
  70. len = *addr;
  71. /* if the length of the table extends past 1M,
  72. * the table cannot be valid. */
  73. if (pos + len <= (IBFT_END-1)) {
  74. ibft_phys_addr = pos;
  75. memblock_reserve(ibft_phys_addr, PAGE_ALIGN(len));
  76. pr_info("iBFT found at %pa.\n", &ibft_phys_addr);
  77. return;
  78. }
  79. }
  80. }
  81. }
  82. }