]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Suresh Siddha <suresh.b.siddha@intel.com> |
2 | Subject: x64, x2apic/intr-remap: ioapic routines which deal with initial io-apic RTE setup | |
3 | References: fate #303948 and fate #303984 | |
4 | Patch-Mainline: queued for .28 | |
5 | Commit-ID: 4dc2f96cacd1e74c688f94348a3bfd0a980817d5 | |
6 | ||
7 | Signed-off-by: Thomas Renninger <trenn@suse.de> | |
8 | ||
9 | Generic ioapic specific routines which be used later during enabling | |
10 | interrupt-remapping. | |
11 | ||
12 | Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> | |
13 | Cc: akpm@linux-foundation.org | |
14 | Cc: arjan@linux.intel.com | |
15 | Cc: andi@firstfloor.org | |
16 | Cc: ebiederm@xmission.com | |
17 | Cc: jbarnes@virtuousgeek.org | |
18 | Cc: steiner@sgi.com | |
19 | Signed-off-by: Ingo Molnar <mingo@elte.hu> | |
20 | ||
21 | --- | |
22 | arch/x86/kernel/io_apic_64.c | 66 +++++++++++++++++++++++++++++++++++++++++++ | |
23 | include/asm-x86/io_apic.h | 6 +++ | |
24 | 2 files changed, 72 insertions(+) | |
25 | ||
26 | Index: linux-2.6.26/arch/x86/kernel/io_apic_64.c | |
27 | =================================================================== | |
28 | --- linux-2.6.26.orig/arch/x86/kernel/io_apic_64.c | |
29 | +++ linux-2.6.26/arch/x86/kernel/io_apic_64.c | |
30 | @@ -108,6 +108,9 @@ static DEFINE_SPINLOCK(vector_lock); | |
31 | */ | |
32 | int nr_ioapic_registers[MAX_IO_APICS]; | |
33 | ||
34 | +/* I/O APIC RTE contents at the OS boot up */ | |
35 | +struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; | |
36 | + | |
37 | /* I/O APIC entries */ | |
38 | struct mp_config_ioapic mp_ioapics[MAX_IO_APICS]; | |
39 | int nr_ioapics; | |
40 | @@ -440,6 +443,69 @@ static void clear_IO_APIC (void) | |
41 | clear_IO_APIC_pin(apic, pin); | |
42 | } | |
43 | ||
44 | +/* | |
45 | + * Saves and masks all the unmasked IO-APIC RTE's | |
46 | + */ | |
47 | +int save_mask_IO_APIC_setup(void) | |
48 | +{ | |
49 | + union IO_APIC_reg_01 reg_01; | |
50 | + unsigned long flags; | |
51 | + int apic, pin; | |
52 | + | |
53 | + /* | |
54 | + * The number of IO-APIC IRQ registers (== #pins): | |
55 | + */ | |
56 | + for (apic = 0; apic < nr_ioapics; apic++) { | |
57 | + spin_lock_irqsave(&ioapic_lock, flags); | |
58 | + reg_01.raw = io_apic_read(apic, 1); | |
59 | + spin_unlock_irqrestore(&ioapic_lock, flags); | |
60 | + nr_ioapic_registers[apic] = reg_01.bits.entries+1; | |
61 | + } | |
62 | + | |
63 | + for (apic = 0; apic < nr_ioapics; apic++) { | |
64 | + early_ioapic_entries[apic] = | |
65 | + kzalloc(sizeof(struct IO_APIC_route_entry) * | |
66 | + nr_ioapic_registers[apic], GFP_KERNEL); | |
67 | + if (!early_ioapic_entries[apic]) | |
68 | + return -ENOMEM; | |
69 | + } | |
70 | + | |
71 | + for (apic = 0; apic < nr_ioapics; apic++) | |
72 | + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { | |
73 | + struct IO_APIC_route_entry entry; | |
74 | + | |
75 | + entry = early_ioapic_entries[apic][pin] = | |
76 | + ioapic_read_entry(apic, pin); | |
77 | + if (!entry.mask) { | |
78 | + entry.mask = 1; | |
79 | + ioapic_write_entry(apic, pin, entry); | |
80 | + } | |
81 | + } | |
82 | + return 0; | |
83 | +} | |
84 | + | |
85 | +void restore_IO_APIC_setup(void) | |
86 | +{ | |
87 | + int apic, pin; | |
88 | + | |
89 | + for (apic = 0; apic < nr_ioapics; apic++) | |
90 | + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) | |
91 | + ioapic_write_entry(apic, pin, | |
92 | + early_ioapic_entries[apic][pin]); | |
93 | +} | |
94 | + | |
95 | +void reinit_intr_remapped_IO_APIC(int intr_remapping) | |
96 | +{ | |
97 | + /* | |
98 | + * for now plain restore of previous settings. | |
99 | + * TBD: In the case of OS enabling interrupt-remapping, | |
100 | + * IO-APIC RTE's need to be setup to point to interrupt-remapping | |
101 | + * table entries. for now, do a plain restore, and wait for | |
102 | + * the setup_IO_APIC_irqs() to do proper initialization. | |
103 | + */ | |
104 | + restore_IO_APIC_setup(); | |
105 | +} | |
106 | + | |
107 | int skip_ioapic_setup; | |
108 | int ioapic_force; | |
109 | ||
110 | Index: linux-2.6.26/include/asm-x86/io_apic.h | |
111 | =================================================================== | |
112 | --- linux-2.6.26.orig/include/asm-x86/io_apic.h | |
113 | +++ linux-2.6.26/include/asm-x86/io_apic.h | |
114 | @@ -193,6 +193,12 @@ extern int io_apic_set_pci_routing(int i | |
115 | extern int (*ioapic_renumber_irq)(int ioapic, int irq); | |
116 | extern void ioapic_init_mappings(void); | |
117 | ||
118 | +#ifdef CONFIG_X86_64 | |
119 | +extern int save_mask_IO_APIC_setup(void); | |
120 | +extern void restore_IO_APIC_setup(void); | |
121 | +extern void reinit_intr_remapped_IO_APIC(int); | |
122 | +#endif | |
123 | + | |
124 | #else /* !CONFIG_X86_IO_APIC */ | |
125 | #define io_apic_assign_pci_irqs 0 | |
126 | static const int timer_through_8259 = 0; |