Browse Source

x86: unify smp_scan_config

Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Alexey Starikovskiy 17 years ago
parent
commit
92fd4b7abd
2 changed files with 41 additions and 6 deletions
  1. 16 5
      arch/x86/kernel/mpparse_32.c
  2. 25 1
      arch/x86/kernel/mpparse_64.c

+ 16 - 5
arch/x86/kernel/mpparse_32.c

@@ -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;

+ 25 - 1
arch/x86/kernel/mpparse_64.c

@@ -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;