
[ppc64] early BSS clear, from Ben Herrenschmidt
  
Gone are the days of initialising stuff we touch in prom_init just
to keep it out of the BSS. There are a few things the hypervisor
writes to in the iseries case, hard code them into the data segment
and add a comment.
  
Remove the -fno-zero-initialized-in-bss hack, it was required when
gcc got smart and put zero initialised stuff into the BSS


---

 arch/ppc64/Makefile          |    6 -----
 arch/ppc64/kernel/LparData.c |   48 +++++++++++++++++++-----------------------
 arch/ppc64/kernel/head.S     |   49 ++++++++++++++-----------------------------
 arch/ppc64/kernel/prom.c     |   15 ++++++++++---
 4 files changed, 51 insertions(+), 67 deletions(-)

diff -puN arch/ppc64/Makefile~ppc64-bss_clear arch/ppc64/Makefile
--- 25/arch/ppc64/Makefile~ppc64-bss_clear	2004-01-13 23:23:17.000000000 -0800
+++ 25-akpm/arch/ppc64/Makefile	2004-01-13 23:23:17.000000000 -0800
@@ -36,12 +36,6 @@ CFLAGS		+= -mtune=power4
 endif
 endif
 
-have_zero_bss := $(shell if $(CC) -fno-zero-initialized-in-bss -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
-
-ifeq ($(have_zero_bss),y)
-CFLAGS		+= -fno-zero-initialized-in-bss
-endif
-
 head-y := arch/ppc64/kernel/head.o
 
 libs-y				+= arch/ppc64/lib/
diff -puN arch/ppc64/kernel/LparData.c~ppc64-bss_clear arch/ppc64/kernel/LparData.c
--- 25/arch/ppc64/kernel/LparData.c~ppc64-bss_clear	2004-01-13 23:23:17.000000000 -0800
+++ 25-akpm/arch/ppc64/kernel/LparData.c	2004-01-13 23:23:17.000000000 -0800
@@ -28,29 +28,12 @@
 #include <asm/iSeries/IoHriProcessorVpd.h>
 #include <asm/iSeries/ItSpCommArea.h>
 
-extern char _start_boltedStacks[];
-
-/* The LparMap data is now located at offset 0x6000 in head.S
- * It was put there so that the HvReleaseData could address it
- * with a 32-bit offset as required by the iSeries hypervisor
- *
- * The Naca has a pointer to the ItVpdAreas.  The hypervisor finds
- * the Naca via the HvReleaseData area.  The HvReleaseData has the
- * offset into the Naca of the pointer to the ItVpdAreas.
- */
-
-extern struct ItVpdAreas itVpdAreas;
-
 /* The LpQueue is used to pass event data from the hypervisor to
  * the partition.  This is where I/O interrupt events are communicated.
- * The ItLpQueue must be initialized (even though only to all zeros)
- * If it were uninitialized (in .bss) it would get zeroed after the
- * kernel gets control.  The hypervisor will have filled in some fields
- * before the kernel gets control.  By initializing it we keep it out
- * of the .bss
  */
 
-struct ItLpQueue xItLpQueue = {};
+/* May be filled in by the hypervisor so cannot end up in the BSS */
+struct ItLpQueue xItLpQueue __attribute__((__section__(".data")));
 
 
 /* The HvReleaseData is the root of the information shared between 
@@ -141,9 +124,11 @@ struct ItLpNaca itLpNaca = {
 	}
 };
 
-struct ItIplParmsReal xItIplParmsReal = {};
+/* May be filled in by the hypervisor so cannot end up in the BSS */
+struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); 
 
-struct ItExtVpdPanel xItExtVpdPanel = {};
+/* May be filled in by the hypervisor so cannot end up in the BSS */
+struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
 
 #define maxPhysicalProcessors 32
 
@@ -157,10 +142,13 @@ struct IoHriProcessorVpd xIoHriProcessor
 	}
 };
 	
-
-u64    xMsVpd[3400] = {};		/* Space for Main Store Vpd 27,200 bytes */
-
-u64    xRecoveryLogBuffer[32] = {};	/* Space for Recovery Log Buffer */
+/* Space for Main Store Vpd 27,200 bytes */
+/* May be filled in by the hypervisor so cannot end up in the BSS */
+u64    xMsVpd[3400] __attribute__((__section__(".data")));
+
+/* Space for Recovery Log Buffer */
+/* May be filled in by the hypervisor so cannot end up in the BSS */
+u64    xRecoveryLogBuffer[32] __attribute__((__section__(".data")));
 
 struct SpCommArea xSpCommArea = {
 	0xE2D7C3C2,
@@ -169,6 +157,14 @@ struct SpCommArea xSpCommArea = {
 	0, 0, 0, 0, {0}
 };
 
+/* The LparMap data is now located at offset 0x6000 in head.S
+ * It was put there so that the HvReleaseData could address it
+ * with a 32-bit offset as required by the iSeries hypervisor
+ *
+ * The Naca has a pointer to the ItVpdAreas.  The hypervisor finds
+ * the Naca via the HvReleaseData area.  The HvReleaseData has the
+ * offset into the Naca of the pointer to the ItVpdAreas.
+ */
 struct ItVpdAreas itVpdAreas = {
 	0xc9a3e5c1,	/* "ItVA" */
 	sizeof( struct ItVpdAreas ),
@@ -223,7 +219,7 @@ struct ItVpdAreas itVpdAreas = {
 	}
 };
 
-struct msChunks msChunks = {0, 0, 0, 0, NULL};
+struct msChunks msChunks;
 
 /* Depending on whether this is called from iSeries or pSeries setup
  * code, the location of the msChunks struct may or may not have
diff -puN arch/ppc64/kernel/head.S~ppc64-bss_clear arch/ppc64/kernel/head.S
--- 25/arch/ppc64/kernel/head.S~ppc64-bss_clear	2004-01-13 23:23:17.000000000 -0800
+++ 25-akpm/arch/ppc64/kernel/head.S	2004-01-13 23:23:17.000000000 -0800
@@ -1248,7 +1248,21 @@ _GLOBAL(pseries_secondary_smp_init)
 	b 	1b			 /* Loop until told to go         */
 #ifdef CONFIG_PPC_ISERIES
 _GLOBAL(__start_initialization_iSeries)
+	/* Clear out the BSS */
+	LOADADDR(r11,__bss_stop)
+
+	LOADADDR(r8,__bss_start)
 
+	sub	r11,r11,r8        /* bss size                        */
+	addi	r11,r11,7         /* round up to an even double word */
+	rldicl. r11,r11,61,3      /* shift right by 3                */
+	beq	4f
+	addi	r8,r8,-8
+	li	r0,0
+	mtctr	r11		  /* zero this many doublewords      */
+3:	stdu	r0,8(r8)
+	bdnz	3b
+4:
 	LOADADDR(r1,init_thread_union)
 	addi	r1,r1,THREAD_SIZE
 	li	r0,0
@@ -1277,6 +1291,8 @@ _GLOBAL(__start_initialization_iSeries)
 
 	bl      .iSeries_fixup_klimit
 
+	/* relocation is on at this point */
+
 	b	.start_here_common
 #endif
 
@@ -1300,20 +1316,6 @@ _GLOBAL(__start_initialization_pSeries)
 	/* Relocate the TOC from a virt addr to a real addr */
 	sub	r2,r2,r3
 
-	/* setup the systemcfg pointer which is needed by prom_init       */
-	LOADADDR(r9,systemcfg)
-	sub	r9,r9,r3                /* addr of the variable systemcfg */
-	SET_REG_TO_CONST(r4, SYSTEMCFG_VIRT_ADDR)
-	sub	r4,r4,r3
-	std	r4,0(r9)		/* set the value of systemcfg     */
-
-	/* setup the naca pointer which is needed by prom_init            */
-	LOADADDR(r9,naca)
-	sub	r9,r9,r3                /* addr of the variable naca      */
-	SET_REG_TO_CONST(r4, NACA_VIRT_ADDR)
-	sub	r4,r4,r3
-	std	r4,0(r9)		/* set the value of naca          */
-
 	/* DRENG / PPPBBB Fix the following comment!!! -Peter */
 	/* The following copies the first 0x100 bytes of code from the    */
 	/* load addr to physical addr 0x0.  This code causes secondary    */
@@ -1917,24 +1919,7 @@ _STATIC(start_here_pSeries)
 
 	/* This is where all platforms converge execution */
 _STATIC(start_here_common)
-	/* relocation is on at this point */
-
-	/* Clear out the BSS */
-	LOADADDR(r11,_end)
-
-	LOADADDR(r8,__bss_start)
-
-	sub	r11,r11,r8        /* bss size                        */
-	addi	r11,r11,7         /* round up to an even double word */
-	rldicl. r11,r11,61,3      /* shift right by 3                */
-	beq	4f
-	addi	r8,r8,-8
-	li	r0,0
-	mtctr	r11		  /* zero this many doublewords      */
-3:	stdu	r0,8(r8)
-	bdnz	3b
-4:
-
+	
 	/* The following code sets up the SP and TOC now that we are */
 	/* running with translation enabled. */
 
diff -puN arch/ppc64/kernel/prom.c~ppc64-bss_clear arch/ppc64/kernel/prom.c
--- 25/arch/ppc64/kernel/prom.c~ppc64-bss_clear	2004-01-13 23:23:17.000000000 -0800
+++ 25-akpm/arch/ppc64/kernel/prom.c	2004-01-13 23:23:17.000000000 -0800
@@ -48,6 +48,7 @@
 #include <asm/pci_dma.h>
 #include <asm/bootinfo.h>
 #include <asm/ppcdebug.h>
+#include <asm/sections.h>
 #include "open_pic.h"
 
 #ifdef CONFIG_LOGO_LINUX_CLUT224
@@ -1224,12 +1225,20 @@ prom_init(unsigned long r3, unsigned lon
 	unsigned long offset = reloc_offset();
 	long l;
 	char *p, *d;
- 	unsigned long phys;
-        u32 getprop_rval;
-        struct systemcfg *_systemcfg = RELOC(systemcfg);
+	unsigned long phys;
+	u32 getprop_rval;
+	struct systemcfg *_systemcfg;
 	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
 
+	/* First zero the BSS -- use memset, some arches don't have
+	 * caches on yet */
+	memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
+
+	/* Setup systemcfg and NACA pointers now */
+	RELOC(systemcfg) = _systemcfg = (struct systemcfg *)(SYSTEMCFG_VIRT_ADDR - offset);
+	RELOC(naca) = (struct naca_struct *)(NACA_VIRT_ADDR - offset);
+
 	/* Default machine type. */
 	_systemcfg->platform = PLATFORM_PSERIES;
 

_
