

* create boot_abs_to_virt() and boot_virt_to_abs() to use __boot_pa()
  and __boot_va() for early boot code.

* change a lot of code to use __boot variants in early boot.  nonlinear
  won't work when relocation is on anyway

* switch rtas_call() and create_pte_mapping() to use __boot or nonlinear
  variants based on system_state variable

* compute first page on the node in show_mem() with pfn_to_page(), not
  node_mem_map

from Joel Schopp:
* remove mem_init pgdat->node_mem_map refernce
* remove cyclic io.h dependency

Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---

 memhotplug-dave/arch/ppc64/kernel/pSeries_smp.c |    2 +-
 memhotplug-dave/arch/ppc64/kernel/prom.c        |    4 ++--
 memhotplug-dave/arch/ppc64/kernel/rtas.c        |   21 +++++++++++++--------
 memhotplug-dave/arch/ppc64/kernel/smp.c         |    5 ++++-
 memhotplug-dave/arch/ppc64/mm/hash_utils.c      |   13 ++++++++++---
 memhotplug-dave/arch/ppc64/mm/init.c            |   16 +++++++++++-----
 memhotplug-dave/include/asm-ppc64/abs_addr.h    |    6 ++++--
 memhotplug-dave/include/asm-ppc64/nonlinear.h   |    8 ++++++++
 memhotplug-dave/include/asm-ppc64/page.h        |   18 +++++++++++++-----
 9 files changed, 66 insertions(+), 27 deletions(-)

diff -puN arch/ppc64/Kconfig~G1-nonlinear-ppc64-daveh arch/ppc64/Kconfig
diff -puN arch/ppc64/kernel/prom.c~G1-nonlinear-ppc64-daveh arch/ppc64/kernel/prom.c
--- memhotplug/arch/ppc64/kernel/prom.c~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:40.000000000 -0800
+++ memhotplug-dave/arch/ppc64/kernel/prom.c	2004-12-10 13:52:41.000000000 -0800
@@ -567,7 +567,7 @@ void __init finish_device_tree(void)
 
 	/* Finish device-tree (pre-parsing some properties etc...) */
 	size = finish_node(allnodes, 0, NULL, 0, 0, 1);
-	mem = (unsigned long)abs_to_virt(lmb_alloc(size, 128));
+	mem = (unsigned long)boot_abs_to_virt(lmb_alloc(size, 128));
 	if (finish_node(allnodes, mem, NULL, 0, 0, 0) != mem + size)
 		BUG();
 
@@ -801,7 +801,7 @@ void __init unflatten_device_tree(void)
 	DBG("  size is %lx, allocating...\n", size);
 
 	/* Allocate memory for the expanded device tree */
-	mem = (unsigned long)abs_to_virt(lmb_alloc(size,
+	mem = (unsigned long)boot_abs_to_virt(lmb_alloc(size,
 						   __alignof__(struct device_node)));
 	DBG("  unflattening...\n", mem);
 
diff -puN arch/ppc64/kernel/rtas.c~G1-nonlinear-ppc64-daveh arch/ppc64/kernel/rtas.c
--- memhotplug/arch/ppc64/kernel/rtas.c~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/arch/ppc64/kernel/rtas.c	2004-12-10 13:52:41.000000000 -0800
@@ -60,7 +60,7 @@ call_rtas_display_status(unsigned char c
 	args->rets  = (rtas_arg_t *)&(args->args[1]);
 	args->args[0] = (int)c;
 
-	enter_rtas(__pa(args));
+	enter_rtas(virt_to_phys(args));
 
 	spin_unlock_irqrestore(&rtas.lock, s);
 }
@@ -164,6 +164,7 @@ int rtas_call(int token, int nargs, int 
 	struct rtas_args *rtas_args;
 	char * buff_copy = NULL;
 	int ret;
+	unsigned long rtas_args_paddr;
 
 	PPCDBG(PPCDBG_RTAS, "Entering rtas_call\n");
 	PPCDBG(PPCDBG_RTAS, "\ttoken    = 0x%x\n", token);
@@ -191,9 +192,13 @@ int rtas_call(int token, int nargs, int 
 	for (i = 0; i < nret; ++i)
 		rtas_args->rets[i] = 0;
 
-	PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n",
-		__pa(rtas_args));
-	enter_rtas(__pa(rtas_args));
+	if (likely(system_state >= SYSTEM_RUNNING))
+		rtas_args_paddr = virt_to_phys(rtas_args);
+	else
+		rtas_args_paddr = __boot_pa(rtas_args);
+
+	PPCDBG(PPCDBG_RTAS, "\tentering rtas with 0x%lx\n", rtas_args_paddr);
+	enter_rtas(rtas_args_paddr);
 	PPCDBG(PPCDBG_RTAS, "\treturned from rtas ...\n");
 
 	/* A -1 return code indicates that the last command couldn't
@@ -361,7 +366,7 @@ rtas_flash_firmware(void)
 	 */
 	rtas_firmware_flash_list.num_blocks = 0;
 	flist = (struct flash_block_list *)&rtas_firmware_flash_list;
-	rtas_block_list = virt_to_abs(flist);
+	rtas_block_list = boot_virt_to_abs(flist);
 	if (rtas_block_list >= 4UL*1024*1024*1024) {
 		printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n");
 		return;
@@ -373,13 +378,13 @@ rtas_flash_firmware(void)
 	for (f = flist; f; f = next) {
 		/* Translate data addrs to absolute */
 		for (i = 0; i < f->num_blocks; i++) {
-			f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data);
+			f->blocks[i].data = (char *)boot_virt_to_abs(f->blocks[i].data);
 			image_size += f->blocks[i].length;
 		}
 		next = f->next;
 		/* Don't translate NULL pointer for last entry */
 		if (f->next)
-			f->next = (struct flash_block_list *)virt_to_abs(f->next);
+			f->next = (struct flash_block_list *)boot_virt_to_abs(f->next);
 		else
 			f->next = NULL;
 		/* make num_blocks into the version/length field */
@@ -462,7 +467,7 @@ void rtas_os_term(char *str)
 
 	do {
 		status = rtas_call(rtas_token("ibm,os-term"), 1, 1, NULL,
-				   __pa(rtas_os_term_buf));
+				   virt_to_phys(rtas_os_term_buf));
 
 		if (status == RTAS_BUSY)
 			udelay(1);
diff -puN arch/ppc64/kernel/smp.c~G1-nonlinear-ppc64-daveh arch/ppc64/kernel/smp.c
--- memhotplug/arch/ppc64/kernel/smp.c~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/arch/ppc64/kernel/smp.c	2004-12-10 13:52:41.000000000 -0800
@@ -444,7 +444,10 @@ int __devinit __cpu_up(unsigned int cpu)
 		tmp = &stab_array[PAGE_SIZE * cpu];
 		memset(tmp, 0, PAGE_SIZE); 
 		paca[cpu].stab_addr = (unsigned long)tmp;
-		paca[cpu].stab_real = virt_to_abs(tmp);
+		if(system_state <= SYSTEM_BOOTING)
+			paca[cpu].stab_real = boot_virt_to_abs(tmp);
+		else
+			paca[cpu].stab_real = virt_to_abs(tmp);
 	}
 
 	/* Make sure callin-map entry is 0 (can be leftover a CPU
diff -puN arch/ppc64/kernel/vio.c~G1-nonlinear-ppc64-daveh arch/ppc64/kernel/vio.c
diff -puN arch/ppc64/mm/hash_utils.c~G1-nonlinear-ppc64-daveh arch/ppc64/mm/hash_utils.c
--- memhotplug/arch/ppc64/mm/hash_utils.c~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/arch/ppc64/mm/hash_utils.c	2004-12-10 13:52:41.000000000 -0800
@@ -105,8 +105,15 @@ static inline void create_pte_mapping(un
 		unsigned long vpn, hash, hpteg;
 		unsigned long vsid = get_kernel_vsid(addr);
 		unsigned long va = (vsid << 28) | (addr & 0xfffffff);
+		unsigned long abs_page_nr, abs_page_addr;
 		int ret;
 
+		if (system_state >= SYSTEM_RUNNING)
+			abs_page_addr = virt_to_abs((void *)addr);
+		else
+			abs_page_addr = boot_virt_to_abs(addr);
+		abs_page_nr = abs_page_addr >> PAGE_SHIFT;
+
 		if (large)
 			vpn = va >> HPAGE_SHIFT;
 		else
@@ -120,12 +127,12 @@ static inline void create_pte_mapping(un
 		if (systemcfg->platform & PLATFORM_LPAR)
 			ret = pSeries_lpar_hpte_insert(hpteg, va,
 				virt_to_abs(addr) >> PAGE_SHIFT,
-				0, mode, 1, large);
+				abs_page_nr, mode, 1, large);
 		else
 #endif /* CONFIG_PPC_PSERIES */
 			ret = native_hpte_insert(hpteg, va,
 				virt_to_abs(addr) >> PAGE_SHIFT,
-				0, mode, 1, large);
+				abs_page_nr, mode, 1, large);
 
 		if (ret == -1) {
 			ppc64_terminate_msg(0x20, "create_pte_mapping");
@@ -176,7 +183,7 @@ void __init htab_initialize(void)
 			ppc64_terminate_msg(0x20, "hpt space");
 			loop_forever();
 		}
-		htab_data.htab = abs_to_virt(table);
+		htab_data.htab = boot_abs_to_virt(table);
 
 		/* htab absolute addr + encoded htabsize */
 		_SDR1 = table + __ilog2(pteg_count) - 11;
diff -puN arch/ppc64/mm/init.c~G1-nonlinear-ppc64-daveh arch/ppc64/mm/init.c
--- memhotplug/arch/ppc64/mm/init.c~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/arch/ppc64/mm/init.c	2004-12-10 13:52:41.000000000 -0800
@@ -98,7 +98,7 @@ void show_mem(void)
 	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			page = pgdat->node_mem_map + i;
+			page = pfn_to_page(i);
 			total++;
 			if (PageReserved(page))
 				reserved++;
@@ -447,8 +447,8 @@ void free_initmem(void)
 
 	addr = (unsigned long)__init_begin;
 	for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
-		ClearPageReserved(virt_to_page(addr));
-		set_page_count(virt_to_page(addr), 1);
+		ClearPageReserved(virt_to_page((void *)addr));
+		set_page_count(virt_to_page((void *)addr), 1);
 		free_page(addr);
 		totalram_pages++;
 	}
@@ -601,6 +601,11 @@ void __init do_init_bootmem(void)
 	unsigned long total_pages = lmb_end_of_DRAM() >> PAGE_SHIFT;
 	int boot_mapsize;
 
+#ifdef CONFIG_NONLINEAR
+	setup_memsections();
+	alloc_memsections(0, 0, total_pages);
+#endif
+
 	/*
 	 * Find an area to use for the bootmem bitmap.  Calculate the size of
 	 * bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
@@ -658,7 +663,7 @@ void __init paging_init(void)
 	memset(zones_size, 0, sizeof(zones_size));
 	memset(zholes_size, 0, sizeof(zholes_size));
 
-	zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
+	zones_size[ZONE_DMA] = top_pfn;
 	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
 
 	free_area_init_node(0, &contig_page_data, zones_size,
@@ -721,7 +726,7 @@ void __init mem_init(void)
 
 	for_each_pgdat(pgdat) {
 		for (i = 0; i < pgdat->node_spanned_pages; i++) {
-			page = pgdat->node_mem_map + i;
+			page = pfn_to_page(pgdat->node_start_pfn + i);
 			if (PageReserved(page))
 				reservedpages++;
 		}
@@ -909,3 +914,4 @@ pgd_t *__pgd_alloc(struct mm_struct *mm,
 {
 	return kmem_cache_alloc(zero_cache, GFP_KERNEL);
 }
+
diff -puN arch/ppc64/xmon/xmon.c~G1-nonlinear-ppc64-daveh arch/ppc64/xmon/xmon.c
diff -puN include/asm-ppc64/abs_addr.h~G1-nonlinear-ppc64-daveh include/asm-ppc64/abs_addr.h
--- memhotplug/include/asm-ppc64/abs_addr.h~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/include/asm-ppc64/abs_addr.h	2004-12-10 13:52:41.000000000 -0800
@@ -102,7 +102,9 @@ physRpn_to_absRpn(unsigned long rpn)
 #endif /* !CONFIG_MSCHUNKS */
 
 /* Convenience macros */
-#define virt_to_abs(va) phys_to_abs(__pa(va))
-#define abs_to_virt(aa) __va(abs_to_phys(aa))
+#define virt_to_abs(va) phys_to_abs(virt_to_phys(va))
+#define abs_to_virt(aa) phys_to_virt(abs_to_phys(aa))
+#define boot_virt_to_abs(va) phys_to_abs(__boot_pa(va))
+#define boot_abs_to_virt(aa) __boot_va(abs_to_phys(aa))
 
 #endif /* _ABS_ADDR_H */
diff -puN /dev/null include/asm-ppc64/nonlinear.h
--- /dev/null	2004-11-08 15:18:04.000000000 -0800
+++ memhotplug-dave/include/asm-ppc64/nonlinear.h	2004-12-10 13:52:41.000000000 -0800
@@ -0,0 +1,8 @@
+#ifndef __PPC64_NONLINEAR_H_
+#define __PPC64_NONLINEAR_H_
+
+#define SECTION_SHIFT		28	/* Size of section - 256 Mbytes */
+#define	MAX_MEM_SHIFT		40
+#define	MAX_PHYS_SHIFT		40
+
+#endif /* __PPC64_NONLINEAR_H_ */
diff -puN include/asm-ppc64/page.h~G1-nonlinear-ppc64-daveh include/asm-ppc64/page.h
--- memhotplug/include/asm-ppc64/page.h~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/include/asm-ppc64/page.h	2004-12-10 13:52:41.000000000 -0800
@@ -217,23 +217,31 @@ extern int page_is_ram(unsigned long pfn
 #define USER_REGION_ID     (0UL)
 #define REGION_ID(X)	   (((unsigned long)(X))>>REGION_SHIFT)
 
-#define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE)
+#define __bpn_to_ba(x) __va(((unsigned long)(x))<<PAGE_SHIFT)
 #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT)
 
+#ifndef __ASSEMBLY__
 #ifdef CONFIG_DISCONTIGMEM
 #define page_to_pfn(page)	discontigmem_page_to_pfn(page)
 #define pfn_to_page(pfn)	discontigmem_pfn_to_page(pfn)
 #define pfn_valid(pfn)		discontigmem_pfn_valid(pfn)
-#else
+#elif defined CONFIG_NONLINEAR
+extern unsigned long page_to_pfn(struct page *page);
+extern struct page *pfn_to_page(unsigned long);
+#else /* !CONFIG_NONLINEAR && !CONFIG_DISCONTIGMEM */
 #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)
 #endif
 
-#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_to_kaddr(pfn)	__va((pfn) << PAGE_SHIFT)
+#include <linux/nonlinear.h>
 
-#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_kaddr(pfn)	phys_to_virt((pfn) << PAGE_SHIFT)
+#define virt_to_page(kaddr)	pfn_to_page(virt_to_phys(kaddr) >> PAGE_SHIFT)
+
+#define virt_addr_valid(kaddr)	pfn_valid(virt_to_phys(kaddr) >> PAGE_SHIFT)
+
+#endif /* __ASSEMBLY__ */
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff -puN include/linux/nonlinear.h~G1-nonlinear-ppc64-daveh include/linux/nonlinear.h
diff -puN mm/nonlinear.c~G1-nonlinear-ppc64-daveh mm/nonlinear.c
diff -puN mm/page_alloc.c~G1-nonlinear-ppc64-daveh mm/page_alloc.c
diff -L I-nonlinear-ppc64-dave-hmore -puN /dev/null /dev/null
diff -puN arch/ppc64/kernel/pSeries_smp.c~G1-nonlinear-ppc64-daveh arch/ppc64/kernel/pSeries_smp.c
--- memhotplug/arch/ppc64/kernel/pSeries_smp.c~G1-nonlinear-ppc64-daveh	2004-12-10 13:52:41.000000000 -0800
+++ memhotplug-dave/arch/ppc64/kernel/pSeries_smp.c	2004-12-10 13:52:41.000000000 -0800
@@ -65,7 +65,7 @@ static void vpa_init(int cpu)
 
 	/* Register the Virtual Processor Area (VPA) */
 	flags = 1UL << (63 - 18);
-	register_vpa(flags, pcpu, __pa((unsigned long)&(paca[cpu].lppaca)));
+	register_vpa(flags, pcpu, __boot_pa((unsigned long)&(paca[cpu].lppaca)));
 }
 
 
_
