^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);