x86: unify smp_scan_config
authorAlexey Starikovskiy <astarikovskiy@suse.de>
Fri, 4 Apr 2008 19:42:46 +0000 (23:42 +0400)
committerIngo Molnar <mingo@elte.hu>
Thu, 17 Apr 2008 15:41:36 +0000 (17:41 +0200)
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/mpparse_32.c
arch/x86/kernel/mpparse_64.c

index bc2000e..7feafa5 100644 (file)
@@ -683,12 +683,13 @@ void __init get_smp_config(void)
 static int __init smp_scan_config(unsigned long base, unsigned long length,
                                  unsigned reserve)
 {
-       unsigned long *bp = phys_to_virt(base);
+       extern void __bad_mpf_size(void);
+       unsigned int *bp = phys_to_virt(base);
        struct intel_mp_floating *mpf;
 
-       printk(KERN_INFO "Scan SMP from %p for %ld bytes.\n", bp, length);
+       Dprintk("Scan SMP from %p for %ld bytes.\n", bp, length);
        if (sizeof(*mpf) != 16)
-               printk("Error: MPF size\n");
+               __bad_mpf_size();
 
        while (length > 0) {
                mpf = (struct intel_mp_floating *)bp;
@@ -699,6 +700,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
                     || (mpf->mpf_specification == 4))) {
 
                        smp_found_config = 1;
+                       mpf_found = mpf;
+#ifdef CONFIG_X86_32
                        printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
                               mpf, virt_to_phys(mpf));
                        reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
@@ -721,8 +724,16 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
                                                BOOTMEM_DEFAULT);
                        }
 
-                       mpf_found = mpf;
-                       return 1;
+#else
+                       if (!reserve)
+                               return 1;
+
+                       reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE);
+                       if (mpf->mpf_physptr)
+                               reserve_bootmem_generic(mpf->mpf_physptr,
+                                                       PAGE_SIZE);
+#endif
+               return 1;
                }
                bp += 4;
                length -= 16;
index 8c7af5b..9a96100 100644 (file)
@@ -593,7 +593,30 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
 
                        smp_found_config = 1;
                        mpf_found = mpf;
+#ifdef CONFIG_X86_32
+                       printk(KERN_INFO "found SMP MP-table at [%p] %08lx\n",
+                              mpf, virt_to_phys(mpf));
+                       reserve_bootmem(virt_to_phys(mpf), PAGE_SIZE,
+                                       BOOTMEM_DEFAULT);
+                       if (mpf->mpf_physptr) {
+                               /*
+                                * We cannot access to MPC table to compute
+                                * table size yet, as only few megabytes from
+                                * the bottom is mapped now.
+                                * PC-9800's MPC table places on the very last
+                                * of physical memory; so that simply reserving
+                                * PAGE_SIZE from mpg->mpf_physptr yields BUG()
+                                * in reserve_bootmem.
+                                */
+                               unsigned long size = PAGE_SIZE;
+                               unsigned long end = max_low_pfn * PAGE_SIZE;
+                               if (mpf->mpf_physptr + size > end)
+                                       size = end - mpf->mpf_physptr;
+                               reserve_bootmem(mpf->mpf_physptr, size,
+                                               BOOTMEM_DEFAULT);
+                       }
 
+#else
                        if (!reserve)
                                return 1;
 
@@ -601,7 +624,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
                        if (mpf->mpf_physptr)
                                reserve_bootmem_generic(mpf->mpf_physptr,
                                                        PAGE_SIZE);
-                       return 1;
+#endif
+               return 1;
                }
                bp += 4;
                length -= 16;