Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *	Intel Multiprocessor Specification 1.1 and 1.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *	compliant MP-table parsing routines.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *	(c) 1995 Alan Cox, Building #3 <alan@lxorguk.ukuu.org.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *	(c) 1998, 1999, 2000, 2009 Ingo Molnar <mingo@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *      (c) 2008 Alexey Starikovskiy <astarikovskiy@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/kernel_stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/mc146818rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <asm/io_apic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <asm/irqdomain.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <asm/mtrr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <asm/mpspec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <asm/proto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/bios_ebda.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <asm/e820/api.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <asm/apic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * Checksum an MP configuration block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static int __init mpf_checksum(unsigned char *mp, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	int sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		sum += *mp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return sum & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static void __init MP_processor_info(struct mpc_cpu *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	int apicid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	char *bootup_cpu = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (!(m->cpuflag & CPU_ENABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		disabled_cpus++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	apicid = m->apicid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (m->cpuflag & CPU_BOOTPROCESSOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		bootup_cpu = " (Bootup-CPU)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		boot_cpu_physical_apicid = m->apicid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	pr_info("Processor #%d%s\n", m->apicid, bootup_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	generic_processor_info(apicid, m->apicver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) static void __init mpc_oem_bus_info(struct mpc_bus *m, char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	memcpy(str, m->bustype, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	str[6] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static void __init MP_bus_info(struct mpc_bus *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	char str[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	mpc_oem_bus_info(m, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #if MAX_MP_BUSSES < 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (m->busid >= MAX_MP_BUSSES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		pr_warn("MP table busid value (%d) for bustype %s is too large, max. supported is %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			m->busid, str, MAX_MP_BUSSES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	set_bit(m->busid, mp_bus_not_pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	} else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		clear_bit(m->busid, mp_bus_not_pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #ifdef CONFIG_EISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		mp_bus_id_to_type[m->busid] = MP_BUS_PCI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	} else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA) - 1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		mp_bus_id_to_type[m->busid] = MP_BUS_EISA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		pr_warn("Unknown bustype %s - ignoring\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void __init MP_ioapic_info(struct mpc_ioapic *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct ioapic_domain_cfg cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		.type = IOAPIC_DOMAIN_LEGACY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		.ops = &mp_ioapic_irqdomain_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (m->flags & MPC_APIC_USABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		mp_register_ioapic(m->apicid, m->apicaddr, gsi_top, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	apic_printk(APIC_VERBOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		"Int: type %d, pol %d, trig %d, bus %02x, IRQ %02x, APIC ID %x, APIC INT %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		mp_irq->irqtype, mp_irq->irqflag & 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		(mp_irq->irqflag >> 2) & 3, mp_irq->srcbus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #else /* CONFIG_X86_IO_APIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static inline void __init MP_bus_info(struct mpc_bus *m) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #endif /* CONFIG_X86_IO_APIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	apic_printk(APIC_VERBOSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		"Lint: type %d, pol %d, trig %d, bus %02x, IRQ %02x, APIC ID %x, APIC LINT %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbusid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		m->srcbusirq, m->destapic, m->destapiclint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * Read/parse the MPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (memcmp(mpc->signature, MPC_SIGNATURE, 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		pr_err("MPTABLE: bad signature [%c%c%c%c]!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		       mpc->signature[0], mpc->signature[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		       mpc->signature[2], mpc->signature[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (mpf_checksum((unsigned char *)mpc, mpc->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		pr_err("MPTABLE: checksum error!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (mpc->spec != 0x01 && mpc->spec != 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		pr_err("MPTABLE: bad table version (%d)!!\n", mpc->spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (!mpc->lapic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		pr_err("MPTABLE: null local APIC address!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	memcpy(oem, mpc->oem, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	oem[8] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	pr_info("MPTABLE: OEM ID: %s\n", oem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	memcpy(str, mpc->productid, 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	str[12] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	pr_info("MPTABLE: Product ID: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	pr_info("MPTABLE: APIC at: 0x%X\n", mpc->lapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void skip_entry(unsigned char **ptr, int *count, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	*ptr += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	*count += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	pr_err("Your mptable is wrong, contact your HW vendor!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	pr_cont("type %x\n", *mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	print_hex_dump(KERN_ERR, "  ", DUMP_PREFIX_ADDRESS, 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			1, mpc, mpc->length, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	char str[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	char oem[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	int count = sizeof(*mpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	unsigned char *mpt = ((unsigned char *)mpc) + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (!smp_check_mpc(mpc, oem, str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/* Initialize the lapic mapping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (!acpi_lapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		register_lapic_address(mpc->lapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	if (early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/* Now process the configuration blocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	while (count < mpc->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		switch (*mpt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		case MP_PROCESSOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 			/* ACPI may have already provided this data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			if (!acpi_lapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 				MP_processor_info((struct mpc_cpu *)mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		case MP_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			MP_bus_info((struct mpc_bus *)mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 			skip_entry(&mpt, &count, sizeof(struct mpc_bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		case MP_IOAPIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			MP_ioapic_info((struct mpc_ioapic *)mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		case MP_INTSRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			mp_save_irq((struct mpc_intsrc *)mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		case MP_LINTSRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			MP_lintsrc_info((struct mpc_lintsrc *)mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 			/* wrong mptable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 			smp_dump_mptable(mpc, mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			count = mpc->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	if (!num_processors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		pr_err("MPTABLE: no processors registered!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	return num_processors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static int __init ELCR_trigger(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	unsigned int port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	port = 0x4d0 + (irq >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return (inb(port) >> (irq & 7)) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void __init construct_default_ioirq_mptable(int mpc_default_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	struct mpc_intsrc intsrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	int ELCR_fallback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	intsrc.type = MP_INTSRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	intsrc.irqflag = MP_IRQTRIG_DEFAULT | MP_IRQPOL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	intsrc.srcbus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	intsrc.dstapic = mpc_ioapic_id(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	intsrc.irqtype = mp_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	 *  If true, we have an ISA/PCI system with no IRQ entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	 *  in the MP table. To prevent the PCI interrupts from being set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	 *  incorrectly, we try to use the ELCR. The sanity check to see if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	 *  there is good ELCR data is very simple - IRQ0, 1, 2 and 13 can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	 *  never be level sensitive, so we simply see if the ELCR agrees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	 *  If it does, we assume it's valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (mpc_default_type == 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		pr_info("ISA/PCI bus type with no IRQ information... falling back to ELCR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		if (ELCR_trigger(0) || ELCR_trigger(1) || ELCR_trigger(2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		    ELCR_trigger(13))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			pr_err("ELCR contains invalid data... not using ELCR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			pr_info("Using ELCR to identify PCI interrupts\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			ELCR_fallback = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		switch (mpc_default_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			if (i == 0 || i == 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 				continue;	/* IRQ0 & IRQ13 not connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 			if (i == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 				continue;	/* IRQ2 is never connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		if (ELCR_fallback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 			 *  If the ELCR indicates a level-sensitive interrupt, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			 *  copy that information over to the MP table in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			 *  irqflag field (level sensitive, active high polarity).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			if (ELCR_trigger(i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				intsrc.irqflag = MP_IRQTRIG_LEVEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 						 MP_IRQPOL_ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 				intsrc.irqflag = MP_IRQTRIG_DEFAULT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 						 MP_IRQPOL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		intsrc.srcbusirq = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		intsrc.dstirq = i ? i : 2;	/* IRQ0 to INTIN2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		mp_save_irq(&intsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	intsrc.irqtype = mp_ExtINT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	intsrc.srcbusirq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	intsrc.dstirq = 0;	/* 8259A to INTIN0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	mp_save_irq(&intsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static void __init construct_ioapic_table(int mpc_default_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	struct mpc_ioapic ioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	struct mpc_bus bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	bus.type = MP_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	bus.busid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	switch (mpc_default_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		pr_err("???\nUnknown standard configuration %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		       mpc_default_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		memcpy(bus.bustype, "ISA   ", 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		memcpy(bus.bustype, "EISA  ", 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	MP_bus_info(&bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	if (mpc_default_type > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		bus.busid = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		memcpy(bus.bustype, "PCI   ", 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		MP_bus_info(&bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	ioapic.type	= MP_IOAPIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	ioapic.apicid	= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	ioapic.apicver	= mpc_default_type > 4 ? 0x10 : 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	ioapic.flags	= MPC_APIC_USABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	ioapic.apicaddr	= IO_APIC_DEFAULT_PHYS_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	MP_ioapic_info(&ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	 * We set up most of the low 16 IO-APIC pins according to MPS rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	construct_default_ioirq_mptable(mpc_default_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static inline void __init construct_ioapic_table(int mpc_default_type) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) static inline void __init construct_default_ISA_mptable(int mpc_default_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	struct mpc_cpu processor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	struct mpc_lintsrc lintsrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	int linttypes[2] = { mp_ExtINT, mp_NMI };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	 * local APIC has default address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	 * 2 CPUs, numbered 0 & 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	processor.type = MP_PROCESSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	/* Either an integrated APIC or a discrete 82489DX. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	processor.apicver = mpc_default_type > 4 ? 0x10 : 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	processor.cpuflag = CPU_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	processor.cpufeature = (boot_cpu_data.x86 << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	    (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_stepping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	processor.featureflag = boot_cpu_data.x86_capability[CPUID_1_EDX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	processor.reserved[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	processor.reserved[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		processor.apicid = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		MP_processor_info(&processor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	construct_ioapic_table(mpc_default_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	lintsrc.type = MP_LINTSRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	lintsrc.irqflag = MP_IRQTRIG_DEFAULT | MP_IRQPOL_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	lintsrc.srcbusid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	lintsrc.srcbusirq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	lintsrc.destapic = MP_APIC_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		lintsrc.irqtype = linttypes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		lintsrc.destapiclint = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		MP_lintsrc_info(&lintsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static unsigned long mpf_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static bool mpf_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static unsigned long __init get_mpc_size(unsigned long physptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct mpc_table *mpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	mpc = early_memremap(physptr, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	size = mpc->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	early_memunmap(mpc, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	apic_printk(APIC_VERBOSE, "  mpc: %lx-%lx\n", physptr, physptr + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	struct mpc_table *mpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	size = get_mpc_size(mpf->physptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	mpc = early_memremap(mpf->physptr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	 * Read the physical hardware table.  Anything here will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	 * override the defaults.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	if (!smp_read_mpc(mpc, early)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) #ifdef CONFIG_X86_LOCAL_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		smp_found_config = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		pr_err("BIOS bug, MP table errors detected!...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		pr_cont("... disabling SMP support. (tell your hw vendor)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		early_memunmap(mpc, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	early_memunmap(mpc, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	if (early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	 * If there are no explicit MP IRQ entries, then we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	 * broken.  We set up most of the low 16 IO-APIC pins to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	 * ISA defaults and hope it will work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	if (!mp_irq_entries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		struct mpc_bus bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		pr_err("BIOS bug, no explicit IRQ entries, using default mptable. (tell your hw vendor)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		bus.type = MP_BUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		bus.busid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		memcpy(bus.bustype, "ISA   ", 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		MP_bus_info(&bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		construct_default_ioirq_mptable(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)  * Scan the memory blocks for an SMP configuration block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) void __init default_get_smp_config(unsigned int early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	struct mpf_intel *mpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	if (!smp_found_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	if (!mpf_found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (acpi_lapic && early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	 * MPS doesn't support hyperthreading, aka only have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	 * thread 0 apic id in MPS table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	if (acpi_lapic && acpi_ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	mpf = early_memremap(mpf_base, sizeof(*mpf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (!mpf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		pr_err("MPTABLE: error mapping MP table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	pr_info("Intel MultiProcessor Specification v1.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		mpf->specification);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (mpf->feature2 & (1 << 7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		pr_info("    IMCR and PIC compatibility mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		pic_mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		pr_info("    Virtual Wire compatibility mode.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		pic_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	 * Now see if we need to read further.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (mpf->feature1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		if (early) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 			 * local APIC has default address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		pr_info("Default MP configuration #%d\n", mpf->feature1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		construct_default_ISA_mptable(mpf->feature1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	} else if (mpf->physptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		if (check_physptr(mpf, early))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	if (!early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		pr_info("Processors: %d\n", num_processors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	 * Only use the first configuration found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	early_memunmap(mpf, sizeof(*mpf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static void __init smp_reserve_memory(struct mpf_intel *mpf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	memblock_reserve(mpf->physptr, get_mpc_size(mpf->physptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static int __init smp_scan_config(unsigned long base, unsigned long length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	unsigned int *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	struct mpf_intel *mpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		    base, base + length - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	BUILD_BUG_ON(sizeof(*mpf) != 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	while (length > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 		bp = early_memremap(base, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		mpf = (struct mpf_intel *)bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		if ((*bp == SMP_MAGIC_IDENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		    (mpf->length == 1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		    !mpf_checksum((unsigned char *)bp, 16) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		    ((mpf->specification == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		     || (mpf->specification == 4))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) #ifdef CONFIG_X86_LOCAL_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 			smp_found_config = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 			mpf_base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 			mpf_found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			pr_info("found SMP MP-table at [mem %#010lx-%#010lx]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 				base, base + sizeof(*mpf) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			memblock_reserve(base, sizeof(*mpf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 			if (mpf->physptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 				smp_reserve_memory(mpf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 			ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		early_memunmap(bp, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		base += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		length -= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) void __init default_find_smp_config(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	unsigned int address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	 * FIXME: Linux assumes you have 640K of base ram..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	 * this continues the error...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	 * 1) Scan the bottom 1K for a signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	 * 2) Scan the top 1K of base RAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	 * 3) Scan the 64K of bios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	if (smp_scan_config(0x0, 0x400) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	    smp_scan_config(639 * 0x400, 0x400) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	    smp_scan_config(0xF0000, 0x10000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	 * If it is an SMP machine we should know now, unless the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	 * configuration is in an EISA bus machine with an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	 * extended bios data area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	 * there is a real-mode segmented pointer pointing to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	 * 4K EBDA area at 0x40E, calculate and scan it here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	 * NOTE! There are Linux loaders that will corrupt the EBDA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	 * area, and as such this kind of SMP config may be less
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	 * trustworthy, simply because the SMP table may have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	 * stomped on during early boot. These loaders are buggy and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	 * should be fixed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	 * MP1.4 SPEC states to only scan first 1K of 4K EBDA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	address = get_bios_ebda();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	if (address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		smp_scan_config(address, 0x400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static u8 __initdata irq_used[MAX_IRQ_SOURCES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int  __init get_MP_intsrc_index(struct mpc_intsrc *m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	if (m->irqtype != mp_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	if (m->irqflag != (MP_IRQTRIG_LEVEL | MP_IRQPOL_ACTIVE_LOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	/* not legacy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	for (i = 0; i < mp_irq_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		if (mp_irqs[i].irqtype != mp_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 		if (mp_irqs[i].irqflag != (MP_IRQTRIG_LEVEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 					   MP_IRQPOL_ACTIVE_LOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 		if (mp_irqs[i].srcbus != m->srcbus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		if (mp_irqs[i].srcbusirq != m->srcbusirq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 		if (irq_used[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			/* already claimed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 			return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		irq_used[i] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	/* not found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) #define SPARE_SLOT_NUM 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	apic_printk(APIC_VERBOSE, "OLD ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	print_mp_irq_info(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	i = get_MP_intsrc_index(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	if (i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		memcpy(m, &mp_irqs[i], sizeof(*m));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		apic_printk(APIC_VERBOSE, "NEW ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		print_mp_irq_info(&mp_irqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	if (!i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		/* legacy, do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	if (*nr_m_spare < SPARE_SLOT_NUM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 		 * not found (-1), or duplicated (-2) are invalid entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		 * we need to use the slot later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		m_spare[*nr_m_spare] = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		*nr_m_spare += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	if (!mpc_new_phys || count <= mpc_new_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) #else /* CONFIG_X86_IO_APIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) #endif /* CONFIG_X86_IO_APIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static int  __init replace_intsrc_all(struct mpc_table *mpc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 					unsigned long mpc_new_phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 					unsigned long mpc_new_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	int count = sizeof(*mpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	int nr_m_spare = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	unsigned char *mpt = ((unsigned char *)mpc) + count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	pr_info("mpc_length %x\n", mpc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	while (count < mpc->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		switch (*mpt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		case MP_PROCESSOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 			skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		case MP_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 			skip_entry(&mpt, &count, sizeof(struct mpc_bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		case MP_IOAPIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 			skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		case MP_INTSRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 			check_irq_src((struct mpc_intsrc *)mpt, &nr_m_spare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 			skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		case MP_LINTSRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 			skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 			/* wrong mptable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 			smp_dump_mptable(mpc, mpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	for (i = 0; i < mp_irq_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		if (irq_used[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		if (mp_irqs[i].irqtype != mp_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		if (mp_irqs[i].irqflag != (MP_IRQTRIG_LEVEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 					   MP_IRQPOL_ACTIVE_LOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		if (nr_m_spare > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 			apic_printk(APIC_VERBOSE, "*NEW* found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			nr_m_spare--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 			memcpy(m_spare[nr_m_spare], &mp_irqs[i], sizeof(mp_irqs[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 			m_spare[nr_m_spare] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 			struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 			count += sizeof(struct mpc_intsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 			if (check_slot(mpc_new_phys, mpc_new_length, count) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			memcpy(m, &mp_irqs[i], sizeof(*m));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 			mpc->length = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			mpt += sizeof(struct mpc_intsrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		print_mp_irq_info(&mp_irqs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	/* update checksum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	mpc->checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	mpc->checksum -= mpf_checksum((unsigned char *)mpc, mpc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) int enable_update_mptable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static int __init update_mptable_setup(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	enable_update_mptable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	pci_routeirq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) early_param("update_mptable", update_mptable_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) static unsigned long __initdata mpc_new_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static unsigned long mpc_new_length __initdata = 4096;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* alloc_mptable or alloc_mptable=4k */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static int __initdata alloc_mptable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static int __init parse_alloc_mptable_opt(char *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	enable_update_mptable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	pci_routeirq = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	alloc_mptable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	mpc_new_length = memparse(p, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) early_param("alloc_mptable", parse_alloc_mptable_opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) void __init e820__memblock_alloc_reserved_mpc_new(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	if (enable_update_mptable && alloc_mptable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 		mpc_new_phys = e820__memblock_alloc_reserved(mpc_new_length, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) static int __init update_mp_table(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	char str[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	char oem[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	struct mpf_intel *mpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	struct mpc_table *mpc, *mpc_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	if (!enable_update_mptable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	if (!mpf_found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	mpf = early_memremap(mpf_base, sizeof(*mpf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 	if (!mpf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		pr_err("MPTABLE: mpf early_memremap() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	 * Now see if we need to go further.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	if (mpf->feature1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		goto do_unmap_mpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	if (!mpf->physptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 		goto do_unmap_mpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	size = get_mpc_size(mpf->physptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	mpc = early_memremap(mpf->physptr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	if (!mpc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		pr_err("MPTABLE: mpc early_memremap() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 		goto do_unmap_mpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	if (!smp_check_mpc(mpc, oem, str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 		goto do_unmap_mpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	pr_info("mpf: %llx\n", (u64)mpf_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	pr_info("physptr: %x\n", mpf->physptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	if (mpc_new_phys && mpc->length > mpc_new_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 		mpc_new_phys = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 		pr_info("mpc_new_length is %ld, please use alloc_mptable=8k\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 			mpc_new_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	if (!mpc_new_phys) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 		unsigned char old, new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		/* check if we can change the position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 		mpc->checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 		old = mpf_checksum((unsigned char *)mpc, mpc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 		mpc->checksum = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 		new = mpf_checksum((unsigned char *)mpc, mpc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 		if (old == new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 			pr_info("mpc is readonly, please try alloc_mptable instead\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 			goto do_unmap_mpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 		pr_info("use in-position replacing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 		mpc_new = early_memremap(mpc_new_phys, mpc_new_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 		if (!mpc_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 			pr_err("MPTABLE: new mpc early_memremap() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 			goto do_unmap_mpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 		mpf->physptr = mpc_new_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 		memcpy(mpc_new, mpc, mpc->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 		early_memunmap(mpc, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		mpc = mpc_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		size = mpc_new_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 		/* check if we can modify that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 		if (mpc_new_phys - mpf->physptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 			struct mpf_intel *mpf_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 			/* steal 16 bytes from [0, 1k) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 			mpf_new = early_memremap(0x400 - 16, sizeof(*mpf_new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 			if (!mpf_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 				pr_err("MPTABLE: new mpf early_memremap() failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 				goto do_unmap_mpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 			pr_info("mpf new: %x\n", 0x400 - 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 			memcpy(mpf_new, mpf, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 			early_memunmap(mpf, sizeof(*mpf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 			mpf = mpf_new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 			mpf->physptr = mpc_new_phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 		mpf->checksum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 		mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 		pr_info("physptr new: %x\n", mpf->physptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	 * only replace the one with mp_INT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 	 *	 MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 	 * already in mp_irqs , stored by ... and mp_config_acpi_gsi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	 * may need pci=routeirq for all coverage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	replace_intsrc_all(mpc, mpc_new_phys, mpc_new_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) do_unmap_mpc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	early_memunmap(mpc, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) do_unmap_mpf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 	early_memunmap(mpf, sizeof(*mpf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) late_initcall(update_mp_table);