^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2007-2010 Red Hat, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * by Peter Jones <pjones@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007 IBM, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * by Konrad Rzeszutek <konradr@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * by Konrad Rzeszutek <ketuzsezr@darnok.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This code finds the iSCSI Boot Format Table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/iscsi_ibft.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/mmzone.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Physical location of iSCSI Boot Format Table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct acpi_table_ibft *ibft_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) EXPORT_SYMBOL_GPL(ibft_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) char *sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) } ibft_signs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { "iBFT" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { "BIFT" }, /* Broadcom iSCSI Offload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define IBFT_SIGN_LEN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define IBFT_START 0x80000 /* 512kB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define IBFT_END 0x100000 /* 1MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define VGA_MEM 0xA0000 /* VGA buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define VGA_SIZE 0x20000 /* 128kB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static int __init find_ibft_in_mem(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned long pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void *virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* The table can't be inside the VGA BIOS reserved space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * so skip that area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (pos == VGA_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) pos += VGA_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) virt = isa_bus_to_virt(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long *addr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) (unsigned long *)isa_bus_to_virt(pos + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) len = *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* if the length of the table extends past 1M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * the table cannot be valid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (pos + len <= (IBFT_END-1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ibft_addr = (struct acpi_table_ibft *)virt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) pr_info("iBFT found at 0x%lx.\n", pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * Routine used to find the iSCSI Boot Format Table. The logical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * kernel address is set in the ibft_addr global variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long __init find_ibft_region(unsigned long *sizep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ibft_addr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * only use ACPI for this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (!efi_enabled(EFI_BOOT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) find_ibft_in_mem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (ibft_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *sizep = PAGE_ALIGN(ibft_addr->header.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return (u64)virt_to_phys(ibft_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *sizep = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }