diff options
Diffstat (limited to 'arch/x86/kernel/apic/io_apic.c')
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 319 |
1 files changed, 135 insertions, 184 deletions
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 68df09bba92e..9488dcff7aec 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -76,17 +76,40 @@ int sis_apic_bug = -1; | |||
76 | static DEFINE_RAW_SPINLOCK(ioapic_lock); | 76 | static DEFINE_RAW_SPINLOCK(ioapic_lock); |
77 | static DEFINE_RAW_SPINLOCK(vector_lock); | 77 | static DEFINE_RAW_SPINLOCK(vector_lock); |
78 | 78 | ||
79 | /* | 79 | static struct ioapic { |
80 | * # of IRQ routing registers | 80 | /* |
81 | */ | 81 | * # of IRQ routing registers |
82 | int nr_ioapic_registers[MAX_IO_APICS]; | 82 | */ |
83 | int nr_registers; | ||
84 | /* | ||
85 | * Saved state during suspend/resume, or while enabling intr-remap. | ||
86 | */ | ||
87 | struct IO_APIC_route_entry *saved_registers; | ||
88 | /* I/O APIC config */ | ||
89 | struct mpc_ioapic mp_config; | ||
90 | /* IO APIC gsi routing info */ | ||
91 | struct mp_ioapic_gsi gsi_config; | ||
92 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); | ||
93 | } ioapics[MAX_IO_APICS]; | ||
83 | 94 | ||
84 | /* I/O APIC entries */ | 95 | #define mpc_ioapic_ver(id) ioapics[id].mp_config.apicver |
85 | struct mpc_ioapic mp_ioapics[MAX_IO_APICS]; | 96 | |
86 | int nr_ioapics; | 97 | int mpc_ioapic_id(int id) |
98 | { | ||
99 | return ioapics[id].mp_config.apicid; | ||
100 | } | ||
87 | 101 | ||
88 | /* IO APIC gsi routing info */ | 102 | unsigned int mpc_ioapic_addr(int id) |
89 | struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; | 103 | { |
104 | return ioapics[id].mp_config.apicaddr; | ||
105 | } | ||
106 | |||
107 | struct mp_ioapic_gsi *mp_ioapic_gsi_routing(int id) | ||
108 | { | ||
109 | return &ioapics[id].gsi_config; | ||
110 | } | ||
111 | |||
112 | int nr_ioapics; | ||
90 | 113 | ||
91 | /* The one past the highest gsi number used */ | 114 | /* The one past the highest gsi number used */ |
92 | u32 gsi_top; | 115 | u32 gsi_top; |
@@ -128,8 +151,8 @@ static int __init parse_noapic(char *str) | |||
128 | } | 151 | } |
129 | early_param("noapic", parse_noapic); | 152 | early_param("noapic", parse_noapic); |
130 | 153 | ||
131 | static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | 154 | static int io_apic_setup_irq_pin(unsigned int irq, int node, |
132 | struct io_apic_irq_attr *attr); | 155 | struct io_apic_irq_attr *attr); |
133 | 156 | ||
134 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ | 157 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ |
135 | void mp_save_irq(struct mpc_intsrc *m) | 158 | void mp_save_irq(struct mpc_intsrc *m) |
@@ -179,6 +202,14 @@ int __init arch_early_irq_init(void) | |||
179 | io_apic_irqs = ~0UL; | 202 | io_apic_irqs = ~0UL; |
180 | } | 203 | } |
181 | 204 | ||
205 | for (i = 0; i < nr_ioapics; i++) { | ||
206 | ioapics[i].saved_registers = | ||
207 | kzalloc(sizeof(struct IO_APIC_route_entry) * | ||
208 | ioapics[i].nr_registers, GFP_KERNEL); | ||
209 | if (!ioapics[i].saved_registers) | ||
210 | pr_err("IOAPIC %d: suspend/resume impossible!\n", i); | ||
211 | } | ||
212 | |||
182 | cfg = irq_cfgx; | 213 | cfg = irq_cfgx; |
183 | count = ARRAY_SIZE(irq_cfgx); | 214 | count = ARRAY_SIZE(irq_cfgx); |
184 | node = cpu_to_node(0); | 215 | node = cpu_to_node(0); |
@@ -297,7 +328,7 @@ struct io_apic { | |||
297 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) | 328 | static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) |
298 | { | 329 | { |
299 | return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) | 330 | return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) |
300 | + (mp_ioapics[idx].apicaddr & ~PAGE_MASK); | 331 | + (mpc_ioapic_addr(idx) & ~PAGE_MASK); |
301 | } | 332 | } |
302 | 333 | ||
303 | static inline void io_apic_eoi(unsigned int apic, unsigned int vector) | 334 | static inline void io_apic_eoi(unsigned int apic, unsigned int vector) |
@@ -573,7 +604,7 @@ static void clear_IO_APIC (void) | |||
573 | int apic, pin; | 604 | int apic, pin; |
574 | 605 | ||
575 | for (apic = 0; apic < nr_ioapics; apic++) | 606 | for (apic = 0; apic < nr_ioapics; apic++) |
576 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | 607 | for (pin = 0; pin < ioapics[apic].nr_registers; pin++) |
577 | clear_IO_APIC_pin(apic, pin); | 608 | clear_IO_APIC_pin(apic, pin); |
578 | } | 609 | } |
579 | 610 | ||
@@ -615,74 +646,43 @@ static int __init ioapic_pirq_setup(char *str) | |||
615 | __setup("pirq=", ioapic_pirq_setup); | 646 | __setup("pirq=", ioapic_pirq_setup); |
616 | #endif /* CONFIG_X86_32 */ | 647 | #endif /* CONFIG_X86_32 */ |
617 | 648 | ||
618 | struct IO_APIC_route_entry **alloc_ioapic_entries(void) | ||
619 | { | ||
620 | int apic; | ||
621 | struct IO_APIC_route_entry **ioapic_entries; | ||
622 | |||
623 | ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics, | ||
624 | GFP_KERNEL); | ||
625 | if (!ioapic_entries) | ||
626 | return 0; | ||
627 | |||
628 | for (apic = 0; apic < nr_ioapics; apic++) { | ||
629 | ioapic_entries[apic] = | ||
630 | kzalloc(sizeof(struct IO_APIC_route_entry) * | ||
631 | nr_ioapic_registers[apic], GFP_KERNEL); | ||
632 | if (!ioapic_entries[apic]) | ||
633 | goto nomem; | ||
634 | } | ||
635 | |||
636 | return ioapic_entries; | ||
637 | |||
638 | nomem: | ||
639 | while (--apic >= 0) | ||
640 | kfree(ioapic_entries[apic]); | ||
641 | kfree(ioapic_entries); | ||
642 | |||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | /* | 649 | /* |
647 | * Saves all the IO-APIC RTE's | 650 | * Saves all the IO-APIC RTE's |
648 | */ | 651 | */ |
649 | int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | 652 | int save_ioapic_entries(void) |
650 | { | 653 | { |
651 | int apic, pin; | 654 | int apic, pin; |
652 | 655 | int err = 0; | |
653 | if (!ioapic_entries) | ||
654 | return -ENOMEM; | ||
655 | 656 | ||
656 | for (apic = 0; apic < nr_ioapics; apic++) { | 657 | for (apic = 0; apic < nr_ioapics; apic++) { |
657 | if (!ioapic_entries[apic]) | 658 | if (!ioapics[apic].saved_registers) { |
658 | return -ENOMEM; | 659 | err = -ENOMEM; |
660 | continue; | ||
661 | } | ||
659 | 662 | ||
660 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | 663 | for (pin = 0; pin < ioapics[apic].nr_registers; pin++) |
661 | ioapic_entries[apic][pin] = | 664 | ioapics[apic].saved_registers[pin] = |
662 | ioapic_read_entry(apic, pin); | 665 | ioapic_read_entry(apic, pin); |
663 | } | 666 | } |
664 | 667 | ||
665 | return 0; | 668 | return err; |
666 | } | 669 | } |
667 | 670 | ||
668 | /* | 671 | /* |
669 | * Mask all IO APIC entries. | 672 | * Mask all IO APIC entries. |
670 | */ | 673 | */ |
671 | void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | 674 | void mask_ioapic_entries(void) |
672 | { | 675 | { |
673 | int apic, pin; | 676 | int apic, pin; |
674 | 677 | ||
675 | if (!ioapic_entries) | ||
676 | return; | ||
677 | |||
678 | for (apic = 0; apic < nr_ioapics; apic++) { | 678 | for (apic = 0; apic < nr_ioapics; apic++) { |
679 | if (!ioapic_entries[apic]) | 679 | if (ioapics[apic].saved_registers) |
680 | break; | 680 | continue; |
681 | 681 | ||
682 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 682 | for (pin = 0; pin < ioapics[apic].nr_registers; pin++) { |
683 | struct IO_APIC_route_entry entry; | 683 | struct IO_APIC_route_entry entry; |
684 | 684 | ||
685 | entry = ioapic_entries[apic][pin]; | 685 | entry = ioapics[apic].saved_registers[pin]; |
686 | if (!entry.mask) { | 686 | if (!entry.mask) { |
687 | entry.mask = 1; | 687 | entry.mask = 1; |
688 | ioapic_write_entry(apic, pin, entry); | 688 | ioapic_write_entry(apic, pin, entry); |
@@ -692,36 +692,23 @@ void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | |||
692 | } | 692 | } |
693 | 693 | ||
694 | /* | 694 | /* |
695 | * Restore IO APIC entries which was saved in ioapic_entries. | 695 | * Restore IO APIC entries which was saved in the ioapic structure. |
696 | */ | 696 | */ |
697 | int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries) | 697 | int restore_ioapic_entries(void) |
698 | { | 698 | { |
699 | int apic, pin; | 699 | int apic, pin; |
700 | 700 | ||
701 | if (!ioapic_entries) | ||
702 | return -ENOMEM; | ||
703 | |||
704 | for (apic = 0; apic < nr_ioapics; apic++) { | 701 | for (apic = 0; apic < nr_ioapics; apic++) { |
705 | if (!ioapic_entries[apic]) | 702 | if (ioapics[apic].saved_registers) |
706 | return -ENOMEM; | 703 | continue; |
707 | 704 | ||
708 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | 705 | for (pin = 0; pin < ioapics[apic].nr_registers; pin++) |
709 | ioapic_write_entry(apic, pin, | 706 | ioapic_write_entry(apic, pin, |
710 | ioapic_entries[apic][pin]); | 707 | ioapics[apic].saved_registers[pin]); |
711 | } | 708 | } |
712 | return 0; | 709 | return 0; |
713 | } | 710 | } |
714 | 711 | ||
715 | void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries) | ||
716 | { | ||
717 | int apic; | ||
718 | |||
719 | for (apic = 0; apic < nr_ioapics; apic++) | ||
720 | kfree(ioapic_entries[apic]); | ||
721 | |||
722 | kfree(ioapic_entries); | ||
723 | } | ||
724 | |||
725 | /* | 712 | /* |
726 | * Find the IRQ entry number of a certain pin. | 713 | * Find the IRQ entry number of a certain pin. |
727 | */ | 714 | */ |
@@ -731,7 +718,7 @@ static int find_irq_entry(int apic, int pin, int type) | |||
731 | 718 | ||
732 | for (i = 0; i < mp_irq_entries; i++) | 719 | for (i = 0; i < mp_irq_entries; i++) |
733 | if (mp_irqs[i].irqtype == type && | 720 | if (mp_irqs[i].irqtype == type && |
734 | (mp_irqs[i].dstapic == mp_ioapics[apic].apicid || | 721 | (mp_irqs[i].dstapic == mpc_ioapic_id(apic) || |
735 | mp_irqs[i].dstapic == MP_APIC_ALL) && | 722 | mp_irqs[i].dstapic == MP_APIC_ALL) && |
736 | mp_irqs[i].dstirq == pin) | 723 | mp_irqs[i].dstirq == pin) |
737 | return i; | 724 | return i; |
@@ -773,7 +760,7 @@ static int __init find_isa_irq_apic(int irq, int type) | |||
773 | if (i < mp_irq_entries) { | 760 | if (i < mp_irq_entries) { |
774 | int apic; | 761 | int apic; |
775 | for(apic = 0; apic < nr_ioapics; apic++) { | 762 | for(apic = 0; apic < nr_ioapics; apic++) { |
776 | if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic) | 763 | if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic) |
777 | return apic; | 764 | return apic; |
778 | } | 765 | } |
779 | } | 766 | } |
@@ -942,6 +929,7 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
942 | { | 929 | { |
943 | int irq; | 930 | int irq; |
944 | int bus = mp_irqs[idx].srcbus; | 931 | int bus = mp_irqs[idx].srcbus; |
932 | struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic); | ||
945 | 933 | ||
946 | /* | 934 | /* |
947 | * Debugging check, we are in big trouble if this message pops up! | 935 | * Debugging check, we are in big trouble if this message pops up! |
@@ -952,7 +940,7 @@ static int pin_2_irq(int idx, int apic, int pin) | |||
952 | if (test_bit(bus, mp_bus_not_pci)) { | 940 | if (test_bit(bus, mp_bus_not_pci)) { |
953 | irq = mp_irqs[idx].srcbusirq; | 941 | irq = mp_irqs[idx].srcbusirq; |
954 | } else { | 942 | } else { |
955 | u32 gsi = mp_gsi_routing[apic].gsi_base + pin; | 943 | u32 gsi = gsi_cfg->gsi_base + pin; |
956 | 944 | ||
957 | if (gsi >= NR_IRQS_LEGACY) | 945 | if (gsi >= NR_IRQS_LEGACY) |
958 | irq = gsi; | 946 | irq = gsi; |
@@ -1003,7 +991,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, | |||
1003 | int lbus = mp_irqs[i].srcbus; | 991 | int lbus = mp_irqs[i].srcbus; |
1004 | 992 | ||
1005 | for (apic = 0; apic < nr_ioapics; apic++) | 993 | for (apic = 0; apic < nr_ioapics; apic++) |
1006 | if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic || | 994 | if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic || |
1007 | mp_irqs[i].dstapic == MP_APIC_ALL) | 995 | mp_irqs[i].dstapic == MP_APIC_ALL) |
1008 | break; | 996 | break; |
1009 | 997 | ||
@@ -1222,7 +1210,7 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1222 | int apic, idx, pin; | 1210 | int apic, idx, pin; |
1223 | 1211 | ||
1224 | for (apic = 0; apic < nr_ioapics; apic++) { | 1212 | for (apic = 0; apic < nr_ioapics; apic++) { |
1225 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 1213 | for (pin = 0; pin < ioapics[apic].nr_registers; pin++) { |
1226 | idx = find_irq_entry(apic, pin, mp_INT); | 1214 | idx = find_irq_entry(apic, pin, mp_INT); |
1227 | if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) | 1215 | if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin))) |
1228 | return irq_trigger(idx); | 1216 | return irq_trigger(idx); |
@@ -1350,14 +1338,14 @@ static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq, | |||
1350 | apic_printk(APIC_VERBOSE,KERN_DEBUG | 1338 | apic_printk(APIC_VERBOSE,KERN_DEBUG |
1351 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " | 1339 | "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> " |
1352 | "IRQ %d Mode:%i Active:%i)\n", | 1340 | "IRQ %d Mode:%i Active:%i)\n", |
1353 | apic_id, mp_ioapics[apic_id].apicid, pin, cfg->vector, | 1341 | apic_id, mpc_ioapic_id(apic_id), pin, cfg->vector, |
1354 | irq, trigger, polarity); | 1342 | irq, trigger, polarity); |
1355 | 1343 | ||
1356 | 1344 | ||
1357 | if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry, | 1345 | if (setup_ioapic_entry(mpc_ioapic_id(apic_id), irq, &entry, |
1358 | dest, trigger, polarity, cfg->vector, pin)) { | 1346 | dest, trigger, polarity, cfg->vector, pin)) { |
1359 | printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", | 1347 | printk("Failed to setup ioapic entry for ioapic %d, pin %d\n", |
1360 | mp_ioapics[apic_id].apicid, pin); | 1348 | mpc_ioapic_id(apic_id), pin); |
1361 | __clear_irq_vector(irq, cfg); | 1349 | __clear_irq_vector(irq, cfg); |
1362 | return; | 1350 | return; |
1363 | } | 1351 | } |
@@ -1369,17 +1357,13 @@ static void setup_ioapic_irq(int apic_id, int pin, unsigned int irq, | |||
1369 | ioapic_write_entry(apic_id, pin, entry); | 1357 | ioapic_write_entry(apic_id, pin, entry); |
1370 | } | 1358 | } |
1371 | 1359 | ||
1372 | static struct { | ||
1373 | DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1); | ||
1374 | } mp_ioapic_routing[MAX_IO_APICS]; | ||
1375 | |||
1376 | static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin) | 1360 | static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin) |
1377 | { | 1361 | { |
1378 | if (idx != -1) | 1362 | if (idx != -1) |
1379 | return false; | 1363 | return false; |
1380 | 1364 | ||
1381 | apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", | 1365 | apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n", |
1382 | mp_ioapics[apic_id].apicid, pin); | 1366 | mpc_ioapic_id(apic_id), pin); |
1383 | return true; | 1367 | return true; |
1384 | } | 1368 | } |
1385 | 1369 | ||
@@ -1389,7 +1373,7 @@ static void __init __io_apic_setup_irqs(unsigned int apic_id) | |||
1389 | struct io_apic_irq_attr attr; | 1373 | struct io_apic_irq_attr attr; |
1390 | unsigned int pin, irq; | 1374 | unsigned int pin, irq; |
1391 | 1375 | ||
1392 | for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) { | 1376 | for (pin = 0; pin < ioapics[apic_id].nr_registers; pin++) { |
1393 | idx = find_irq_entry(apic_id, pin, mp_INT); | 1377 | idx = find_irq_entry(apic_id, pin, mp_INT); |
1394 | if (io_apic_pin_not_connected(idx, apic_id, pin)) | 1378 | if (io_apic_pin_not_connected(idx, apic_id, pin)) |
1395 | continue; | 1379 | continue; |
@@ -1511,7 +1495,7 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
1511 | printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); | 1495 | printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries); |
1512 | for (i = 0; i < nr_ioapics; i++) | 1496 | for (i = 0; i < nr_ioapics; i++) |
1513 | printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", | 1497 | printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n", |
1514 | mp_ioapics[i].apicid, nr_ioapic_registers[i]); | 1498 | mpc_ioapic_id(i), ioapics[i].nr_registers); |
1515 | 1499 | ||
1516 | /* | 1500 | /* |
1517 | * We are a bit conservative about what we expect. We have to | 1501 | * We are a bit conservative about what we expect. We have to |
@@ -1531,7 +1515,7 @@ __apicdebuginit(void) print_IO_APIC(void) | |||
1531 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1515 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
1532 | 1516 | ||
1533 | printk("\n"); | 1517 | printk("\n"); |
1534 | printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid); | 1518 | printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(apic)); |
1535 | printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); | 1519 | printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw); |
1536 | printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); | 1520 | printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID); |
1537 | printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); | 1521 | printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type); |
@@ -1825,7 +1809,7 @@ void __init enable_IO_APIC(void) | |||
1825 | for(apic = 0; apic < nr_ioapics; apic++) { | 1809 | for(apic = 0; apic < nr_ioapics; apic++) { |
1826 | int pin; | 1810 | int pin; |
1827 | /* See if any of the pins is in ExtINT mode */ | 1811 | /* See if any of the pins is in ExtINT mode */ |
1828 | for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | 1812 | for (pin = 0; pin < ioapics[apic].nr_registers; pin++) { |
1829 | struct IO_APIC_route_entry entry; | 1813 | struct IO_APIC_route_entry entry; |
1830 | entry = ioapic_read_entry(apic, pin); | 1814 | entry = ioapic_read_entry(apic, pin); |
1831 | 1815 | ||
@@ -1949,14 +1933,14 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) | |||
1949 | reg_00.raw = io_apic_read(apic_id, 0); | 1933 | reg_00.raw = io_apic_read(apic_id, 0); |
1950 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1934 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
1951 | 1935 | ||
1952 | old_id = mp_ioapics[apic_id].apicid; | 1936 | old_id = mpc_ioapic_id(apic_id); |
1953 | 1937 | ||
1954 | if (mp_ioapics[apic_id].apicid >= get_physical_broadcast()) { | 1938 | if (mpc_ioapic_id(apic_id) >= get_physical_broadcast()) { |
1955 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", | 1939 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n", |
1956 | apic_id, mp_ioapics[apic_id].apicid); | 1940 | apic_id, mpc_ioapic_id(apic_id)); |
1957 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", | 1941 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", |
1958 | reg_00.bits.ID); | 1942 | reg_00.bits.ID); |
1959 | mp_ioapics[apic_id].apicid = reg_00.bits.ID; | 1943 | ioapics[apic_id].mp_config.apicid = reg_00.bits.ID; |
1960 | } | 1944 | } |
1961 | 1945 | ||
1962 | /* | 1946 | /* |
@@ -1965,9 +1949,9 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) | |||
1965 | * 'stuck on smp_invalidate_needed IPI wait' messages. | 1949 | * 'stuck on smp_invalidate_needed IPI wait' messages. |
1966 | */ | 1950 | */ |
1967 | if (apic->check_apicid_used(&phys_id_present_map, | 1951 | if (apic->check_apicid_used(&phys_id_present_map, |
1968 | mp_ioapics[apic_id].apicid)) { | 1952 | mpc_ioapic_id(apic_id))) { |
1969 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", | 1953 | printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", |
1970 | apic_id, mp_ioapics[apic_id].apicid); | 1954 | apic_id, mpc_ioapic_id(apic_id)); |
1971 | for (i = 0; i < get_physical_broadcast(); i++) | 1955 | for (i = 0; i < get_physical_broadcast(); i++) |
1972 | if (!physid_isset(i, phys_id_present_map)) | 1956 | if (!physid_isset(i, phys_id_present_map)) |
1973 | break; | 1957 | break; |
@@ -1976,13 +1960,14 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) | |||
1976 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", | 1960 | printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n", |
1977 | i); | 1961 | i); |
1978 | physid_set(i, phys_id_present_map); | 1962 | physid_set(i, phys_id_present_map); |
1979 | mp_ioapics[apic_id].apicid = i; | 1963 | ioapics[apic_id].mp_config.apicid = i; |
1980 | } else { | 1964 | } else { |
1981 | physid_mask_t tmp; | 1965 | physid_mask_t tmp; |
1982 | apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid, &tmp); | 1966 | apic->apicid_to_cpu_present(mpc_ioapic_id(apic_id), |
1967 | &tmp); | ||
1983 | apic_printk(APIC_VERBOSE, "Setting %d in the " | 1968 | apic_printk(APIC_VERBOSE, "Setting %d in the " |
1984 | "phys_id_present_map\n", | 1969 | "phys_id_present_map\n", |
1985 | mp_ioapics[apic_id].apicid); | 1970 | mpc_ioapic_id(apic_id)); |
1986 | physids_or(phys_id_present_map, phys_id_present_map, tmp); | 1971 | physids_or(phys_id_present_map, phys_id_present_map, tmp); |
1987 | } | 1972 | } |
1988 | 1973 | ||
@@ -1990,24 +1975,24 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) | |||
1990 | * We need to adjust the IRQ routing table | 1975 | * We need to adjust the IRQ routing table |
1991 | * if the ID changed. | 1976 | * if the ID changed. |
1992 | */ | 1977 | */ |
1993 | if (old_id != mp_ioapics[apic_id].apicid) | 1978 | if (old_id != mpc_ioapic_id(apic_id)) |
1994 | for (i = 0; i < mp_irq_entries; i++) | 1979 | for (i = 0; i < mp_irq_entries; i++) |
1995 | if (mp_irqs[i].dstapic == old_id) | 1980 | if (mp_irqs[i].dstapic == old_id) |
1996 | mp_irqs[i].dstapic | 1981 | mp_irqs[i].dstapic |
1997 | = mp_ioapics[apic_id].apicid; | 1982 | = mpc_ioapic_id(apic_id); |
1998 | 1983 | ||
1999 | /* | 1984 | /* |
2000 | * Update the ID register according to the right value | 1985 | * Update the ID register according to the right value |
2001 | * from the MPC table if they are different. | 1986 | * from the MPC table if they are different. |
2002 | */ | 1987 | */ |
2003 | if (mp_ioapics[apic_id].apicid == reg_00.bits.ID) | 1988 | if (mpc_ioapic_id(apic_id) == reg_00.bits.ID) |
2004 | continue; | 1989 | continue; |
2005 | 1990 | ||
2006 | apic_printk(APIC_VERBOSE, KERN_INFO | 1991 | apic_printk(APIC_VERBOSE, KERN_INFO |
2007 | "...changing IO-APIC physical APIC ID to %d ...", | 1992 | "...changing IO-APIC physical APIC ID to %d ...", |
2008 | mp_ioapics[apic_id].apicid); | 1993 | mpc_ioapic_id(apic_id)); |
2009 | 1994 | ||
2010 | reg_00.bits.ID = mp_ioapics[apic_id].apicid; | 1995 | reg_00.bits.ID = mpc_ioapic_id(apic_id); |
2011 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 1996 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2012 | io_apic_write(apic_id, 0, reg_00.raw); | 1997 | io_apic_write(apic_id, 0, reg_00.raw); |
2013 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 1998 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
@@ -2018,7 +2003,7 @@ void __init setup_ioapic_ids_from_mpc_nocheck(void) | |||
2018 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2003 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2019 | reg_00.raw = io_apic_read(apic_id, 0); | 2004 | reg_00.raw = io_apic_read(apic_id, 0); |
2020 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2005 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
2021 | if (reg_00.bits.ID != mp_ioapics[apic_id].apicid) | 2006 | if (reg_00.bits.ID != mpc_ioapic_id(apic_id)) |
2022 | printk("could not set ID!\n"); | 2007 | printk("could not set ID!\n"); |
2023 | else | 2008 | else |
2024 | apic_printk(APIC_VERBOSE, " ok.\n"); | 2009 | apic_printk(APIC_VERBOSE, " ok.\n"); |
@@ -2404,7 +2389,7 @@ static void eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | |||
2404 | 2389 | ||
2405 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2390 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2406 | for_each_irq_pin(entry, cfg->irq_2_pin) { | 2391 | for_each_irq_pin(entry, cfg->irq_2_pin) { |
2407 | if (mp_ioapics[entry->apic].apicver >= 0x20) { | 2392 | if (mpc_ioapic_ver(entry->apic) >= 0x20) { |
2408 | /* | 2393 | /* |
2409 | * Intr-remapping uses pin number as the virtual vector | 2394 | * Intr-remapping uses pin number as the virtual vector |
2410 | * in the RTE. Actual vector is programmed in | 2395 | * in the RTE. Actual vector is programmed in |
@@ -2918,49 +2903,19 @@ static int __init io_apic_bug_finalize(void) | |||
2918 | 2903 | ||
2919 | late_initcall(io_apic_bug_finalize); | 2904 | late_initcall(io_apic_bug_finalize); |
2920 | 2905 | ||
2921 | static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS]; | 2906 | static void resume_ioapic_id(int ioapic_id) |
2922 | |||
2923 | static void suspend_ioapic(int ioapic_id) | ||
2924 | { | 2907 | { |
2925 | struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id]; | ||
2926 | int i; | ||
2927 | |||
2928 | if (!saved_data) | ||
2929 | return; | ||
2930 | |||
2931 | for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++) | ||
2932 | saved_data[i] = ioapic_read_entry(ioapic_id, i); | ||
2933 | } | ||
2934 | |||
2935 | static int ioapic_suspend(void) | ||
2936 | { | ||
2937 | int ioapic_id; | ||
2938 | |||
2939 | for (ioapic_id = 0; ioapic_id < nr_ioapics; ioapic_id++) | ||
2940 | suspend_ioapic(ioapic_id); | ||
2941 | |||
2942 | return 0; | ||
2943 | } | ||
2944 | |||
2945 | static void resume_ioapic(int ioapic_id) | ||
2946 | { | ||
2947 | struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id]; | ||
2948 | unsigned long flags; | 2908 | unsigned long flags; |
2949 | union IO_APIC_reg_00 reg_00; | 2909 | union IO_APIC_reg_00 reg_00; |
2950 | int i; | ||
2951 | 2910 | ||
2952 | if (!saved_data) | ||
2953 | return; | ||
2954 | 2911 | ||
2955 | raw_spin_lock_irqsave(&ioapic_lock, flags); | 2912 | raw_spin_lock_irqsave(&ioapic_lock, flags); |
2956 | reg_00.raw = io_apic_read(ioapic_id, 0); | 2913 | reg_00.raw = io_apic_read(ioapic_id, 0); |
2957 | if (reg_00.bits.ID != mp_ioapics[ioapic_id].apicid) { | 2914 | if (reg_00.bits.ID != mpc_ioapic_id(ioapic_id)) { |
2958 | reg_00.bits.ID = mp_ioapics[ioapic_id].apicid; | 2915 | reg_00.bits.ID = mpc_ioapic_id(ioapic_id); |
2959 | io_apic_write(ioapic_id, 0, reg_00.raw); | 2916 | io_apic_write(ioapic_id, 0, reg_00.raw); |
2960 | } | 2917 | } |
2961 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); | 2918 | raw_spin_unlock_irqrestore(&ioapic_lock, flags); |
2962 | for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++) | ||
2963 | ioapic_write_entry(ioapic_id, i, saved_data[i]); | ||
2964 | } | 2919 | } |
2965 | 2920 | ||
2966 | static void ioapic_resume(void) | 2921 | static void ioapic_resume(void) |
@@ -2968,28 +2923,18 @@ static void ioapic_resume(void) | |||
2968 | int ioapic_id; | 2923 | int ioapic_id; |
2969 | 2924 | ||
2970 | for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--) | 2925 | for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--) |
2971 | resume_ioapic(ioapic_id); | 2926 | resume_ioapic_id(ioapic_id); |
2927 | |||
2928 | restore_ioapic_entries(); | ||
2972 | } | 2929 | } |
2973 | 2930 | ||
2974 | static struct syscore_ops ioapic_syscore_ops = { | 2931 | static struct syscore_ops ioapic_syscore_ops = { |
2975 | .suspend = ioapic_suspend, | 2932 | .suspend = save_ioapic_entries, |
2976 | .resume = ioapic_resume, | 2933 | .resume = ioapic_resume, |
2977 | }; | 2934 | }; |
2978 | 2935 | ||
2979 | static int __init ioapic_init_ops(void) | 2936 | static int __init ioapic_init_ops(void) |
2980 | { | 2937 | { |
2981 | int i; | ||
2982 | |||
2983 | for (i = 0; i < nr_ioapics; i++) { | ||
2984 | unsigned int size; | ||
2985 | |||
2986 | size = nr_ioapic_registers[i] | ||
2987 | * sizeof(struct IO_APIC_route_entry); | ||
2988 | ioapic_saved_data[i] = kzalloc(size, GFP_KERNEL); | ||
2989 | if (!ioapic_saved_data[i]) | ||
2990 | pr_err("IOAPIC %d: suspend/resume impossible!\n", i); | ||
2991 | } | ||
2992 | |||
2993 | register_syscore_ops(&ioapic_syscore_ops); | 2938 | register_syscore_ops(&ioapic_syscore_ops); |
2994 | 2939 | ||
2995 | return 0; | 2940 | return 0; |
@@ -3570,7 +3515,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | |||
3570 | } | 3515 | } |
3571 | #endif /* CONFIG_HT_IRQ */ | 3516 | #endif /* CONFIG_HT_IRQ */ |
3572 | 3517 | ||
3573 | int | 3518 | static int |
3574 | io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) | 3519 | io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) |
3575 | { | 3520 | { |
3576 | struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); | 3521 | struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); |
@@ -3585,21 +3530,21 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) | |||
3585 | return ret; | 3530 | return ret; |
3586 | } | 3531 | } |
3587 | 3532 | ||
3588 | static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | 3533 | int io_apic_setup_irq_pin_once(unsigned int irq, int node, |
3589 | struct io_apic_irq_attr *attr) | 3534 | struct io_apic_irq_attr *attr) |
3590 | { | 3535 | { |
3591 | unsigned int id = attr->ioapic, pin = attr->ioapic_pin; | 3536 | unsigned int id = attr->ioapic, pin = attr->ioapic_pin; |
3592 | int ret; | 3537 | int ret; |
3593 | 3538 | ||
3594 | /* Avoid redundant programming */ | 3539 | /* Avoid redundant programming */ |
3595 | if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) { | 3540 | if (test_bit(pin, ioapics[id].pin_programmed)) { |
3596 | pr_debug("Pin %d-%d already programmed\n", | 3541 | pr_debug("Pin %d-%d already programmed\n", |
3597 | mp_ioapics[id].apicid, pin); | 3542 | mpc_ioapic_id(id), pin); |
3598 | return 0; | 3543 | return 0; |
3599 | } | 3544 | } |
3600 | ret = io_apic_setup_irq_pin(irq, node, attr); | 3545 | ret = io_apic_setup_irq_pin(irq, node, attr); |
3601 | if (!ret) | 3546 | if (!ret) |
3602 | set_bit(pin, mp_ioapic_routing[id].pin_programmed); | 3547 | set_bit(pin, ioapics[id].pin_programmed); |
3603 | return ret; | 3548 | return ret; |
3604 | } | 3549 | } |
3605 | 3550 | ||
@@ -3764,8 +3709,7 @@ static u8 __init io_apic_unique_id(u8 id) | |||
3764 | 3709 | ||
3765 | bitmap_zero(used, 256); | 3710 | bitmap_zero(used, 256); |
3766 | for (i = 0; i < nr_ioapics; i++) { | 3711 | for (i = 0; i < nr_ioapics; i++) { |
3767 | struct mpc_ioapic *ia = &mp_ioapics[i]; | 3712 | __set_bit(mpc_ioapic_id(i), used); |
3768 | __set_bit(ia->apicid, used); | ||
3769 | } | 3713 | } |
3770 | if (!test_bit(id, used)) | 3714 | if (!test_bit(id, used)) |
3771 | return id; | 3715 | return id; |
@@ -3825,7 +3769,7 @@ void __init setup_ioapic_dest(void) | |||
3825 | return; | 3769 | return; |
3826 | 3770 | ||
3827 | for (ioapic = 0; ioapic < nr_ioapics; ioapic++) | 3771 | for (ioapic = 0; ioapic < nr_ioapics; ioapic++) |
3828 | for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) { | 3772 | for (pin = 0; pin < ioapics[ioapic].nr_registers; pin++) { |
3829 | irq_entry = find_irq_entry(ioapic, pin, mp_INT); | 3773 | irq_entry = find_irq_entry(ioapic, pin, mp_INT); |
3830 | if (irq_entry == -1) | 3774 | if (irq_entry == -1) |
3831 | continue; | 3775 | continue; |
@@ -3896,7 +3840,7 @@ void __init ioapic_and_gsi_init(void) | |||
3896 | ioapic_res = ioapic_setup_resources(nr_ioapics); | 3840 | ioapic_res = ioapic_setup_resources(nr_ioapics); |
3897 | for (i = 0; i < nr_ioapics; i++) { | 3841 | for (i = 0; i < nr_ioapics; i++) { |
3898 | if (smp_found_config) { | 3842 | if (smp_found_config) { |
3899 | ioapic_phys = mp_ioapics[i].apicaddr; | 3843 | ioapic_phys = mpc_ioapic_addr(i); |
3900 | #ifdef CONFIG_X86_32 | 3844 | #ifdef CONFIG_X86_32 |
3901 | if (!ioapic_phys) { | 3845 | if (!ioapic_phys) { |
3902 | printk(KERN_ERR | 3846 | printk(KERN_ERR |
@@ -3956,8 +3900,9 @@ int mp_find_ioapic(u32 gsi) | |||
3956 | 3900 | ||
3957 | /* Find the IOAPIC that manages this GSI. */ | 3901 | /* Find the IOAPIC that manages this GSI. */ |
3958 | for (i = 0; i < nr_ioapics; i++) { | 3902 | for (i = 0; i < nr_ioapics; i++) { |
3959 | if ((gsi >= mp_gsi_routing[i].gsi_base) | 3903 | struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(i); |
3960 | && (gsi <= mp_gsi_routing[i].gsi_end)) | 3904 | if ((gsi >= gsi_cfg->gsi_base) |
3905 | && (gsi <= gsi_cfg->gsi_end)) | ||
3961 | return i; | 3906 | return i; |
3962 | } | 3907 | } |
3963 | 3908 | ||
@@ -3967,12 +3912,16 @@ int mp_find_ioapic(u32 gsi) | |||
3967 | 3912 | ||
3968 | int mp_find_ioapic_pin(int ioapic, u32 gsi) | 3913 | int mp_find_ioapic_pin(int ioapic, u32 gsi) |
3969 | { | 3914 | { |
3915 | struct mp_ioapic_gsi *gsi_cfg; | ||
3916 | |||
3970 | if (WARN_ON(ioapic == -1)) | 3917 | if (WARN_ON(ioapic == -1)) |
3971 | return -1; | 3918 | return -1; |
3972 | if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end)) | 3919 | |
3920 | gsi_cfg = mp_ioapic_gsi_routing(ioapic); | ||
3921 | if (WARN_ON(gsi > gsi_cfg->gsi_end)) | ||
3973 | return -1; | 3922 | return -1; |
3974 | 3923 | ||
3975 | return gsi - mp_gsi_routing[ioapic].gsi_base; | 3924 | return gsi - gsi_cfg->gsi_base; |
3976 | } | 3925 | } |
3977 | 3926 | ||
3978 | static __init int bad_ioapic(unsigned long address) | 3927 | static __init int bad_ioapic(unsigned long address) |
@@ -3994,40 +3943,42 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) | |||
3994 | { | 3943 | { |
3995 | int idx = 0; | 3944 | int idx = 0; |
3996 | int entries; | 3945 | int entries; |
3946 | struct mp_ioapic_gsi *gsi_cfg; | ||
3997 | 3947 | ||
3998 | if (bad_ioapic(address)) | 3948 | if (bad_ioapic(address)) |
3999 | return; | 3949 | return; |
4000 | 3950 | ||
4001 | idx = nr_ioapics; | 3951 | idx = nr_ioapics; |
4002 | 3952 | ||
4003 | mp_ioapics[idx].type = MP_IOAPIC; | 3953 | ioapics[idx].mp_config.type = MP_IOAPIC; |
4004 | mp_ioapics[idx].flags = MPC_APIC_USABLE; | 3954 | ioapics[idx].mp_config.flags = MPC_APIC_USABLE; |
4005 | mp_ioapics[idx].apicaddr = address; | 3955 | ioapics[idx].mp_config.apicaddr = address; |
4006 | 3956 | ||
4007 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | 3957 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); |
4008 | mp_ioapics[idx].apicid = io_apic_unique_id(id); | 3958 | ioapics[idx].mp_config.apicid = io_apic_unique_id(id); |
4009 | mp_ioapics[idx].apicver = io_apic_get_version(idx); | 3959 | ioapics[idx].mp_config.apicver = io_apic_get_version(idx); |
4010 | 3960 | ||
4011 | /* | 3961 | /* |
4012 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups | 3962 | * Build basic GSI lookup table to facilitate gsi->io_apic lookups |
4013 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). | 3963 | * and to prevent reprogramming of IOAPIC pins (PCI GSIs). |
4014 | */ | 3964 | */ |
4015 | entries = io_apic_get_redir_entries(idx); | 3965 | entries = io_apic_get_redir_entries(idx); |
4016 | mp_gsi_routing[idx].gsi_base = gsi_base; | 3966 | gsi_cfg = mp_ioapic_gsi_routing(idx); |
4017 | mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1; | 3967 | gsi_cfg->gsi_base = gsi_base; |
3968 | gsi_cfg->gsi_end = gsi_base + entries - 1; | ||
4018 | 3969 | ||
4019 | /* | 3970 | /* |
4020 | * The number of IO-APIC IRQ registers (== #pins): | 3971 | * The number of IO-APIC IRQ registers (== #pins): |
4021 | */ | 3972 | */ |
4022 | nr_ioapic_registers[idx] = entries; | 3973 | ioapics[idx].nr_registers = entries; |
4023 | 3974 | ||
4024 | if (mp_gsi_routing[idx].gsi_end >= gsi_top) | 3975 | if (gsi_cfg->gsi_end >= gsi_top) |
4025 | gsi_top = mp_gsi_routing[idx].gsi_end + 1; | 3976 | gsi_top = gsi_cfg->gsi_end + 1; |
4026 | 3977 | ||
4027 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " | 3978 | printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " |
4028 | "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, | 3979 | "GSI %d-%d\n", idx, mpc_ioapic_id(idx), |
4029 | mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr, | 3980 | mpc_ioapic_ver(idx), mpc_ioapic_addr(idx), |
4030 | mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end); | 3981 | gsi_cfg->gsi_base, gsi_cfg->gsi_end); |
4031 | 3982 | ||
4032 | nr_ioapics++; | 3983 | nr_ioapics++; |
4033 | } | 3984 | } |