[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 #include -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 #include #include +#include #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; _