···234extern void setup_local_APIC(void);235extern void end_local_APIC_setup(void);236extern void init_apic_mappings(void);0237extern void setup_boot_APIC_clock(void);238extern void setup_secondary_APIC_clock(void);239extern int APIC_init_uniprocessor(void);···245 * On 32bit this is mach-xxx local246 */247#ifdef CONFIG_X86_64248-extern void early_init_lapic_mapping(void);249extern int apic_is_clustered_box(void);250#else251static inline int apic_is_clustered_box(void)
···234extern void setup_local_APIC(void);235extern void end_local_APIC_setup(void);236extern void init_apic_mappings(void);237+void register_lapic_address(unsigned long address);238extern void setup_boot_APIC_clock(void);239extern void setup_secondary_APIC_clock(void);240extern int APIC_init_uniprocessor(void);···244 * On 32bit this is mach-xxx local245 */246#ifdef CONFIG_X86_640247extern int apic_is_clustered_box(void);248#else249static inline int apic_is_clustered_box(void)
···1191 oldvalue, value);1192}11931194-1195/**1196 * setup_local_APIC - setup the local APIC0001197 */1198void __cpuinit setup_local_APIC(void)1199{01200 unsigned int value, queued;1201 int i, j, acked = 0;1202 unsigned long long tsc = 0, ntsc;···1223 }1224#endif1225 perf_events_lapic_init();1226-1227- preempt_disable();12281229 /*1230 * Double-check whether this APIC is really registered.···1339 * TODO: set up through-local-APIC from through-I/O-APIC? --macro1340 */1341 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;1342- if (!smp_processor_id() && (pic_mode || !value)) {1343 value = APIC_DM_EXTINT;1344- apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",1345- smp_processor_id());1346 } else {1347 value = APIC_DM_EXTINT | APIC_LVT_MASKED;1348- apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",1349- smp_processor_id());1350 }1351 apic_write(APIC_LVT0, value);13521353 /*1354 * only the BP should see the LINT1 NMI signal, obviously.1355 */1356- if (!smp_processor_id())1357 value = APIC_DM_NMI;1358 else1359 value = APIC_DM_NMI | APIC_LVT_MASKED;···1359 value |= APIC_LVT_LEVEL_TRIGGER;1360 apic_write(APIC_LVT1, value);13611362- preempt_enable();1363-1364#ifdef CONFIG_X86_MCE_INTEL1365 /* Recheck CMCI information after local APIC is up on CPU #0 */1366- if (smp_processor_id() == 0)1367 cmci_recheck();1368#endif1369}···1630}1631#endif16321633-#ifdef CONFIG_X86_641634-void __init early_init_lapic_mapping(void)1635-{1636- /*1637- * If no local APIC can be found then go out1638- * : it means there is no mpatable and MADT1639- */1640- if (!smp_found_config)1641- return;1642-1643- set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);1644- apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",1645- APIC_BASE, mp_lapic_addr);1646-1647- /*1648- * Fetch the APIC ID of the BSP in case we have a1649- * default configuration (or the MP table is broken).1650- */1651- boot_cpu_physical_apicid = read_apic_id();1652-}1653-#endif1654-1655/**1656 * init_apic_mappings - initialize APIC mappings1657 */···1655 * acpi_register_lapic_address()1656 */1657 if (!acpi_lapic && !smp_found_config)1658- set_fixmap_nocache(FIX_APIC_BASE, apic_phys);1659-1660- apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",1661- APIC_BASE, apic_phys);1662 }16631664 /*···1673 * and disable smp mode1674 */1675 apic_version[new_apicid] =00000000000000001676 GET_APIC_VERSION(apic_read(APIC_LVR));1677 }1678}
···1191 oldvalue, value);1192}119301194/**1195 * setup_local_APIC - setup the local APIC1196+ *1197+ * Used to setup local APIC while initializing BSP or bringin up APs.1198+ * Always called with preemption disabled.1199 */1200void __cpuinit setup_local_APIC(void)1201{1202+ int cpu = smp_processor_id();1203 unsigned int value, queued;1204 int i, j, acked = 0;1205 unsigned long long tsc = 0, ntsc;···1220 }1221#endif1222 perf_events_lapic_init();0012231224 /*1225 * Double-check whether this APIC is really registered.···1338 * TODO: set up through-local-APIC from through-I/O-APIC? --macro1339 */1340 value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;1341+ if (!cpu && (pic_mode || !value)) {1342 value = APIC_DM_EXTINT;1343+ apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);01344 } else {1345 value = APIC_DM_EXTINT | APIC_LVT_MASKED;1346+ apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);01347 }1348 apic_write(APIC_LVT0, value);13491350 /*1351 * only the BP should see the LINT1 NMI signal, obviously.1352 */1353+ if (!cpu)1354 value = APIC_DM_NMI;1355 else1356 value = APIC_DM_NMI | APIC_LVT_MASKED;···1360 value |= APIC_LVT_LEVEL_TRIGGER;1361 apic_write(APIC_LVT1, value);1362001363#ifdef CONFIG_X86_MCE_INTEL1364 /* Recheck CMCI information after local APIC is up on CPU #0 */1365+ if (!cpu)1366 cmci_recheck();1367#endif1368}···1633}1634#endif163500000000000000000000001636/**1637 * init_apic_mappings - initialize APIC mappings1638 */···1680 * acpi_register_lapic_address()1681 */1682 if (!acpi_lapic && !smp_found_config)1683+ register_lapic_address(apic_phys);0001684 }16851686 /*···1701 * and disable smp mode1702 */1703 apic_version[new_apicid] =1704+ GET_APIC_VERSION(apic_read(APIC_LVR));1705+ }1706+}1707+1708+void __init register_lapic_address(unsigned long address)1709+{1710+ mp_lapic_addr = address;1711+1712+ if (!x2apic_mode) {1713+ set_fixmap_nocache(FIX_APIC_BASE, address);1714+ apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",1715+ APIC_BASE, mp_lapic_addr);1716+ }1717+ if (boot_cpu_physical_apicid == -1U) {1718+ boot_cpu_physical_apicid = read_apic_id();1719+ apic_version[boot_cpu_physical_apicid] =1720 GET_APIC_VERSION(apic_read(APIC_LVR));1721 }1722}
+26-2
arch/x86/kernel/apic/io_apic.c
···125}126early_param("noapic", parse_noapic);12700000000000000000000128struct irq_pin_list {129 int apic, pin;130 struct irq_pin_list *next;···154{155 return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);156}0157158/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */159#ifdef CONFIG_SPARSE_IRQ···2027 = mp_ioapics[apic_id].apicid;20282029 /*2030- * Read the right value from the MPC table and2031- * write it into the ID register.2032 */0002033 apic_printk(APIC_VERBOSE, KERN_INFO2034 "...changing IO-APIC physical APIC ID to %d ...",2035 mp_ioapics[apic_id].apicid);
···125}126early_param("noapic", parse_noapic);127128+/* Will be called in mpparse/acpi/sfi codes for saving IRQ info */129+void mp_save_irq(struct mpc_intsrc *m)130+{131+ int i;132+133+ apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"134+ " IRQ %02x, APIC ID %x, APIC INT %02x\n",135+ m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus,136+ m->srcbusirq, m->dstapic, m->dstirq);137+138+ for (i = 0; i < mp_irq_entries; i++) {139+ if (!memcmp(&mp_irqs[i], m, sizeof(*m)))140+ return;141+ }142+143+ memcpy(&mp_irqs[mp_irq_entries], m, sizeof(*m));144+ if (++mp_irq_entries == MAX_IRQ_SOURCES)145+ panic("Max # of irq sources exceeded!!\n");146+}147+148struct irq_pin_list {149 int apic, pin;150 struct irq_pin_list *next;···134{135 return kzalloc_node(sizeof(struct irq_pin_list), GFP_KERNEL, node);136}137+138139/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */140#ifdef CONFIG_SPARSE_IRQ···2006 = mp_ioapics[apic_id].apicid;20072008 /*2009+ * Update the ID register according to the right value2010+ * from the MPC table if they are different.2011 */2012+ if (mp_ioapics[apic_id].apicid == reg_00.bits.ID)2013+ continue;2014+2015 apic_printk(APIC_VERBOSE, KERN_INFO2016 "...changing IO-APIC physical APIC ID to %d ...",2017 mp_ioapics[apic_id].apicid);
+11-103
arch/x86/kernel/mpparse.c
···118119static void __init MP_ioapic_info(struct mpc_ioapic *m)120{121- if (!(m->flags & MPC_APIC_USABLE))122- return;123-124- printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",125- m->apicid, m->apicver, m->apicaddr);126-127- mp_register_ioapic(m->apicid, m->apicaddr, gsi_top);128-}129-130-static void print_MP_intsrc_info(struct mpc_intsrc *m)131-{132- apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"133- " IRQ %02x, APIC ID %x, APIC INT %02x\n",134- m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus,135- m->srcbusirq, m->dstapic, m->dstirq);136}137138static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)···131 mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);132}133134-static void __init assign_to_mp_irq(struct mpc_intsrc *m,135- struct mpc_intsrc *mp_irq)136-{137- mp_irq->dstapic = m->dstapic;138- mp_irq->type = m->type;139- mp_irq->irqtype = m->irqtype;140- mp_irq->irqflag = m->irqflag;141- mp_irq->srcbus = m->srcbus;142- mp_irq->srcbusirq = m->srcbusirq;143- mp_irq->dstirq = m->dstirq;144-}145-146-static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq,147- struct mpc_intsrc *m)148-{149- m->dstapic = mp_irq->dstapic;150- m->type = mp_irq->type;151- m->irqtype = mp_irq->irqtype;152- m->irqflag = mp_irq->irqflag;153- m->srcbus = mp_irq->srcbus;154- m->srcbusirq = mp_irq->srcbusirq;155- m->dstirq = mp_irq->dstirq;156-}157-158-static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq,159- struct mpc_intsrc *m)160-{161- if (mp_irq->dstapic != m->dstapic)162- return 1;163- if (mp_irq->type != m->type)164- return 2;165- if (mp_irq->irqtype != m->irqtype)166- return 3;167- if (mp_irq->irqflag != m->irqflag)168- return 4;169- if (mp_irq->srcbus != m->srcbus)170- return 5;171- if (mp_irq->srcbusirq != m->srcbusirq)172- return 6;173- if (mp_irq->dstirq != m->dstirq)174- return 7;175-176- return 0;177-}178-179-static void __init MP_intsrc_info(struct mpc_intsrc *m)180-{181- int i;182-183- print_MP_intsrc_info(m);184-185- for (i = 0; i < mp_irq_entries; i++) {186- if (!mp_irq_mpc_intsrc_cmp(&mp_irqs[i], m))187- return;188- }189-190- assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);191- if (++mp_irq_entries == MAX_IRQ_SOURCES)192- panic("Max # of irq sources exceeded!!\n");193-}194#else /* CONFIG_X86_IO_APIC */195static inline void __init MP_bus_info(struct mpc_bus *m) {}196static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}197-static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}198#endif /* CONFIG_X86_IO_APIC */199-200201static void __init MP_lintsrc_info(struct mpc_lintsrc *m)202{···147/*148 * Read/parse the MPC149 */150-151static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)152{153···199200void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }201202-static void __init smp_register_lapic_address(unsigned long address)203-{204- mp_lapic_addr = address;205-206- set_fixmap_nocache(FIX_APIC_BASE, address);207- if (boot_cpu_physical_apicid == -1U) {208- boot_cpu_physical_apicid = read_apic_id();209- apic_version[boot_cpu_physical_apicid] =210- GET_APIC_VERSION(apic_read(APIC_LVR));211- }212-}213-214static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)215{216 char str[16];···213#ifdef CONFIG_X86_32214 generic_mps_oem_check(mpc, oem, str);215#endif216- /* save the local APIC address, it might be non-default */217 if (!acpi_lapic)218- mp_lapic_addr = mpc->lapic;219220 if (early)221 return 1;222-223- /* Initialize the lapic mapping */224- if (!acpi_lapic)225- smp_register_lapic_address(mpc->lapic);226227 if (mpc->oemptr)228 x86_init.mpparse.smp_read_mpc_oem(mpc);···245 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));246 break;247 case MP_INTSRC:248- MP_intsrc_info((struct mpc_intsrc *)mpt);249 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));250 break;251 case MP_LINTSRC:···337338 intsrc.srcbusirq = i;339 intsrc.dstirq = i ? i : 2; /* IRQ0 to INTIN2 */340- MP_intsrc_info(&intsrc);341 }342343 intsrc.irqtype = mp_ExtINT;344 intsrc.srcbusirq = 0;345 intsrc.dstirq = 0; /* 8259A to INTIN0 */346- MP_intsrc_info(&intsrc);347}348349···692 int i;693694 apic_printk(APIC_VERBOSE, "OLD ");695- print_MP_intsrc_info(m);696697 i = get_MP_intsrc_index(m);698 if (i > 0) {699- assign_to_mpc_intsrc(&mp_irqs[i], m);700 apic_printk(APIC_VERBOSE, "NEW ");701 print_mp_irq_info(&mp_irqs[i]);702 return;···783 if (nr_m_spare > 0) {784 apic_printk(APIC_VERBOSE, "*NEW* found\n");785 nr_m_spare--;786- assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]);787 m_spare[nr_m_spare] = NULL;788 } else {789 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;790 count += sizeof(struct mpc_intsrc);791 if (check_slot(mpc_new_phys, mpc_new_length, count) < 0)792 goto out;793- assign_to_mpc_intsrc(&mp_irqs[i], m);794 mpc->length = count;795 mpt += sizeof(struct mpc_intsrc);796 }