diff options
author | Jaswinder Singh Rajput <jaswinderrajput@gmail.com> | 2009-03-18 11:12:28 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-03-18 12:15:05 -0400 |
commit | a6830278568a8bb9758aac152db15187741e0113 (patch) | |
tree | 2bd3e669a53e0372b4a78a5fb3ef9b2fcd65669c /arch/x86/kernel/mpparse.c | |
parent | cde5edbda8ba7d600154ce4171125a48e4d2a21b (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.c | 261 |
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 | ||
116 | static int bad_ioapic(unsigned long address) | 113 | static 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 */ | ||
225 | static inline void __init MP_bus_info(struct mpc_bus *m) {} | ||
226 | static inline void __init MP_ioapic_info(struct mpc_ioapic *m) {} | ||
227 | static inline void __init MP_intsrc_info(struct mpc_intsrc *m) {} | ||
228 | #endif /* CONFIG_X86_IO_APIC */ | ||
227 | 229 | ||
228 | #endif | ||
229 | 230 | ||
230 | static void __init MP_lintsrc_info(struct mpc_lintsrc *m) | 231 | static 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 | ||
279 | static void skip_entry(unsigned char **ptr, int *count, int size) | ||
280 | { | ||
281 | *ptr += size; | ||
282 | *count += size; | ||
283 | } | ||
284 | |||
278 | static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early) | 285 | static 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 | ||
671 | static 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 | |||
692 | static int __init smp_scan_config(unsigned long base, unsigned long length, | 696 | static 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 | ||
850 | static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; | 828 | static struct mpc_intsrc __initdata *m_spare[SPARE_SLOT_NUM]; |
851 | #endif | 829 | |
830 | static 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 */ | ||
858 | static inline void check_irq_src(struct mpc_intsrc *m, int *nr_m_spare) {} | ||
859 | #endif /* CONFIG_X86_IO_APIC */ | ||
860 | |||
861 | static 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 | ||
853 | static int __init replace_intsrc_all(struct mpc_table *mpc, | 881 | static 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); |