

Mostly just a couple of things split out of the original
H-nonlinear.. patch for x86-64.  Note, this only touches
x86-64 specific code. 

Basic nonlinear support for x86-64.  This also fixes a few
typos (such as CONFIG_ARCH_HAS_MEM_MAP) that resulted in 
build failures.  

Signed-off-by: Matt Tolentino <matthew.e.tolentino@intel.com>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 memhotplug1-dave/arch/x86_64/Kconfig            |   13 ++++++++
 memhotplug1-dave/arch/x86_64/kernel/apic.c      |    4 +-
 memhotplug1-dave/arch/x86_64/kernel/pci-gart.c  |    4 +-
 memhotplug1-dave/arch/x86_64/kernel/setup.c     |   11 ++++---
 memhotplug1-dave/arch/x86_64/kernel/setup64.c   |    2 -
 memhotplug1-dave/arch/x86_64/mm/init.c          |    5 ++-
 memhotplug1-dave/include/asm-x86_64/io.h        |    3 +
 memhotplug1-dave/include/asm-x86_64/nonlinear.h |    8 +++++
 memhotplug1-dave/include/asm-x86_64/page.h      |   37 ++++++++++++++++--------
 memhotplug1-dave/include/asm-x86_64/pgtable.h   |    1 
 10 files changed, 65 insertions(+), 23 deletions(-)

diff -puN arch/x86_64/Kconfig~H2-add_basic_nonlinear_support_for_x86-64 arch/x86_64/Kconfig
--- memhotplug1/arch/x86_64/Kconfig~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/arch/x86_64/Kconfig	2004-11-04 16:45:45.000000000 -0800
@@ -295,6 +295,19 @@ config NUMA
        bool
        default n
 
+config NONLINEAR
+       bool "Allow for nonlinear physical memory"
+       default y
+
+config ARCH_HAS_MEM_MAP
+       bool
+       depends on !DISCONTIGMEM && !NONLINEAR
+       default y
+
+config ARCH_HAS_BOOTPA
+       bool
+       default y
+
 config HAVE_DEC_LOCK
 	bool
 	depends on SMP
diff -puN arch/x86_64/kernel/apic.c~H2-add_basic_nonlinear_support_for_x86-64 arch/x86_64/kernel/apic.c
--- memhotplug1/arch/x86_64/kernel/apic.c~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/arch/x86_64/kernel/apic.c	2004-11-04 16:45:45.000000000 -0800
@@ -627,7 +627,7 @@ void __init init_apic_mappings(void)
 	 */
 	if (!smp_found_config && detect_init_APIC()) {
 		apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
-		apic_phys = __pa(apic_phys);
+		apic_phys = __boot_pa(apic_phys);
 	} else
 		apic_phys = mp_lapic_addr;
 
@@ -651,7 +651,7 @@ void __init init_apic_mappings(void)
 				ioapic_phys = mp_ioapics[i].mpc_apicaddr;
 			} else {
 				ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
-				ioapic_phys = __pa(ioapic_phys);
+				ioapic_phys = __boot_pa(ioapic_phys);
 			}
 			set_fixmap_nocache(idx, ioapic_phys);
 			apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n",
diff -puN arch/x86_64/kernel/pci-gart.c~H2-add_basic_nonlinear_support_for_x86-64 arch/x86_64/kernel/pci-gart.c
--- memhotplug1/arch/x86_64/kernel/pci-gart.c~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/arch/x86_64/kernel/pci-gart.c	2004-11-04 16:45:45.000000000 -0800
@@ -736,7 +736,7 @@ static __init int init_k8_gatt(struct ag
 		u32 ctl; 
 		u32 gatt_reg; 
 
-		gatt_reg = __pa(gatt) >> 12; 
+		gatt_reg = __boot_pa(gatt) >> 12;
 		gatt_reg <<= 4; 
 		pci_write_config_dword(dev, 0x98, gatt_reg);
 		pci_read_config_dword(dev, 0x90, &ctl); 
@@ -862,7 +862,7 @@ static int __init pci_iommu_init(void)
 	scratch = get_zeroed_page(GFP_KERNEL); 
 	if (!scratch) 
 		panic("Cannot allocate iommu scratch page");
-	gart_unmapped_entry = GPTE_ENCODE(__pa(scratch));
+	gart_unmapped_entry = GPTE_ENCODE(__boot_pa(scratch));
 	for (i = EMERGENCY_PAGES; i < iommu_pages; i++) 
 		iommu_gatt_base[i] = gart_unmapped_entry;
 
diff -puN arch/x86_64/kernel/setup.c~H2-add_basic_nonlinear_support_for_x86-64 arch/x86_64/kernel/setup.c
--- memhotplug1/arch/x86_64/kernel/setup.c~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/arch/x86_64/kernel/setup.c	2004-11-04 16:45:45.000000000 -0800
@@ -467,10 +467,10 @@ void __init setup_arch(char **cmdline_p)
 	init_mm.end_data = (unsigned long) &_edata;
 	init_mm.brk = (unsigned long) &_end;
 
-	code_resource.start = virt_to_phys(&_text);
-	code_resource.end = virt_to_phys(&_etext)-1;
-	data_resource.start = virt_to_phys(&_etext);
-	data_resource.end = virt_to_phys(&_edata)-1;
+	code_resource.start = __boot_pa(&_text);
+	code_resource.end = __boot_pa(&_etext)-1;
+	data_resource.start = __boot_pa(&_etext);
+	data_resource.end = __boot_pa(&_edata)-1;
 
 	parse_cmdline_early(cmdline_p);
 
@@ -480,6 +480,9 @@ void __init setup_arch(char **cmdline_p)
 	 */
 	end_pfn = e820_end_of_ram();
 
+	setup_memsections();
+	alloc_memsections(0, 0, end_pfn);
+
 	check_efer();
 
 	init_memory_mapping(); 
diff -puN arch/x86_64/kernel/setup64.c~H2-add_basic_nonlinear_support_for_x86-64 arch/x86_64/kernel/setup64.c
--- memhotplug1/arch/x86_64/kernel/setup64.c~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/arch/x86_64/kernel/setup64.c	2004-11-04 16:45:45.000000000 -0800
@@ -134,7 +134,7 @@ void pda_init(int cpu)
 	if (level4 != init_level4_pgt)
 		memcpy(level4, &init_level4_pgt, PAGE_SIZE); 
 	set_pml4(level4 + 510, mk_kernel_pml4(__pa_symbol(boot_vmalloc_pgt)));
-	asm volatile("movq %0,%%cr3" :: "r" (__pa(level4))); 
+	asm volatile("movq %0,%%cr3" :: "r" (__boot_pa(level4)));
 
 	pda->irqstackptr += IRQSTACKSIZE-64;
 } 
diff -puN arch/x86_64/mm/init.c~H2-add_basic_nonlinear_support_for_x86-64 arch/x86_64/mm/init.c
--- memhotplug1/arch/x86_64/mm/init.c~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/arch/x86_64/mm/init.c	2004-11-04 16:45:45.000000000 -0800
@@ -444,7 +444,7 @@ void __init mem_init(void)
 	max_low_pfn = end_pfn;
 	max_pfn = end_pfn;
 	num_physpages = end_pfn;
-	high_memory = (void *) __va(end_pfn * PAGE_SIZE);
+	high_memory = (void *) __va((end_pfn-1) * PAGE_SIZE);
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
@@ -458,7 +458,10 @@ void __init mem_init(void)
 	/* should count reserved pages here for all nodes */ 
 #else
 	max_mapnr = end_pfn;
+
+#ifdef CONFIG_ARCH_HAS_MEM_MAP
 	if (!mem_map) BUG();
+#endif
 
 	totalram_pages += free_all_bootmem();
 
diff -puN include/asm-x86_64/io.h~H2-add_basic_nonlinear_support_for_x86-64 include/asm-x86_64/io.h
--- memhotplug1/include/asm-x86_64/io.h~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/include/asm-x86_64/io.h	2004-11-04 16:45:45.000000000 -0800
@@ -108,6 +108,7 @@ __OUTS(l)
 #if defined(__KERNEL__) && __x86_64__
 
 #include <linux/vmalloc.h>
+#include <linux/nonlinear.h>
 
 #ifndef __i386__
 /*
@@ -116,7 +117,7 @@ __OUTS(l)
  */
 extern inline unsigned long virt_to_phys(volatile void * address)
 {
-	return __pa(address);
+	return __pa((void *)address);
 }
 
 extern inline void * phys_to_virt(unsigned long address)
diff -puN /dev/null include/asm-x86_64/nonlinear.h
--- /dev/null	2004-08-06 10:20:23.000000000 -0700
+++ memhotplug1-dave/include/asm-x86_64/nonlinear.h	2004-11-04 16:45:45.000000000 -0800
@@ -0,0 +1,8 @@
+#ifndef __X86_64_NONLINEAR_H_
+#define __X64_64_NONLINEAR_H_
+
+#define SECTION_SHIFT		27	/* Size of section - 128 Mbytes */
+#define	MAX_MEM_SHIFT		40
+#define	MAX_PHYS_SHIFT		40
+
+#endif /* __X86_64_NONLINEAR_H_ */
diff -puN include/asm-x86_64/page.h~H2-add_basic_nonlinear_support_for_x86-64 include/asm-x86_64/page.h
--- memhotplug1/include/asm-x86_64/page.h~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/include/asm-x86_64/page.h	2004-11-04 16:45:45.000000000 -0800
@@ -105,22 +105,33 @@ extern __inline__ int get_order(unsigned
 	return order;
 }
 
-#endif /* __ASSEMBLY__ */
-
 #define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET)
 
-/* Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol.
-   Otherwise you risk miscompilation. */ 
-#define __pa(x)			(((unsigned long)(x)>=__START_KERNEL_map)?(unsigned long)(x) - (unsigned long)__START_KERNEL_map:(unsigned long)(x) - PAGE_OFFSET)
-/* __pa_symbol should be used for C visible symbols.
-   This seems to be the official gcc blessed way to do such arithmetic. */ 
-#define __pa_symbol(x)		\
-	({unsigned long v;  \
+/*
+ * Note: __pa(&symbol_visible_to_c) should be always replaced with __pa_symbol.
+ * Otherwise you risk miscompilation.
+ */
+#define __boot_pa(x)  (((unsigned long)(x)>=__START_KERNEL_map)?(unsigned long)(x) - (unsigned long)__START_KERNEL_map:(unsigned long)(x) - PAGE_OFFSET)
+#define __boot_va(x)  ((void *)((unsigned long)(x)+PAGE_OFFSET))
+
+#ifndef CONFIG_NONLINEAR
+#define __pa(x)	__boot_pa(x)
+#define __va(x)	__boot_va(x)
+#else
+#include <linux/nonlinear.h>
+#endif
+
+/*
+ * __pa_symbol should be used for C visible symbols.
+ * This seems to be the official gcc blessed way to do
+ * such arithmetic.
+ */
+#define __pa_symbol(x)			\
+	({unsigned long v;		\
 	  asm("" : "=r" (v) : "0" (x)); \
-	  __pa(v); })
+	__boot_pa(v); })
 
-#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
-#ifndef CONFIG_DISCONTIGMEM
+#ifdef CONFIG_ARCH_HAS_MEM_MAP
 #define pfn_to_page(pfn)	(mem_map + (pfn))
 #define page_to_pfn(page)	((unsigned long)((page) - mem_map))
 #define pfn_valid(pfn)		((pfn) < max_mapnr)
@@ -130,6 +141,8 @@ extern __inline__ int get_order(unsigned
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 
+#endif /* __ASSEMBLY__ */
+
 #define VM_DATA_DEFAULT_FLAGS \
 	(((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
 	 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff -puN include/asm-x86_64/pgtable.h~H2-add_basic_nonlinear_support_for_x86-64 include/asm-x86_64/pgtable.h
--- memhotplug1/include/asm-x86_64/pgtable.h~H2-add_basic_nonlinear_support_for_x86-64	2004-11-04 16:45:45.000000000 -0800
+++ memhotplug1-dave/include/asm-x86_64/pgtable.h	2004-11-04 16:45:45.000000000 -0800
@@ -15,6 +15,7 @@
 #include <asm/fixmap.h>
 #include <asm/bitops.h>
 #include <linux/threads.h>
+#include <linux/nonlinear.h>
 #include <asm/pda.h>
 
 extern pgd_t level3_kernel_pgt[512];
_
