0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/memblock.h>
0014 #include <linux/blkdev.h>
0015 #include <linux/ctype.h>
0016 #include <linux/device.h>
0017 #include <linux/efi.h>
0018 #include <linux/err.h>
0019 #include <linux/init.h>
0020 #include <linux/limits.h>
0021 #include <linux/module.h>
0022 #include <linux/pci.h>
0023 #include <linux/stat.h>
0024 #include <linux/string.h>
0025 #include <linux/types.h>
0026 #include <linux/acpi.h>
0027 #include <linux/iscsi_ibft.h>
0028
0029 #include <asm/mmzone.h>
0030
0031
0032
0033
0034 phys_addr_t ibft_phys_addr;
0035 EXPORT_SYMBOL_GPL(ibft_phys_addr);
0036
0037 static const struct {
0038 char *sign;
0039 } ibft_signs[] = {
0040 { "iBFT" },
0041 { "BIFT" },
0042 };
0043
0044 #define IBFT_SIGN_LEN 4
0045 #define IBFT_START 0x80000
0046 #define IBFT_END 0x100000
0047 #define VGA_MEM 0xA0000
0048 #define VGA_SIZE 0x20000
0049
0050
0051
0052
0053 void __init reserve_ibft_region(void)
0054 {
0055 unsigned long pos;
0056 unsigned int len = 0;
0057 void *virt;
0058 int i;
0059
0060 ibft_phys_addr = 0;
0061
0062
0063
0064
0065 if (efi_enabled(EFI_BOOT))
0066 return;
0067
0068 for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
0069
0070
0071 if (pos == VGA_MEM)
0072 pos += VGA_SIZE;
0073 virt = isa_bus_to_virt(pos);
0074
0075 for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) {
0076 if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) ==
0077 0) {
0078 unsigned long *addr =
0079 (unsigned long *)isa_bus_to_virt(pos + 4);
0080 len = *addr;
0081
0082
0083 if (pos + len <= (IBFT_END-1)) {
0084 ibft_phys_addr = pos;
0085 memblock_reserve(ibft_phys_addr, PAGE_ALIGN(len));
0086 pr_info("iBFT found at %pa.\n", &ibft_phys_addr);
0087 return;
0088 }
0089 }
0090 }
0091 }
0092 }