|
@@ -114,6 +114,9 @@ DEFINE_SPINLOCK(vector_lock);
|
|
|
*/
|
|
|
int nr_ioapic_registers[MAX_IO_APICS];
|
|
|
|
|
|
+/* I/O APIC RTE contents at the OS boot up */
|
|
|
+struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
|
|
|
+
|
|
|
/* I/O APIC entries */
|
|
|
struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
|
|
|
int nr_ioapics;
|
|
@@ -446,6 +449,69 @@ static void clear_IO_APIC (void)
|
|
|
clear_IO_APIC_pin(apic, pin);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Saves and masks all the unmasked IO-APIC RTE's
|
|
|
+ */
|
|
|
+int save_mask_IO_APIC_setup(void)
|
|
|
+{
|
|
|
+ union IO_APIC_reg_01 reg_01;
|
|
|
+ unsigned long flags;
|
|
|
+ int apic, pin;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The number of IO-APIC IRQ registers (== #pins):
|
|
|
+ */
|
|
|
+ for (apic = 0; apic < nr_ioapics; apic++) {
|
|
|
+ spin_lock_irqsave(&ioapic_lock, flags);
|
|
|
+ reg_01.raw = io_apic_read(apic, 1);
|
|
|
+ spin_unlock_irqrestore(&ioapic_lock, flags);
|
|
|
+ nr_ioapic_registers[apic] = reg_01.bits.entries+1;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (apic = 0; apic < nr_ioapics; apic++) {
|
|
|
+ early_ioapic_entries[apic] =
|
|
|
+ kzalloc(sizeof(struct IO_APIC_route_entry) *
|
|
|
+ nr_ioapic_registers[apic], GFP_KERNEL);
|
|
|
+ if (!early_ioapic_entries[apic])
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (apic = 0; apic < nr_ioapics; apic++)
|
|
|
+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
|
|
|
+ struct IO_APIC_route_entry entry;
|
|
|
+
|
|
|
+ entry = early_ioapic_entries[apic][pin] =
|
|
|
+ ioapic_read_entry(apic, pin);
|
|
|
+ if (!entry.mask) {
|
|
|
+ entry.mask = 1;
|
|
|
+ ioapic_write_entry(apic, pin, entry);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void restore_IO_APIC_setup(void)
|
|
|
+{
|
|
|
+ int apic, pin;
|
|
|
+
|
|
|
+ for (apic = 0; apic < nr_ioapics; apic++)
|
|
|
+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
|
|
|
+ ioapic_write_entry(apic, pin,
|
|
|
+ early_ioapic_entries[apic][pin]);
|
|
|
+}
|
|
|
+
|
|
|
+void reinit_intr_remapped_IO_APIC(int intr_remapping)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * for now plain restore of previous settings.
|
|
|
+ * TBD: In the case of OS enabling interrupt-remapping,
|
|
|
+ * IO-APIC RTE's need to be setup to point to interrupt-remapping
|
|
|
+ * table entries. for now, do a plain restore, and wait for
|
|
|
+ * the setup_IO_APIC_irqs() to do proper initialization.
|
|
|
+ */
|
|
|
+ restore_IO_APIC_setup();
|
|
|
+}
|
|
|
+
|
|
|
int skip_ioapic_setup;
|
|
|
int ioapic_force;
|
|
|
|