aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/mpparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/mpparse.c')
-rw-r--r--arch/x86/kernel/mpparse.c139
1 files changed, 23 insertions, 116 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index d7b6f7fb4fec..9103b89c145a 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/delay.h> 12#include <linux/delay.h>
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/memblock.h>
14#include <linux/kernel_stat.h> 15#include <linux/kernel_stat.h>
15#include <linux/mc146818rtc.h> 16#include <linux/mc146818rtc.h>
16#include <linux/bitops.h> 17#include <linux/bitops.h>
@@ -117,21 +118,8 @@ static void __init MP_bus_info(struct mpc_bus *m)
117 118
118static void __init MP_ioapic_info(struct mpc_ioapic *m) 119static void __init MP_ioapic_info(struct mpc_ioapic *m)
119{ 120{
120 if (!(m->flags & MPC_APIC_USABLE)) 121 if (m->flags & MPC_APIC_USABLE)
121 return; 122 mp_register_ioapic(m->apicid, m->apicaddr, gsi_top);
122
123 printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
124 m->apicid, m->apicver, m->apicaddr);
125
126 mp_register_ioapic(m->apicid, m->apicaddr, gsi_top);
127}
128
129static void print_MP_intsrc_info(struct mpc_intsrc *m)
130{
131 apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
132 " IRQ %02x, APIC ID %x, APIC INT %02x\n",
133 m->irqtype, m->irqflag & 3, (m->irqflag >> 2) & 3, m->srcbus,
134 m->srcbusirq, m->dstapic, m->dstirq);
135} 123}
136 124
137static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq) 125static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
@@ -143,73 +131,11 @@ static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
143 mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq); 131 mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);
144} 132}
145 133
146static void __init assign_to_mp_irq(struct mpc_intsrc *m,
147 struct mpc_intsrc *mp_irq)
148{
149 mp_irq->dstapic = m->dstapic;
150 mp_irq->type = m->type;
151 mp_irq->irqtype = m->irqtype;
152 mp_irq->irqflag = m->irqflag;
153 mp_irq->srcbus = m->srcbus;
154 mp_irq->srcbusirq = m->srcbusirq;
155 mp_irq->dstirq = m->dstirq;
156}
157
158static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq,
159 struct mpc_intsrc *m)
160{
161 m->dstapic = mp_irq->dstapic;
162 m->type = mp_irq->type;
163 m->irqtype = mp_irq->irqtype;
164 m->irqflag = mp_irq->irqflag;
165 m->srcbus = mp_irq->srcbus;
166 m->srcbusirq = mp_irq->srcbusirq;
167 m->dstirq = mp_irq->dstirq;
168}
169
170static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq,
171 struct mpc_intsrc *m)
172{
173 if (mp_irq->dstapic != m->dstapic)
174 return 1;
175 if (mp_irq->type != m->type)
176 return 2;
177 if (mp_irq->irqtype != m->irqtype)
178 return 3;
179 if (mp_irq->irqflag != m->irqflag)
180 return 4;
181 if (mp_irq->srcbus != m->srcbus)
182 return 5;
183 if (mp_irq->srcbusirq != m->srcbusirq)
184 return 6;
185 if (mp_irq->dstirq != m->dstirq)
186 return 7;
187
188 return 0;
189}
190
191static void __init MP_intsrc_info(struct mpc_intsrc *m)
192{
193 int i;
194
195 print_MP_intsrc_info(m);
196
197 for (i = 0; i < mp_irq_entries; i++) {
198 if (!mp_irq_mpc_intsrc_cmp(&mp_irqs[i], m))
199 return;
200 }
201
202 assign_to_mp_irq(m, &mp_irqs[mp_irq_entries]);
203 if (++mp_irq_entries == MAX_IRQ_SOURCES)
204 panic("Max # of irq sources exceeded!!\n");
205}
206#else /* CONFIG_X86_IO_APIC */ 134#else /* CONFIG_X86_IO_APIC */
207static inline void __init MP_bus_info(struct mpc_bus *m) {} 135static inline void __init MP_bus_info(struct mpc_bus *m) {}
208static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {} 136static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
209static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}
210#endif /* CONFIG_X86_IO_APIC */ 137#endif /* CONFIG_X86_IO_APIC */
211 138
212
213static void __init MP_lintsrc_info(struct mpc_lintsrc *m) 139static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
214{ 140{
215 apic_printk(APIC_VERBOSE, "Lint: type %d, pol %d, trig %d, bus %02x," 141 apic_printk(APIC_VERBOSE, "Lint: type %d, pol %d, trig %d, bus %02x,"
@@ -221,7 +147,6 @@ static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
221/* 147/*
222 * Read/parse the MPC 148 * Read/parse the MPC
223 */ 149 */
224
225static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str) 150static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
226{ 151{
227 152
@@ -274,18 +199,6 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
274 199
275void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { } 200void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }
276 201
277static void __init smp_register_lapic_address(unsigned long address)
278{
279 mp_lapic_addr = address;
280
281 set_fixmap_nocache(FIX_APIC_BASE, address);
282 if (boot_cpu_physical_apicid == -1U) {
283 boot_cpu_physical_apicid = read_apic_id();
284 apic_version[boot_cpu_physical_apicid] =
285 GET_APIC_VERSION(apic_read(APIC_LVR));
286 }
287}
288
289static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) 202static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
290{ 203{
291 char str[16]; 204 char str[16];
@@ -300,17 +213,13 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
300#ifdef CONFIG_X86_32 213#ifdef CONFIG_X86_32
301 generic_mps_oem_check(mpc, oem, str); 214 generic_mps_oem_check(mpc, oem, str);
302#endif 215#endif
303 /* save the local APIC address, it might be non-default */ 216 /* Initialize the lapic mapping */
304 if (!acpi_lapic) 217 if (!acpi_lapic)
305 mp_lapic_addr = mpc->lapic; 218 register_lapic_address(mpc->lapic);
306 219
307 if (early) 220 if (early)
308 return 1; 221 return 1;
309 222
310 /* Initialize the lapic mapping */
311 if (!acpi_lapic)
312 smp_register_lapic_address(mpc->lapic);
313
314 if (mpc->oemptr) 223 if (mpc->oemptr)
315 x86_init.mpparse.smp_read_mpc_oem(mpc); 224 x86_init.mpparse.smp_read_mpc_oem(mpc);
316 225
@@ -336,7 +245,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
336 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic)); 245 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
337 break; 246 break;
338 case MP_INTSRC: 247 case MP_INTSRC:
339 MP_intsrc_info((struct mpc_intsrc *)mpt); 248 mp_save_irq((struct mpc_intsrc *)mpt);
340 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc)); 249 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
341 break; 250 break;
342 case MP_LINTSRC: 251 case MP_LINTSRC:
@@ -376,7 +285,7 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
376 intsrc.type = MP_INTSRC; 285 intsrc.type = MP_INTSRC;
377 intsrc.irqflag = 0; /* conforming */ 286 intsrc.irqflag = 0; /* conforming */
378 intsrc.srcbus = 0; 287 intsrc.srcbus = 0;
379 intsrc.dstapic = mp_ioapics[0].apicid; 288 intsrc.dstapic = mpc_ioapic_id(0);
380 289
381 intsrc.irqtype = mp_INT; 290 intsrc.irqtype = mp_INT;
382 291
@@ -428,13 +337,13 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
428 337
429 intsrc.srcbusirq = i; 338 intsrc.srcbusirq = i;
430 intsrc.dstirq = i ? i : 2; /* IRQ0 to INTIN2 */ 339 intsrc.dstirq = i ? i : 2; /* IRQ0 to INTIN2 */
431 MP_intsrc_info(&intsrc); 340 mp_save_irq(&intsrc);
432 } 341 }
433 342
434 intsrc.irqtype = mp_ExtINT; 343 intsrc.irqtype = mp_ExtINT;
435 intsrc.srcbusirq = 0; 344 intsrc.srcbusirq = 0;
436 intsrc.dstirq = 0; /* 8259A to INTIN0 */ 345 intsrc.dstirq = 0; /* 8259A to INTIN0 */
437 MP_intsrc_info(&intsrc); 346 mp_save_irq(&intsrc);
438} 347}
439 348
440 349
@@ -657,7 +566,7 @@ static void __init smp_reserve_memory(struct mpf_intel *mpf)
657{ 566{
658 unsigned long size = get_mpc_size(mpf->physptr); 567 unsigned long size = get_mpc_size(mpf->physptr);
659 568
660 reserve_early_overlap_ok(mpf->physptr, mpf->physptr+size, "MP-table mpc"); 569 memblock_x86_reserve_range(mpf->physptr, mpf->physptr+size, "* MP-table mpc");
661} 570}
662 571
663static int __init smp_scan_config(unsigned long base, unsigned long length) 572static int __init smp_scan_config(unsigned long base, unsigned long length)
@@ -686,7 +595,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
686 mpf, (u64)virt_to_phys(mpf)); 595 mpf, (u64)virt_to_phys(mpf));
687 596
688 mem = virt_to_phys(mpf); 597 mem = virt_to_phys(mpf);
689 reserve_early_overlap_ok(mem, mem + sizeof(*mpf), "MP-table mpf"); 598 memblock_x86_reserve_range(mem, mem + sizeof(*mpf), "* MP-table mpf");
690 if (mpf->physptr) 599 if (mpf->physptr)
691 smp_reserve_memory(mpf); 600 smp_reserve_memory(mpf);
692 601
@@ -783,11 +692,11 @@ static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
783 int i; 692 int i;
784 693
785 apic_printk(APIC_VERBOSE, "OLD "); 694 apic_printk(APIC_VERBOSE, "OLD ");
786 print_MP_intsrc_info(m); 695 print_mp_irq_info(m);
787 696
788 i = get_MP_intsrc_index(m); 697 i = get_MP_intsrc_index(m);
789 if (i > 0) { 698 if (i > 0) {
790 assign_to_mpc_intsrc(&mp_irqs[i], m); 699 memcpy(m, &mp_irqs[i], sizeof(*m));
791 apic_printk(APIC_VERBOSE, "NEW "); 700 apic_printk(APIC_VERBOSE, "NEW ");
792 print_mp_irq_info(&mp_irqs[i]); 701 print_mp_irq_info(&mp_irqs[i]);
793 return; 702 return;
@@ -805,23 +714,21 @@ static void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
805 *nr_m_spare += 1; 714 *nr_m_spare += 1;
806 } 715 }
807} 716}
808#else /* CONFIG_X86_IO_APIC */
809static
810inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
811#endif /* CONFIG_X86_IO_APIC */
812 717
813static int 718static int __init
814check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count) 719check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
815{ 720{
816 int ret = 0;
817
818 if (!mpc_new_phys || count <= mpc_new_length) { 721 if (!mpc_new_phys || count <= mpc_new_length) {
819 WARN(1, "update_mptable: No spare slots (length: %x)\n", count); 722 WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
820 return -1; 723 return -1;
821 } 724 }
822 725
823 return ret; 726 return 0;
824} 727}
728#else /* CONFIG_X86_IO_APIC */
729static
730inline void __init check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
731#endif /* CONFIG_X86_IO_APIC */
825 732
826static int __init replace_intsrc_all(struct mpc_table *mpc, 733static int __init replace_intsrc_all(struct mpc_table *mpc,
827 unsigned long mpc_new_phys, 734 unsigned long mpc_new_phys,
@@ -874,14 +781,14 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
874 if (nr_m_spare > 0) { 781 if (nr_m_spare > 0) {
875 apic_printk(APIC_VERBOSE, "*NEW* found\n"); 782 apic_printk(APIC_VERBOSE, "*NEW* found\n");
876 nr_m_spare--; 783 nr_m_spare--;
877 assign_to_mpc_intsrc(&mp_irqs[i], m_spare[nr_m_spare]); 784 memcpy(m_spare[nr_m_spare], &mp_irqs[i], sizeof(mp_irqs[i]));
878 m_spare[nr_m_spare] = NULL; 785 m_spare[nr_m_spare] = NULL;
879 } else { 786 } else {
880 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 787 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
881 count += sizeof(struct mpc_intsrc); 788 count += sizeof(struct mpc_intsrc);
882 if (check_slot(mpc_new_phys, mpc_new_length, count) < 0) 789 if (check_slot(mpc_new_phys, mpc_new_length, count) < 0)
883 goto out; 790 goto out;
884 assign_to_mpc_intsrc(&mp_irqs[i], m); 791 memcpy(m, &mp_irqs[i], sizeof(*m));
885 mpc->length = count; 792 mpc->length = count;
886 mpt += sizeof(struct mpc_intsrc); 793 mpt += sizeof(struct mpc_intsrc);
887 } 794 }
@@ -974,7 +881,7 @@ static int __init update_mp_table(void)
974 881
975 if (!mpc_new_phys) { 882 if (!mpc_new_phys) {
976 unsigned char old, new; 883 unsigned char old, new;
977 /* check if we can change the postion */ 884 /* check if we can change the position */
978 mpc->checksum = 0; 885 mpc->checksum = 0;
979 old = mpf_checksum((unsigned char *)mpc, mpc->length); 886 old = mpf_checksum((unsigned char *)mpc, mpc->length);
980 mpc->checksum = 0xff; 887 mpc->checksum = 0xff;
@@ -983,7 +890,7 @@ static int __init update_mp_table(void)
983 printk(KERN_INFO "mpc is readonly, please try alloc_mptable instead\n"); 890 printk(KERN_INFO "mpc is readonly, please try alloc_mptable instead\n");
984 return 0; 891 return 0;
985 } 892 }
986 printk(KERN_INFO "use in-positon replacing\n"); 893 printk(KERN_INFO "use in-position replacing\n");
987 } else { 894 } else {
988 mpf->physptr = mpc_new_phys; 895 mpf->physptr = mpc_new_phys;
989 mpc_new = phys_to_virt(mpc_new_phys); 896 mpc_new = phys_to_virt(mpc_new_phys);