···8888 short apic, pin, next;8989} irq_2_pin[PIN_MAP_SIZE];90909191+struct io_apic {9292+ unsigned int index;9393+ unsigned int unused[3];9494+ unsigned int data;9595+};9696+9797+static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)9898+{9999+ return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)100100+ + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK);101101+}102102+103103+static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)104104+{105105+ struct io_apic __iomem *io_apic = io_apic_base(apic);106106+ writel(reg, &io_apic->index);107107+ return readl(&io_apic->data);108108+}109109+110110+static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)111111+{112112+ struct io_apic __iomem *io_apic = io_apic_base(apic);113113+ writel(reg, &io_apic->index);114114+ writel(value, &io_apic->data);115115+}116116+117117+/*118118+ * Re-write a value: to be used for read-modify-write119119+ * cycles where the read already set up the index register.120120+ */121121+static inline void io_apic_modify(unsigned int apic, unsigned int value)122122+{123123+ struct io_apic __iomem *io_apic = io_apic_base(apic);124124+ writel(value, &io_apic->data);125125+}126126+127127+/*128128+ * Synchronize the IO-APIC and the CPU by doing129129+ * a dummy read from the IO-APIC130130+ */131131+static inline void io_apic_sync(unsigned int apic)132132+{133133+ struct io_apic __iomem *io_apic = io_apic_base(apic);134134+ readl(&io_apic->data);135135+}136136+91137#define __DO_ACTION(R, ACTION, FINAL) \92138 \93139{ \···172126 return eu.entry;173127}174128129129+/*130130+ * When we write a new IO APIC routing entry, we need to write the high131131+ * word first! If the mask bit in the low word is clear, we will enable132132+ * the interrupt, and we need to make sure the entry is fully populated133133+ * before that happens.134134+ */175135static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)176136{177137 unsigned long flags;178138 union entry_union eu;179139 eu.entry = e;140140+ spin_lock_irqsave(&ioapic_lock, flags);141141+ io_apic_write(apic, 0x11 + 2*pin, eu.w2);142142+ io_apic_write(apic, 0x10 + 2*pin, eu.w1);143143+ spin_unlock_irqrestore(&ioapic_lock, flags);144144+}145145+146146+/*147147+ * When we mask an IO APIC routing entry, we need to write the low148148+ * word first, in order to set the mask bit before we change the149149+ * high bits!150150+ */151151+static void ioapic_mask_entry(int apic, int pin)152152+{153153+ unsigned long flags;154154+ union entry_union eu = { .entry.mask = 1 };155155+180156 spin_lock_irqsave(&ioapic_lock, flags);181157 io_apic_write(apic, 0x10 + 2*pin, eu.w1);182158 io_apic_write(apic, 0x11 + 2*pin, eu.w2);···324256 /*325257 * Disable it in the IO-APIC irq-routing table:326258 */327327- memset(&entry, 0, sizeof(entry));328328- entry.mask = 1;329329- ioapic_write_entry(apic, pin, entry);259259+ ioapic_mask_entry(apic, pin);330260}331261332262static void clear_IO_APIC (void)
-34
include/asm-x86_64/io_apic.h
···12121313#define APIC_MISMATCH_DEBUG14141515-#define IO_APIC_BASE(idx) \1616- ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \1717- + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK)))1818-1915/*2016 * The structure of the IO-APIC:2117 */···114118115119/* non-0 if default (table-less) MP configuration */116120extern int mpc_default_type;117117-118118-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)119119-{120120- *IO_APIC_BASE(apic) = reg;121121- return *(IO_APIC_BASE(apic)+4);122122-}123123-124124-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)125125-{126126- *IO_APIC_BASE(apic) = reg;127127- *(IO_APIC_BASE(apic)+4) = value;128128-}129129-130130-/*131131- * Re-write a value: to be used for read-modify-write132132- * cycles where the read already set up the index register.133133- */134134-static inline void io_apic_modify(unsigned int apic, unsigned int value)135135-{136136- *(IO_APIC_BASE(apic)+4) = value;137137-}138138-139139-/*140140- * Synchronize the IO-APIC and the CPU by doing141141- * a dummy read from the IO-APIC142142- */143143-static inline void io_apic_sync(unsigned int apic)144144-{145145- (void) *(IO_APIC_BASE(apic)+4);146146-}147121148122/* 1 if "noapic" boot option passed */149123extern int skip_ioapic_setup;