aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/mpparse.c
diff options
context:
space:
mode:
authorJaswinder Singh Rajput <jaswinderrajput@gmail.com>2009-03-18 11:12:28 -0400
committerIngo Molnar <mingo@elte.hu>2009-03-18 12:15:05 -0400
commita6830278568a8bb9758aac152db15187741e0113 (patch)
tree2bd3e669a53e0372b4a78a5fb3ef9b2fcd65669c /arch/x86/kernel/mpparse.c
parentcde5edbda8ba7d600154ce4171125a48e4d2a21b (diff)
x86: mpparse: clean up code by introducing a few helper functions
Impact: cleanup Refactor the MP-table parsing code via the introduction of the following helper functions: skip_entry() smp_reserve_bootmem() check_irq_src() check_slot() To simplify the code flow and to reduce the size of the following oversized functions: smp_read_mpc(), smp_scan_config(). There should be no impact to functionality. Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/mpparse.c')
-rw-r--r--arch/x86/kernel/mpparse.c261
1 files changed, 120 insertions, 141 deletions
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index 47673e02ae58..58ddf6259afb 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -109,9 +109,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
109 } else 109 } else
110 printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); 110 printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
111} 111}
112#endif
113
114#ifdef CONFIG_X86_IO_APIC
115 112
116static int bad_ioapic(unsigned long address) 113static int bad_ioapic(unsigned long address)
117{ 114{
@@ -224,8 +221,12 @@ static void __init MP_intsrc_info(struct mpc_intsrc *m)
224 if (++mp_irq_entries == MAX_IRQ_SOURCES) 221 if (++mp_irq_entries == MAX_IRQ_SOURCES)
225 panic("Max # of irq sources exceeded!!\n"); 222 panic("Max # of irq sources exceeded!!\n");
226} 223}
224#else /* CONFIG_X86_IO_APIC */
225static inline void __init MP_bus_info(struct mpc_bus *m) {}
226static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {}
227static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {}
228#endif /* CONFIG_X86_IO_APIC */
227 229
228#endif
229 230
230static void __init MP_lintsrc_info(struct mpc_lintsrc *m) 231static void __init MP_lintsrc_info(struct mpc_lintsrc *m)
231{ 232{
@@ -275,6 +276,12 @@ static int __init smp_check_mpc(struct mpc_table *mpc, char *oem, char *str)
275 return 1; 276 return 1;
276} 277}
277 278
279static void skip_entry(unsigned char **ptr, int *count, int size)
280{
281 *ptr += size;
282 *count += size;
283}
284
278static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) 285static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
279{ 286{
280 char str[16]; 287 char str[16];
@@ -310,55 +317,27 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
310 while (count < mpc->length) { 317 while (count < mpc->length) {
311 switch (*mpt) { 318 switch (*mpt) {
312 case MP_PROCESSOR: 319 case MP_PROCESSOR:
313 { 320 /* ACPI may have already provided this data */
314 struct mpc_cpu *m = (struct mpc_cpu *)mpt; 321 if (!acpi_lapic)
315 /* ACPI may have already provided this data */ 322 MP_processor_info((struct mpc_cpu *)&mpt);
316 if (!acpi_lapic) 323 skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
317 MP_processor_info(m); 324 break;
318 mpt += sizeof(*m);
319 count += sizeof(*m);
320 break;
321 }
322 case MP_BUS: 325 case MP_BUS:
323 { 326 MP_bus_info((struct mpc_bus *)&mpt);
324 struct mpc_bus *m = (struct mpc_bus *)mpt; 327 skip_entry(&mpt, &count, sizeof(struct mpc_bus));
325#ifdef CONFIG_X86_IO_APIC 328 break;
326 MP_bus_info(m);
327#endif
328 mpt += sizeof(*m);
329 count += sizeof(*m);
330 break;
331 }
332 case MP_IOAPIC: 329 case MP_IOAPIC:
333 { 330 MP_ioapic_info((struct mpc_ioapic *)&mpt);
334#ifdef CONFIG_X86_IO_APIC 331 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
335 struct mpc_ioapic *m = (struct mpc_ioapic *)mpt; 332 break;
336 MP_ioapic_info(m);
337#endif
338 mpt += sizeof(struct mpc_ioapic);
339 count += sizeof(struct mpc_ioapic);
340 break;
341 }
342 case MP_INTSRC: 333 case MP_INTSRC:
343 { 334 MP_intsrc_info((struct mpc_intsrc *)&mpt);
344#ifdef CONFIG_X86_IO_APIC 335 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
345 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 336 break;
346
347 MP_intsrc_info(m);
348#endif
349 mpt += sizeof(struct mpc_intsrc);
350 count += sizeof(struct mpc_intsrc);
351 break;
352 }
353 case MP_LINTSRC: 337 case MP_LINTSRC:
354 { 338 MP_lintsrc_info((struct mpc_lintsrc *)&mpt);
355 struct mpc_lintsrc *m = 339 skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
356 (struct mpc_lintsrc *)mpt; 340 break;
357 MP_lintsrc_info(m);
358 mpt += sizeof(*m);
359 count += sizeof(*m);
360 break;
361 }
362 default: 341 default:
363 /* wrong mptable */ 342 /* wrong mptable */
364 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); 343 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
@@ -689,6 +668,31 @@ void __init get_smp_config(void)
689 __get_smp_config(0); 668 __get_smp_config(0);
690} 669}
691 670
671static void smp_reserve_bootmem(struct mpf_intel *mpf)
672{
673 unsigned long size = get_mpc_size(mpf->physptr);
674#ifdef CONFIG_X86_32
675 /*
676 * We cannot access to MPC table to compute table size yet,
677 * as only few megabytes from the bottom is mapped now.
678 * PC-9800's MPC table places on the very last of physical
679 * memory; so that simply reserving PAGE_SIZE from mpf->physptr
680 * yields BUG() in reserve_bootmem.
681 * also need to make sure physptr is below than max_low_pfn
682 * we don't need reserve the area above max_low_pfn
683 */
684 unsigned long end = max_low_pfn * PAGE_SIZE;
685
686 if (mpf->physptr < end) {
687 if (mpf->physptr + size > end)
688 size = end - mpf->physptr;
689 reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
690 }
691#else
692 reserve_bootmem_generic(mpf->physptr, size, BOOTMEM_DEFAULT);
693#endif
694}
695
692static int __init smp_scan_config(unsigned long base, unsigned long length, 696static int __init smp_scan_config(unsigned long base, unsigned long length,
693 unsigned reserve) 697 unsigned reserve)
694{ 698{
@@ -717,35 +721,9 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
717 if (!reserve) 721 if (!reserve)
718 return 1; 722 return 1;
719 reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf), 723 reserve_bootmem_generic(virt_to_phys(mpf), sizeof(*mpf),
720 BOOTMEM_DEFAULT);
721 if (mpf->physptr) {
722 unsigned long size = get_mpc_size(mpf->physptr);
723#ifdef CONFIG_X86_32
724 /*
725 * We cannot access to MPC table to compute
726 * table size yet, as only few megabytes from
727 * the bottom is mapped now.
728 * PC-9800's MPC table places on the very last
729 * of physical memory; so that simply reserving
730 * PAGE_SIZE from mpf->physptr yields BUG()
731 * in reserve_bootmem.
732 * also need to make sure physptr is below than
733 * max_low_pfn
734 * we don't need reserve the area above max_low_pfn
735 */
736 unsigned long end = max_low_pfn * PAGE_SIZE;
737
738 if (mpf->physptr < end) {
739 if (mpf->physptr + size > end)
740 size = end - mpf->physptr;
741 reserve_bootmem_generic(mpf->physptr, size,
742 BOOTMEM_DEFAULT);
743 }
744#else
745 reserve_bootmem_generic(mpf->physptr, size,
746 BOOTMEM_DEFAULT); 724 BOOTMEM_DEFAULT);
747#endif 725 if (mpf->physptr)
748 } 726 smp_reserve_bootmem(mpf);
749 727
750 return 1; 728 return 1;
751 } 729 }
@@ -848,7 +826,57 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
848#define SPARE_SLOT_NUM 20 826#define SPARE_SLOT_NUM 20
849 827
850static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; 828static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM];
851#endif 829
830static void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare)
831{
832 int i;
833
834 apic_printk(APIC_VERBOSE, "OLD ");
835 print_MP_intsrc_info(m);
836
837 i = get_MP_intsrc_index(m);
838 if (i > 0) {
839 assign_to_mpc_intsrc(&mp_irqs[i], m);
840 apic_printk(APIC_VERBOSE, "NEW ");
841 print_mp_irq_info(&mp_irqs[i]);
842 return;
843 }
844 if (!i) {
845 /* legacy, do nothing */
846 return;
847 }
848 if (*nr_m_spare < SPARE_SLOT_NUM) {
849 /*
850 * not found (-1), or duplicated (-2) are invalid entries,
851 * we need to use the slot later
852 */
853 m_spare[*nr_m_spare] = m;
854 *nr_m_spare += 1;
855 }
856}
857#else /* CONFIG_X86_IO_APIC */
858static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {}
859#endif /* CONFIG_X86_IO_APIC */
860
861static int check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length,
862 int count)
863{
864 if (!mpc_new_phys) {
865 pr_info("No spare slots, try to append...take your risk, "
866 "new mpc_length %x\n", count);
867 } else {
868 if (count <= mpc_new_length)
869 pr_info("No spare slots, try to append..., "
870 "new mpc_length %x\n", count);
871 else {
872 pr_err("mpc_new_length %lx is too small\n",
873 mpc_new_length);
874 return -1;
875 }
876 }
877
878 return 0;
879}
852 880
853static int __init replace_intsrc_all(struct mpc_table *mpc, 881static int __init replace_intsrc_all(struct mpc_table *mpc,
854 unsigned long mpc_new_phys, 882 unsigned long mpc_new_phys,
@@ -856,71 +884,30 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
856{ 884{
857#ifdef CONFIG_X86_IO_APIC 885#ifdef CONFIG_X86_IO_APIC
858 int i; 886 int i;
859 int nr_m_spare = 0;
860#endif 887#endif
861
862 int count = sizeof(*mpc); 888 int count = sizeof(*mpc);
889 int nr_m_spare = 0;
863 unsigned char *mpt = ((unsigned char *)mpc) + count; 890 unsigned char *mpt = ((unsigned char *)mpc) + count;
864 891
865 printk(KERN_INFO "mpc_length %x\n", mpc->length); 892 printk(KERN_INFO "mpc_length %x\n", mpc->length);
866 while (count < mpc->length) { 893 while (count < mpc->length) {
867 switch (*mpt) { 894 switch (*mpt) {
868 case MP_PROCESSOR: 895 case MP_PROCESSOR:
869 { 896 skip_entry(&mpt, &count, sizeof(struct mpc_cpu));
870 struct mpc_cpu *m = (struct mpc_cpu *)mpt; 897 break;
871 mpt += sizeof(*m);
872 count += sizeof(*m);
873 break;
874 }
875 case MP_BUS: 898 case MP_BUS:
876 { 899 skip_entry(&mpt, &count, sizeof(struct mpc_bus));
877 struct mpc_bus *m = (struct mpc_bus *)mpt; 900 break;
878 mpt += sizeof(*m);
879 count += sizeof(*m);
880 break;
881 }
882 case MP_IOAPIC: 901 case MP_IOAPIC:
883 { 902 skip_entry(&mpt, &count, sizeof(struct mpc_ioapic));
884 mpt += sizeof(struct mpc_ioapic); 903 break;
885 count += sizeof(struct mpc_ioapic);
886 break;
887 }
888 case MP_INTSRC: 904 case MP_INTSRC:
889 { 905 check_irq_src((struct mpc_intsrc *)&mpt, &nr_m_spare);
890#ifdef CONFIG_X86_IO_APIC 906 skip_entry(&mpt, &count, sizeof(struct mpc_intsrc));
891 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 907 break;
892
893 apic_printk(APIC_VERBOSE, "OLD ");
894 print_MP_intsrc_info(m);
895 i = get_MP_intsrc_index(m);
896 if (i > 0) {
897 assign_to_mpc_intsrc(&mp_irqs[i], m);
898 apic_printk(APIC_VERBOSE, "NEW ");
899 print_mp_irq_info(&mp_irqs[i]);
900 } else if (!i) {
901 /* legacy, do nothing */
902 } else if (nr_m_spare < SPARE_SLOT_NUM) {
903 /*
904 * not found (-1), or duplicated (-2)
905 * are invalid entries,
906 * we need to use the slot later
907 */
908 m_spare[nr_m_spare] = m;
909 nr_m_spare++;
910 }
911#endif
912 mpt += sizeof(struct mpc_intsrc);
913 count += sizeof(struct mpc_intsrc);
914 break;
915 }
916 case MP_LINTSRC: 908 case MP_LINTSRC:
917 { 909 skip_entry(&mpt, &count, sizeof(struct mpc_lintsrc));
918 struct mpc_lintsrc *m = 910 break;
919 (struct mpc_lintsrc *)mpt;
920 mpt += sizeof(*m);
921 count += sizeof(*m);
922 break;
923 }
924 default: 911 default:
925 /* wrong mptable */ 912 /* wrong mptable */
926 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n"); 913 printk(KERN_ERR "Your mptable is wrong, contact your HW vendor!\n");
@@ -950,16 +937,8 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
950 } else { 937 } else {
951 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt; 938 struct mpc_intsrc *m = (struct mpc_intsrc *)mpt;
952 count += sizeof(struct mpc_intsrc); 939 count += sizeof(struct mpc_intsrc);
953 if (!mpc_new_phys) { 940 if (!check_slot(mpc_new_phys, mpc_new_length, count))
954 printk(KERN_INFO "No spare slots, try to append...take your risk, new mpc_length %x\n", count); 941 goto out;
955 } else {
956 if (count <= mpc_new_length)
957 printk(KERN_INFO "No spare slots, try to append..., new mpc_length %x\n", count);
958 else {
959 printk(KERN_ERR "mpc_new_length %lx is too small\n", mpc_new_length);
960 goto out;
961 }
962 }
963 assign_to_mpc_intsrc(&mp_irqs[i], m); 942 assign_to_mpc_intsrc(&mp_irqs[i], m);
964 mpc->length = count; 943 mpc->length = count;
965 mpt += sizeof(struct mpc_intsrc); 944 mpt += sizeof(struct mpc_intsrc);