* [PATCH] powerpc: Do a bit more cpu init cleanups
@ 2006-06-27 19:22 Olof Johansson
2006-06-27 22:20 ` Benjamin Herrenschmidt
2006-06-28 4:38 ` [PATCH] powerpc: Do a bit more cpu init cleanups (v2) Olof Johansson
0 siblings, 2 replies; 7+ messages in thread
From: Olof Johansson @ 2006-06-27 19:22 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Cleanup CPU inits a bit more, Geoff Levand already did some earlier.
* Rename cpu_setup_power4.S to cpu_setup_ppc970.S
* Move CPU state save to cpu_setup, since cpu_setup is only ever done
on cpu 0 on 64-bit.
* Rename __restore_cpu_setup to __restore_cpu_setup_ppc970 since it's
only actually doing anything there, and check before calling instead
of in the function (no check needed on powermac).
* Same for __970_cpu_preinit
* Rename pSeries_secondary_smp_init to generic_secondary_smp_init since
everyone but powermac and iSeries use it.
Build tested with all 64-bit defconfigs, boot tested on power5 and
powermac.
Signed-off-by: Olof Johansson <olof@lixom•net>
Index: linux-2.6/arch/powerpc/kernel/Makefile
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/Makefile
+++ linux-2.6/arch/powerpc/kernel/Makefile
@@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrac
obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
signal_64.o ptrace32.o \
- paca.o cpu_setup_power4.o \
+ paca.o cpu_setup_ppc970.o \
firmware.o sysfs.o
obj-$(CONFIG_PPC64) += vdso64/
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
Index: linux-2.6/arch/powerpc/kernel/cpu_setup_power4.S
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/cpu_setup_power4.S
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * This file contains low level CPU setup functions.
- * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/config.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/cache.h>
-
-_GLOBAL(__970_cpu_preinit)
- /*
- * Do nothing if not running in HV mode
- */
- mfmsr r0
- rldicl. r0,r0,4,63
- beqlr
-
- /*
- * Deal only with PPC970 and PPC970FX.
- */
- mfspr r0,SPRN_PVR
- srwi r0,r0,16
- cmpwi r0,0x39
- beq 1f
- cmpwi r0,0x3c
- beq 1f
- cmpwi r0,0x44
- bnelr
-1:
-
- /* Make sure HID4:rm_ci is off before MMU is turned off, that large
- * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
- * HID5:DCBZ32_ill
- */
- li r0,0
- mfspr r3,SPRN_HID4
- rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
- rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */
- sync
- mtspr SPRN_HID4,r3
- isync
- sync
- mfspr r3,SPRN_HID5
- rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */
- sync
- mtspr SPRN_HID5,r3
- isync
- sync
-
- /* Setup some basic HID1 features */
- mfspr r0,SPRN_HID1
- li r3,0x1200 /* enable i-fetch cacheability */
- sldi r3,r3,44 /* and prefetch */
- or r0,r0,r3
- mtspr SPRN_HID1,r0
- mtspr SPRN_HID1,r0
- isync
-
- /* Clear HIOR */
- li r0,0
- sync
- mtspr SPRN_HIOR,0 /* Clear interrupt prefix */
- isync
- blr
-
-_GLOBAL(__setup_cpu_ppc970)
- mfspr r0,SPRN_HID0
- li r11,5 /* clear DOZE and SLEEP */
- rldimi r0,r11,52,8 /* set NAP and DPM */
- mtspr SPRN_HID0,r0
- mfspr r0,SPRN_HID0
- mfspr r0,SPRN_HID0
- mfspr r0,SPRN_HID0
- mfspr r0,SPRN_HID0
- mfspr r0,SPRN_HID0
- mfspr r0,SPRN_HID0
- sync
- isync
- blr
-
-/* Definitions for the table use to save CPU states */
-#define CS_HID0 0
-#define CS_HID1 8
-#define CS_HID4 16
-#define CS_HID5 24
-#define CS_SIZE 32
-
- .data
- .balign L1_CACHE_BYTES,0
-cpu_state_storage:
- .space CS_SIZE
- .balign L1_CACHE_BYTES,0
- .text
-
-/* Called in normal context to backup CPU 0 state. This
- * does not include cache settings. This function is also
- * called for machine sleep. This does not include the MMU
- * setup, BATs, etc... but rather the "special" registers
- * like HID0, HID1, HID4, etc...
- */
-_GLOBAL(__save_cpu_setup)
- /* Some CR fields are volatile, we back it up all */
- mfcr r7
-
- /* Get storage ptr */
- LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
-
- /* We only deal with 970 for now */
- mfspr r0,SPRN_PVR
- srwi r0,r0,16
- cmpwi r0,0x39
- beq 1f
- cmpwi r0,0x3c
- beq 1f
- cmpwi r0,0x44
- bne 2f
-
-1: /* Save HID0,1,4 and 5 */
- mfspr r3,SPRN_HID0
- std r3,CS_HID0(r5)
- mfspr r3,SPRN_HID1
- std r3,CS_HID1(r5)
- mfspr r3,SPRN_HID4
- std r3,CS_HID4(r5)
- mfspr r3,SPRN_HID5
- std r3,CS_HID5(r5)
-
-2:
- mtcr r7
- blr
-
-/* Called with no MMU context (typically MSR:IR/DR off) to
- * restore CPU state as backed up by the previous
- * function. This does not include cache setting
- */
-_GLOBAL(__restore_cpu_setup)
- /* Get storage ptr (FIXME when using anton reloc as we
- * are running with translation disabled here
- */
- LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
-
- /* We only deal with 970 for now */
- mfspr r0,SPRN_PVR
- srwi r0,r0,16
- cmpwi r0,0x39
- beq 1f
- cmpwi r0,0x3c
- beq 1f
- cmpwi r0,0x44
- bnelr
-
-1: /* Before accessing memory, we make sure rm_ci is clear */
- li r0,0
- mfspr r3,SPRN_HID4
- rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
- sync
- mtspr SPRN_HID4,r3
- isync
- sync
-
- /* Clear interrupt prefix */
- li r0,0
- sync
- mtspr SPRN_HIOR,0
- isync
-
- /* Restore HID0 */
- ld r3,CS_HID0(r5)
- sync
- isync
- mtspr SPRN_HID0,r3
- mfspr r3,SPRN_HID0
- mfspr r3,SPRN_HID0
- mfspr r3,SPRN_HID0
- mfspr r3,SPRN_HID0
- mfspr r3,SPRN_HID0
- mfspr r3,SPRN_HID0
- sync
- isync
-
- /* Restore HID1 */
- ld r3,CS_HID1(r5)
- sync
- isync
- mtspr SPRN_HID1,r3
- mtspr SPRN_HID1,r3
- sync
- isync
-
- /* Restore HID4 */
- ld r3,CS_HID4(r5)
- sync
- isync
- mtspr SPRN_HID4,r3
- sync
- isync
-
- /* Restore HID5 */
- ld r3,CS_HID5(r5)
- sync
- isync
- mtspr SPRN_HID5,r3
- sync
- isync
- blr
-
Index: linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S
===================================================================
--- /dev/null
+++ linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S
@@ -0,0 +1,175 @@
+/*
+ * This file contains low level CPU setup functions.
+ * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+
+_GLOBAL(__cpu_preinit_ppc970)
+ /* Do nothing if not running in HV mode */
+ mfmsr r0
+ rldicl. r0,r0,4,63
+ beqlr
+
+ /* Make sure HID4:rm_ci is off before MMU is turned off, that large
+ * pages are enabled with HID4:61 and clear HID5:DCBZ_size and
+ * HID5:DCBZ32_ill
+ */
+ li r0,0
+ mfspr r3,SPRN_HID4
+ rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
+ rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */
+ sync
+ mtspr SPRN_HID4,r3
+ isync
+ sync
+ mfspr r3,SPRN_HID5
+ rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */
+ sync
+ mtspr SPRN_HID5,r3
+ isync
+ sync
+
+ /* Setup some basic HID1 features */
+ mfspr r0,SPRN_HID1
+ li r3,0x1200 /* enable i-fetch cacheability */
+ sldi r3,r3,44 /* and prefetch */
+ or r0,r0,r3
+ mtspr SPRN_HID1,r0
+ mtspr SPRN_HID1,r0
+ isync
+
+ /* Clear HIOR */
+ li r0,0
+ sync
+ mtspr SPRN_HIOR,0 /* Clear interrupt prefix */
+ isync
+ blr
+
+/* Definitions for the table use to save CPU states */
+#define CS_HID0 0
+#define CS_HID1 8
+#define CS_HID4 16
+#define CS_HID5 24
+#define CS_SIZE 32
+
+ .data
+ .balign L1_CACHE_BYTES,0
+cpu_state_storage:
+ .space CS_SIZE
+ .balign L1_CACHE_BYTES,0
+ .text
+
+
+_GLOBAL(__setup_cpu_ppc970)
+ /* Do nothing if not running in HV mode */
+ mfmsr r0
+ rldicl. r0,r0,4,63
+ beqlr
+
+ mfspr r0,SPRN_HID0
+ li r11,5 /* clear DOZE and SLEEP */
+ rldimi r0,r11,52,8 /* set NAP and DPM */
+ mtspr SPRN_HID0,r0
+ mfspr r0,SPRN_HID0
+ mfspr r0,SPRN_HID0
+ mfspr r0,SPRN_HID0
+ mfspr r0,SPRN_HID0
+ mfspr r0,SPRN_HID0
+ mfspr r0,SPRN_HID0
+ sync
+ isync
+
+ /* Save away cpu state */
+ LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
+
+ /* Save HID0,1,4 and 5 */
+ mfspr r3,SPRN_HID0
+ std r3,CS_HID0(r5)
+ mfspr r3,SPRN_HID1
+ std r3,CS_HID1(r5)
+ mfspr r3,SPRN_HID4
+ std r3,CS_HID4(r5)
+ mfspr r3,SPRN_HID5
+ std r3,CS_HID5(r5)
+
+ blr
+
+/* Called with no MMU context (typically MSR:IR/DR off) to
+ * restore CPU state as backed up by the previous
+ * function. This does not include cache setting
+ */
+_GLOBAL(__restore_cpu_setup_ppc970)
+ /* Do nothing if not running in HV mode */
+ mfmsr r0
+ rldicl. r0,r0,4,63
+ beqlr
+
+ LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
+ /* Before accessing memory, we make sure rm_ci is clear */
+ li r0,0
+ mfspr r3,SPRN_HID4
+ rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
+ sync
+ mtspr SPRN_HID4,r3
+ isync
+ sync
+
+ /* Clear interrupt prefix */
+ li r0,0
+ sync
+ mtspr SPRN_HIOR,0
+ isync
+
+ /* Restore HID0 */
+ ld r3,CS_HID0(r5)
+ sync
+ isync
+ mtspr SPRN_HID0,r3
+ mfspr r3,SPRN_HID0
+ mfspr r3,SPRN_HID0
+ mfspr r3,SPRN_HID0
+ mfspr r3,SPRN_HID0
+ mfspr r3,SPRN_HID0
+ mfspr r3,SPRN_HID0
+ sync
+ isync
+
+ /* Restore HID1 */
+ ld r3,CS_HID1(r5)
+ sync
+ isync
+ mtspr SPRN_HID1,r3
+ mtspr SPRN_HID1,r3
+ sync
+ isync
+
+ /* Restore HID4 */
+ ld r3,CS_HID4(r5)
+ sync
+ isync
+ mtspr SPRN_HID4,r3
+ sync
+ isync
+
+ /* Restore HID5 */
+ ld r3,CS_HID5(r5)
+ sync
+ isync
+ mtspr SPRN_HID5,r3
+ sync
+ isync
+ blr
+
Index: linux-2.6/arch/powerpc/kernel/head_64.S
===================================================================
--- linux-2.6.orig/arch/powerpc/kernel/head_64.S
+++ linux-2.6/arch/powerpc/kernel/head_64.S
@@ -152,7 +152,7 @@ _GLOBAL(__secondary_hold)
bne 100b
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
- LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init)
+ LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init)
mtctr r4
mr r3,r24
bctr
@@ -1473,18 +1473,28 @@ fwnmi_data_area:
. = 0x8000
/*
- * On pSeries, secondary processors spin in the following code.
+ * On pSeries and most other platforms, secondary processors spin
+ * in the following code.
* At entry, r3 = this processor's number (physical cpu id)
*/
-_GLOBAL(pSeries_secondary_smp_init)
+_GLOBAL(generic_secondary_smp_init)
mr r24,r3
/* turn on 64-bit mode */
bl .enable_64b_mode
isync
- /* Copy some CPU settings from CPU 0 */
- bl .__restore_cpu_setup
+ /* Copy some CPU settings from CPU 0, only needed on PPC970{,FX,MP} */
+ mfspr r0,SPRN_PVR
+ srwi r0,r0,16
+ cmpwi r0,0x39 /* 970 */
+ beq 1f
+ cmpwi r0,0x3c /* 970FX */
+ beq 1f
+ cmpwi r0,0x44 /* 970MP */
+ bne 2f
+1: bl .__restore_cpu_setup_ppc970
+2:
/* Set up a paca value for this processor. Since we have the
* physical cpu id in r24, we need to search the pacas to find
@@ -1600,7 +1610,16 @@ _GLOBAL(__start_initialization_multiplat
bl .enable_64b_mode
/* Setup some critical 970 SPRs before switching MMU off */
- bl .__970_cpu_preinit
+ mfspr r0,SPRN_PVR
+ srwi r0,r0,16
+ cmpwi r0,0x39 /* 970 */
+ beq 1f
+ cmpwi r0,0x3c /* 970FX */
+ beq 1f
+ cmpwi r0,0x44 /* 970MP */
+ bne 2f
+1: bl .__cpu_preinit_ppc970
+2:
/* cpu # */
li r24,0
@@ -1771,7 +1790,7 @@ _GLOBAL(pmac_secondary_start)
isync
/* Copy some CPU settings from CPU 0 */
- bl .__restore_cpu_setup
+ bl .__restore_cpu_setup_ppc970
/* pSeries do that early though I don't think we really need it */
mfmsr r3
@@ -1921,12 +1940,6 @@ _STATIC(start_here_multiplatform)
mr r5,r26
bl .identify_cpu
- /* Save some low level config HIDs of CPU0 to be copied to
- * other CPUs later on, or used for suspend/resume
- */
- bl .__save_cpu_setup
- sync
-
/* Do very early kernel initializations, including initial hash table,
* stab and slb setup before we turn on relocation. */
Index: linux-2.6/arch/powerpc/platforms/cell/smp.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/cell/smp.c
+++ linux-2.6/arch/powerpc/platforms/cell/smp.c
@@ -58,7 +58,7 @@
*/
static cpumask_t of_spin_map;
-extern void pSeries_secondary_smp_init(unsigned long);
+extern void generic_secondary_smp_init(unsigned long);
/**
* smp_startup_cpu() - start the given cpu
@@ -75,7 +75,7 @@ static inline int __devinit smp_startup_
{
int status;
unsigned long start_here = __pa((u32)*((unsigned long *)
- pSeries_secondary_smp_init));
+ generic_secondary_smp_init));
unsigned int pcpu;
int start_cpu;
Index: linux-2.6/arch/powerpc/platforms/pseries/smp.c
===================================================================
--- linux-2.6.orig/arch/powerpc/platforms/pseries/smp.c
+++ linux-2.6/arch/powerpc/platforms/pseries/smp.c
@@ -63,7 +63,7 @@
*/
static cpumask_t of_spin_map;
-extern void pSeries_secondary_smp_init(unsigned long);
+extern void generic_secondary_smp_init(unsigned long);
#ifdef CONFIG_HOTPLUG_CPU
@@ -271,7 +271,7 @@ static inline int __devinit smp_startup_
{
int status;
unsigned long start_here = __pa((u32)*((unsigned long *)
- pSeries_secondary_smp_init));
+ generic_secondary_smp_init));
unsigned int pcpu;
int start_cpu;
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] powerpc: Do a bit more cpu init cleanups 2006-06-27 19:22 [PATCH] powerpc: Do a bit more cpu init cleanups Olof Johansson @ 2006-06-27 22:20 ` Benjamin Herrenschmidt 2006-06-27 22:54 ` Olof Johansson 2006-06-28 4:38 ` [PATCH] powerpc: Do a bit more cpu init cleanups (v2) Olof Johansson 1 sibling, 1 reply; 7+ messages in thread From: Benjamin Herrenschmidt @ 2006-06-27 22:20 UTC (permalink / raw) To: Olof Johansson; +Cc: linuxppc-dev, paulus On Tue, 2006-06-27 at 12:22 -0700, Olof Johansson wrote: > Cleanup CPU inits a bit more, Geoff Levand already did some earlier. > > * Rename cpu_setup_power4.S to cpu_setup_ppc970.S > * Move CPU state save to cpu_setup, since cpu_setup is only ever done > on cpu 0 on 64-bit. Nah, keep that one separate, will be needed as soon as we start doing some sleep/wake stuff for ppc64 > * Rename __restore_cpu_setup to __restore_cpu_setup_ppc970 since it's > only actually doing anything there, and check before calling instead > of in the function (no check needed on powermac). I'd like to keep a generic save/restore.. that or we put then in cputable. > * Same for __970_cpu_preinit > * Rename pSeries_secondary_smp_init to generic_secondary_smp_init since > everyone but powermac and iSeries use it. Ok. > Build tested with all 64-bit defconfigs, boot tested on power5 and > powermac. > > Signed-off-by: Olof Johansson <olof@lixom•net> > > > Index: linux-2.6/arch/powerpc/kernel/Makefile > =================================================================== > --- linux-2.6.orig/arch/powerpc/kernel/Makefile > +++ linux-2.6/arch/powerpc/kernel/Makefile > @@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrac > obj-y += vdso32/ > obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ > signal_64.o ptrace32.o \ > - paca.o cpu_setup_power4.o \ > + paca.o cpu_setup_ppc970.o \ > firmware.o sysfs.o > obj-$(CONFIG_PPC64) += vdso64/ > obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o > Index: linux-2.6/arch/powerpc/kernel/cpu_setup_power4.S > =================================================================== > --- linux-2.6.orig/arch/powerpc/kernel/cpu_setup_power4.S > +++ /dev/null > @@ -1,216 +0,0 @@ > -/* > - * This file contains low level CPU setup functions. > - * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org) > - * > - * This program is free software; you can redistribute it and/or > - * modify it under the terms of the GNU General Public License > - * as published by the Free Software Foundation; either version > - * 2 of the License, or (at your option) any later version. > - * > - */ > - > -#include <linux/config.h> > -#include <asm/processor.h> > -#include <asm/page.h> > -#include <asm/cputable.h> > -#include <asm/ppc_asm.h> > -#include <asm/asm-offsets.h> > -#include <asm/cache.h> > - > -_GLOBAL(__970_cpu_preinit) > - /* > - * Do nothing if not running in HV mode > - */ > - mfmsr r0 > - rldicl. r0,r0,4,63 > - beqlr > - > - /* > - * Deal only with PPC970 and PPC970FX. > - */ > - mfspr r0,SPRN_PVR > - srwi r0,r0,16 > - cmpwi r0,0x39 > - beq 1f > - cmpwi r0,0x3c > - beq 1f > - cmpwi r0,0x44 > - bnelr > -1: > - > - /* Make sure HID4:rm_ci is off before MMU is turned off, that large > - * pages are enabled with HID4:61 and clear HID5:DCBZ_size and > - * HID5:DCBZ32_ill > - */ > - li r0,0 > - mfspr r3,SPRN_HID4 > - rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ > - rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ > - sync > - mtspr SPRN_HID4,r3 > - isync > - sync > - mfspr r3,SPRN_HID5 > - rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ > - sync > - mtspr SPRN_HID5,r3 > - isync > - sync > - > - /* Setup some basic HID1 features */ > - mfspr r0,SPRN_HID1 > - li r3,0x1200 /* enable i-fetch cacheability */ > - sldi r3,r3,44 /* and prefetch */ > - or r0,r0,r3 > - mtspr SPRN_HID1,r0 > - mtspr SPRN_HID1,r0 > - isync > - > - /* Clear HIOR */ > - li r0,0 > - sync > - mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ > - isync > - blr > - > -_GLOBAL(__setup_cpu_ppc970) > - mfspr r0,SPRN_HID0 > - li r11,5 /* clear DOZE and SLEEP */ > - rldimi r0,r11,52,8 /* set NAP and DPM */ > - mtspr SPRN_HID0,r0 > - mfspr r0,SPRN_HID0 > - mfspr r0,SPRN_HID0 > - mfspr r0,SPRN_HID0 > - mfspr r0,SPRN_HID0 > - mfspr r0,SPRN_HID0 > - mfspr r0,SPRN_HID0 > - sync > - isync > - blr > - > -/* Definitions for the table use to save CPU states */ > -#define CS_HID0 0 > -#define CS_HID1 8 > -#define CS_HID4 16 > -#define CS_HID5 24 > -#define CS_SIZE 32 > - > - .data > - .balign L1_CACHE_BYTES,0 > -cpu_state_storage: > - .space CS_SIZE > - .balign L1_CACHE_BYTES,0 > - .text > - > -/* Called in normal context to backup CPU 0 state. This > - * does not include cache settings. This function is also > - * called for machine sleep. This does not include the MMU > - * setup, BATs, etc... but rather the "special" registers > - * like HID0, HID1, HID4, etc... > - */ > -_GLOBAL(__save_cpu_setup) > - /* Some CR fields are volatile, we back it up all */ > - mfcr r7 > - > - /* Get storage ptr */ > - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) > - > - /* We only deal with 970 for now */ > - mfspr r0,SPRN_PVR > - srwi r0,r0,16 > - cmpwi r0,0x39 > - beq 1f > - cmpwi r0,0x3c > - beq 1f > - cmpwi r0,0x44 > - bne 2f > - > -1: /* Save HID0,1,4 and 5 */ > - mfspr r3,SPRN_HID0 > - std r3,CS_HID0(r5) > - mfspr r3,SPRN_HID1 > - std r3,CS_HID1(r5) > - mfspr r3,SPRN_HID4 > - std r3,CS_HID4(r5) > - mfspr r3,SPRN_HID5 > - std r3,CS_HID5(r5) > - > -2: > - mtcr r7 > - blr > - > -/* Called with no MMU context (typically MSR:IR/DR off) to > - * restore CPU state as backed up by the previous > - * function. This does not include cache setting > - */ > -_GLOBAL(__restore_cpu_setup) > - /* Get storage ptr (FIXME when using anton reloc as we > - * are running with translation disabled here > - */ > - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) > - > - /* We only deal with 970 for now */ > - mfspr r0,SPRN_PVR > - srwi r0,r0,16 > - cmpwi r0,0x39 > - beq 1f > - cmpwi r0,0x3c > - beq 1f > - cmpwi r0,0x44 > - bnelr > - > -1: /* Before accessing memory, we make sure rm_ci is clear */ > - li r0,0 > - mfspr r3,SPRN_HID4 > - rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ > - sync > - mtspr SPRN_HID4,r3 > - isync > - sync > - > - /* Clear interrupt prefix */ > - li r0,0 > - sync > - mtspr SPRN_HIOR,0 > - isync > - > - /* Restore HID0 */ > - ld r3,CS_HID0(r5) > - sync > - isync > - mtspr SPRN_HID0,r3 > - mfspr r3,SPRN_HID0 > - mfspr r3,SPRN_HID0 > - mfspr r3,SPRN_HID0 > - mfspr r3,SPRN_HID0 > - mfspr r3,SPRN_HID0 > - mfspr r3,SPRN_HID0 > - sync > - isync > - > - /* Restore HID1 */ > - ld r3,CS_HID1(r5) > - sync > - isync > - mtspr SPRN_HID1,r3 > - mtspr SPRN_HID1,r3 > - sync > - isync > - > - /* Restore HID4 */ > - ld r3,CS_HID4(r5) > - sync > - isync > - mtspr SPRN_HID4,r3 > - sync > - isync > - > - /* Restore HID5 */ > - ld r3,CS_HID5(r5) > - sync > - isync > - mtspr SPRN_HID5,r3 > - sync > - isync > - blr > - > Index: linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S > =================================================================== > --- /dev/null > +++ linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S > @@ -0,0 +1,175 @@ > +/* > + * This file contains low level CPU setup functions. > + * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org) > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + * > + */ > + > +#include <linux/config.h> > +#include <asm/processor.h> > +#include <asm/page.h> > +#include <asm/cputable.h> > +#include <asm/ppc_asm.h> > +#include <asm/asm-offsets.h> > +#include <asm/cache.h> > + > +_GLOBAL(__cpu_preinit_ppc970) > + /* Do nothing if not running in HV mode */ > + mfmsr r0 > + rldicl. r0,r0,4,63 > + beqlr > + > + /* Make sure HID4:rm_ci is off before MMU is turned off, that large > + * pages are enabled with HID4:61 and clear HID5:DCBZ_size and > + * HID5:DCBZ32_ill > + */ > + li r0,0 > + mfspr r3,SPRN_HID4 > + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ > + rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ > + sync > + mtspr SPRN_HID4,r3 > + isync > + sync > + mfspr r3,SPRN_HID5 > + rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ > + sync > + mtspr SPRN_HID5,r3 > + isync > + sync > + > + /* Setup some basic HID1 features */ > + mfspr r0,SPRN_HID1 > + li r3,0x1200 /* enable i-fetch cacheability */ > + sldi r3,r3,44 /* and prefetch */ > + or r0,r0,r3 > + mtspr SPRN_HID1,r0 > + mtspr SPRN_HID1,r0 > + isync > + > + /* Clear HIOR */ > + li r0,0 > + sync > + mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ > + isync > + blr > + > +/* Definitions for the table use to save CPU states */ > +#define CS_HID0 0 > +#define CS_HID1 8 > +#define CS_HID4 16 > +#define CS_HID5 24 > +#define CS_SIZE 32 > + > + .data > + .balign L1_CACHE_BYTES,0 > +cpu_state_storage: > + .space CS_SIZE > + .balign L1_CACHE_BYTES,0 > + .text > + > + > +_GLOBAL(__setup_cpu_ppc970) > + /* Do nothing if not running in HV mode */ > + mfmsr r0 > + rldicl. r0,r0,4,63 > + beqlr > + > + mfspr r0,SPRN_HID0 > + li r11,5 /* clear DOZE and SLEEP */ > + rldimi r0,r11,52,8 /* set NAP and DPM */ > + mtspr SPRN_HID0,r0 > + mfspr r0,SPRN_HID0 > + mfspr r0,SPRN_HID0 > + mfspr r0,SPRN_HID0 > + mfspr r0,SPRN_HID0 > + mfspr r0,SPRN_HID0 > + mfspr r0,SPRN_HID0 > + sync > + isync > + > + /* Save away cpu state */ > + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) > + > + /* Save HID0,1,4 and 5 */ > + mfspr r3,SPRN_HID0 > + std r3,CS_HID0(r5) > + mfspr r3,SPRN_HID1 > + std r3,CS_HID1(r5) > + mfspr r3,SPRN_HID4 > + std r3,CS_HID4(r5) > + mfspr r3,SPRN_HID5 > + std r3,CS_HID5(r5) > + > + blr > + > +/* Called with no MMU context (typically MSR:IR/DR off) to > + * restore CPU state as backed up by the previous > + * function. This does not include cache setting > + */ > +_GLOBAL(__restore_cpu_setup_ppc970) > + /* Do nothing if not running in HV mode */ > + mfmsr r0 > + rldicl. r0,r0,4,63 > + beqlr > + > + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) > + /* Before accessing memory, we make sure rm_ci is clear */ > + li r0,0 > + mfspr r3,SPRN_HID4 > + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ > + sync > + mtspr SPRN_HID4,r3 > + isync > + sync > + > + /* Clear interrupt prefix */ > + li r0,0 > + sync > + mtspr SPRN_HIOR,0 > + isync > + > + /* Restore HID0 */ > + ld r3,CS_HID0(r5) > + sync > + isync > + mtspr SPRN_HID0,r3 > + mfspr r3,SPRN_HID0 > + mfspr r3,SPRN_HID0 > + mfspr r3,SPRN_HID0 > + mfspr r3,SPRN_HID0 > + mfspr r3,SPRN_HID0 > + mfspr r3,SPRN_HID0 > + sync > + isync > + > + /* Restore HID1 */ > + ld r3,CS_HID1(r5) > + sync > + isync > + mtspr SPRN_HID1,r3 > + mtspr SPRN_HID1,r3 > + sync > + isync > + > + /* Restore HID4 */ > + ld r3,CS_HID4(r5) > + sync > + isync > + mtspr SPRN_HID4,r3 > + sync > + isync > + > + /* Restore HID5 */ > + ld r3,CS_HID5(r5) > + sync > + isync > + mtspr SPRN_HID5,r3 > + sync > + isync > + blr > + > Index: linux-2.6/arch/powerpc/kernel/head_64.S > =================================================================== > --- linux-2.6.orig/arch/powerpc/kernel/head_64.S > +++ linux-2.6/arch/powerpc/kernel/head_64.S > @@ -152,7 +152,7 @@ _GLOBAL(__secondary_hold) > bne 100b > > #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) > - LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) > + LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init) > mtctr r4 > mr r3,r24 > bctr > @@ -1473,18 +1473,28 @@ fwnmi_data_area: > . = 0x8000 > > /* > - * On pSeries, secondary processors spin in the following code. > + * On pSeries and most other platforms, secondary processors spin > + * in the following code. > * At entry, r3 = this processor's number (physical cpu id) > */ > -_GLOBAL(pSeries_secondary_smp_init) > +_GLOBAL(generic_secondary_smp_init) > mr r24,r3 > > /* turn on 64-bit mode */ > bl .enable_64b_mode > isync > > - /* Copy some CPU settings from CPU 0 */ > - bl .__restore_cpu_setup > + /* Copy some CPU settings from CPU 0, only needed on PPC970{,FX,MP} */ > + mfspr r0,SPRN_PVR > + srwi r0,r0,16 > + cmpwi r0,0x39 /* 970 */ > + beq 1f > + cmpwi r0,0x3c /* 970FX */ > + beq 1f > + cmpwi r0,0x44 /* 970MP */ > + bne 2f > +1: bl .__restore_cpu_setup_ppc970 > +2: > > /* Set up a paca value for this processor. Since we have the > * physical cpu id in r24, we need to search the pacas to find > @@ -1600,7 +1610,16 @@ _GLOBAL(__start_initialization_multiplat > bl .enable_64b_mode > > /* Setup some critical 970 SPRs before switching MMU off */ > - bl .__970_cpu_preinit > + mfspr r0,SPRN_PVR > + srwi r0,r0,16 > + cmpwi r0,0x39 /* 970 */ > + beq 1f > + cmpwi r0,0x3c /* 970FX */ > + beq 1f > + cmpwi r0,0x44 /* 970MP */ > + bne 2f > +1: bl .__cpu_preinit_ppc970 > +2: > > /* cpu # */ > li r24,0 > @@ -1771,7 +1790,7 @@ _GLOBAL(pmac_secondary_start) > isync > > /* Copy some CPU settings from CPU 0 */ > - bl .__restore_cpu_setup > + bl .__restore_cpu_setup_ppc970 > > /* pSeries do that early though I don't think we really need it */ > mfmsr r3 > @@ -1921,12 +1940,6 @@ _STATIC(start_here_multiplatform) > mr r5,r26 > bl .identify_cpu > > - /* Save some low level config HIDs of CPU0 to be copied to > - * other CPUs later on, or used for suspend/resume > - */ > - bl .__save_cpu_setup > - sync > - > /* Do very early kernel initializations, including initial hash table, > * stab and slb setup before we turn on relocation. */ > > Index: linux-2.6/arch/powerpc/platforms/cell/smp.c > =================================================================== > --- linux-2.6.orig/arch/powerpc/platforms/cell/smp.c > +++ linux-2.6/arch/powerpc/platforms/cell/smp.c > @@ -58,7 +58,7 @@ > */ > static cpumask_t of_spin_map; > > -extern void pSeries_secondary_smp_init(unsigned long); > +extern void generic_secondary_smp_init(unsigned long); > > /** > * smp_startup_cpu() - start the given cpu > @@ -75,7 +75,7 @@ static inline int __devinit smp_startup_ > { > int status; > unsigned long start_here = __pa((u32)*((unsigned long *) > - pSeries_secondary_smp_init)); > + generic_secondary_smp_init)); > unsigned int pcpu; > int start_cpu; > > Index: linux-2.6/arch/powerpc/platforms/pseries/smp.c > =================================================================== > --- linux-2.6.orig/arch/powerpc/platforms/pseries/smp.c > +++ linux-2.6/arch/powerpc/platforms/pseries/smp.c > @@ -63,7 +63,7 @@ > */ > static cpumask_t of_spin_map; > > -extern void pSeries_secondary_smp_init(unsigned long); > +extern void generic_secondary_smp_init(unsigned long); > > #ifdef CONFIG_HOTPLUG_CPU > > @@ -271,7 +271,7 @@ static inline int __devinit smp_startup_ > { > int status; > unsigned long start_here = __pa((u32)*((unsigned long *) > - pSeries_secondary_smp_init)); > + generic_secondary_smp_init)); > unsigned int pcpu; > int start_cpu; > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] powerpc: Do a bit more cpu init cleanups 2006-06-27 22:20 ` Benjamin Herrenschmidt @ 2006-06-27 22:54 ` Olof Johansson 2006-06-27 23:07 ` Benjamin Herrenschmidt 0 siblings, 1 reply; 7+ messages in thread From: Olof Johansson @ 2006-06-27 22:54 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: Olof Johansson, linuxppc-dev, paulus On Wed, Jun 28, 2006 at 08:20:48AM +1000, Benjamin Herrenschmidt wrote: > On Tue, 2006-06-27 at 12:22 -0700, Olof Johansson wrote: > > Cleanup CPU inits a bit more, Geoff Levand already did some earlier. > > > > * Rename cpu_setup_power4.S to cpu_setup_ppc970.S > > > * Move CPU state save to cpu_setup, since cpu_setup is only ever done > > on cpu 0 on 64-bit. > > Nah, keep that one separate, will be needed as soon as we start doing > some sleep/wake stuff for ppc64 Why? I can see having to restore the settings on wake, but not doing a brand new cpu_setup. > > * Rename __restore_cpu_setup to __restore_cpu_setup_ppc970 since it's > > only actually doing anything there, and check before calling instead > > of in the function (no check needed on powermac). > > I'd like to keep a generic save/restore.. that or we put then in > cputable. Keep? There never was one. :) Since restore is called very first thing in smp secondary init, we don't have cputable available. > > * Same for __970_cpu_preinit > > * Rename pSeries_secondary_smp_init to generic_secondary_smp_init since > > everyone but powermac and iSeries use it. > > Ok. -Olof ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] powerpc: Do a bit more cpu init cleanups 2006-06-27 22:54 ` Olof Johansson @ 2006-06-27 23:07 ` Benjamin Herrenschmidt 2006-06-27 23:48 ` Olof Johansson 0 siblings, 1 reply; 7+ messages in thread From: Benjamin Herrenschmidt @ 2006-06-27 23:07 UTC (permalink / raw) To: Olof Johansson; +Cc: linuxppc-dev, paulus On Tue, 2006-06-27 at 15:54 -0700, Olof Johansson wrote: > On Wed, Jun 28, 2006 at 08:20:48AM +1000, Benjamin Herrenschmidt wrote: > > On Tue, 2006-06-27 at 12:22 -0700, Olof Johansson wrote: > > > Cleanup CPU inits a bit more, Geoff Levand already did some earlier. > > > > > > * Rename cpu_setup_power4.S to cpu_setup_ppc970.S > > > > > * Move CPU state save to cpu_setup, since cpu_setup is only ever done > > > on cpu 0 on 64-bit. > > > > Nah, keep that one separate, will be needed as soon as we start doing > > some sleep/wake stuff for ppc64 > > Why? I can see having to restore the settings on wake, but not doing a > brand new cpu_setup. No, a new save, not setup. > > > * Rename __restore_cpu_setup to __restore_cpu_setup_ppc970 since it's > > > only actually doing anything there, and check before calling instead > > > of in the function (no check needed on powermac). > > > > I'd like to keep a generic save/restore.. that or we put then in > > cputable. > > Keep? There never was one. :) There is one for 32 bits :) > Since restore is called very first thing in smp secondary init, we don't > have cputable available. We could easily Ben. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] powerpc: Do a bit more cpu init cleanups 2006-06-27 23:07 ` Benjamin Herrenschmidt @ 2006-06-27 23:48 ` Olof Johansson 0 siblings, 0 replies; 7+ messages in thread From: Olof Johansson @ 2006-06-27 23:48 UTC (permalink / raw) To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, paulus On Wed, Jun 28, 2006 at 09:07:41AM +1000, Benjamin Herrenschmidt wrote: > On Tue, 2006-06-27 at 15:54 -0700, Olof Johansson wrote: > > On Wed, Jun 28, 2006 at 08:20:48AM +1000, Benjamin Herrenschmidt wrote: > > > On Tue, 2006-06-27 at 12:22 -0700, Olof Johansson wrote: > > > > Cleanup CPU inits a bit more, Geoff Levand already did some earlier. > > > > > > > > * Rename cpu_setup_power4.S to cpu_setup_ppc970.S > > > > > > > * Move CPU state save to cpu_setup, since cpu_setup is only ever done > > > > on cpu 0 on 64-bit. > > > > > > Nah, keep that one separate, will be needed as soon as we start doing > > > some sleep/wake stuff for ppc64 > > > > Why? I can see having to restore the settings on wake, but not doing a > > brand new cpu_setup. > > No, a new save, not setup. I prefer to join them for now. I'm not convinced resaving is the best way to go for sleep/wake, HID defaults are saved during boot. If other bits have been flipped, chances are there's higher-level code that needs to be aware and do things on resume anyway, and they can just set the bit again there (i.e. platform suspend/resume handlers). So, I prefer to keep the change as-is until there's code that shows the neccessity of having it the other way. > > > > * Rename __restore_cpu_setup to __restore_cpu_setup_ppc970 since it's > > > > only actually doing anything there, and check before calling instead > > > > of in the function (no check needed on powermac). > > > > > > I'd like to keep a generic save/restore.. that or we put then in > > > cputable. > > > > Keep? There never was one. :) > > There is one for 32 bits :) I didn't change any 32-bit code, so it's still there! :) (see below) > > Since restore is called very first thing in smp secondary init, we don't > > have cputable available. > > We could easily Yeah, on second look it wouldn't be hard. I'll add it to the cputable and use those pointers. It'll get rid of one of the PVR checks too. -Olof ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] powerpc: Do a bit more cpu init cleanups (v2) 2006-06-27 19:22 [PATCH] powerpc: Do a bit more cpu init cleanups Olof Johansson 2006-06-27 22:20 ` Benjamin Herrenschmidt @ 2006-06-28 4:38 ` Olof Johansson 2006-06-28 9:30 ` [PATCH] powerpc: Do a bit more cpu init cleanups (v3) Olof Johansson 1 sibling, 1 reply; 7+ messages in thread From: Olof Johansson @ 2006-06-28 4:38 UTC (permalink / raw) To: paulus; +Cc: linuxppc-dev Cleanup CPU inits a bit more, Geoff Levand already did some earlier. * Rename cpu_setup_power4.S to cpu_setup_ppc970.S * Move CPU state save to cpu_setup, since cpu_setup is done on cpu 0 on 64-bit and save is never done more than once. * Rename __restore_cpu_setup to __restore_cpu_ppc970 and add function pointers to the cputable to use instead. Powermac always has 970 so no need to check there. * Rename __970_cpu_preinit to __cpu_preinit_ppc970 and check PVR before calling it instead of in it, it's too early to use cputable here. * Rename pSeries_secondary_smp_init to generic_secondary_smp_init since everyone but powermac and iSeries use it. Signed-off-by: Olof Johansson <olof@lixom•net> Index: linux-2.6/arch/powerpc/kernel/Makefile =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/Makefile +++ linux-2.6/arch/powerpc/kernel/Makefile @@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrac obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ - paca.o cpu_setup_power4.o \ + paca.o cpu_setup_ppc970.o \ firmware.o sysfs.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o Index: linux-2.6/arch/powerpc/kernel/cpu_setup_power4.S =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/cpu_setup_power4.S +++ /dev/null @@ -1,216 +0,0 @@ -/* - * This file contains low level CPU setup functions. - * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include <linux/config.h> -#include <asm/processor.h> -#include <asm/page.h> -#include <asm/cputable.h> -#include <asm/ppc_asm.h> -#include <asm/asm-offsets.h> -#include <asm/cache.h> - -_GLOBAL(__970_cpu_preinit) - /* - * Do nothing if not running in HV mode - */ - mfmsr r0 - rldicl. r0,r0,4,63 - beqlr - - /* - * Deal only with PPC970 and PPC970FX. - */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bnelr -1: - - /* Make sure HID4:rm_ci is off before MMU is turned off, that large - * pages are enabled with HID4:61 and clear HID5:DCBZ_size and - * HID5:DCBZ32_ill - */ - li r0,0 - mfspr r3,SPRN_HID4 - rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ - rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ - sync - mtspr SPRN_HID4,r3 - isync - sync - mfspr r3,SPRN_HID5 - rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ - sync - mtspr SPRN_HID5,r3 - isync - sync - - /* Setup some basic HID1 features */ - mfspr r0,SPRN_HID1 - li r3,0x1200 /* enable i-fetch cacheability */ - sldi r3,r3,44 /* and prefetch */ - or r0,r0,r3 - mtspr SPRN_HID1,r0 - mtspr SPRN_HID1,r0 - isync - - /* Clear HIOR */ - li r0,0 - sync - mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ - isync - blr - -_GLOBAL(__setup_cpu_ppc970) - mfspr r0,SPRN_HID0 - li r11,5 /* clear DOZE and SLEEP */ - rldimi r0,r11,52,8 /* set NAP and DPM */ - mtspr SPRN_HID0,r0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - sync - isync - blr - -/* Definitions for the table use to save CPU states */ -#define CS_HID0 0 -#define CS_HID1 8 -#define CS_HID4 16 -#define CS_HID5 24 -#define CS_SIZE 32 - - .data - .balign L1_CACHE_BYTES,0 -cpu_state_storage: - .space CS_SIZE - .balign L1_CACHE_BYTES,0 - .text - -/* Called in normal context to backup CPU 0 state. This - * does not include cache settings. This function is also - * called for machine sleep. This does not include the MMU - * setup, BATs, etc... but rather the "special" registers - * like HID0, HID1, HID4, etc... - */ -_GLOBAL(__save_cpu_setup) - /* Some CR fields are volatile, we back it up all */ - mfcr r7 - - /* Get storage ptr */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) - - /* We only deal with 970 for now */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bne 2f - -1: /* Save HID0,1,4 and 5 */ - mfspr r3,SPRN_HID0 - std r3,CS_HID0(r5) - mfspr r3,SPRN_HID1 - std r3,CS_HID1(r5) - mfspr r3,SPRN_HID4 - std r3,CS_HID4(r5) - mfspr r3,SPRN_HID5 - std r3,CS_HID5(r5) - -2: - mtcr r7 - blr - -/* Called with no MMU context (typically MSR:IR/DR off) to - * restore CPU state as backed up by the previous - * function. This does not include cache setting - */ -_GLOBAL(__restore_cpu_setup) - /* Get storage ptr (FIXME when using anton reloc as we - * are running with translation disabled here - */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) - - /* We only deal with 970 for now */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bnelr - -1: /* Before accessing memory, we make sure rm_ci is clear */ - li r0,0 - mfspr r3,SPRN_HID4 - rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ - sync - mtspr SPRN_HID4,r3 - isync - sync - - /* Clear interrupt prefix */ - li r0,0 - sync - mtspr SPRN_HIOR,0 - isync - - /* Restore HID0 */ - ld r3,CS_HID0(r5) - sync - isync - mtspr SPRN_HID0,r3 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - sync - isync - - /* Restore HID1 */ - ld r3,CS_HID1(r5) - sync - isync - mtspr SPRN_HID1,r3 - mtspr SPRN_HID1,r3 - sync - isync - - /* Restore HID4 */ - ld r3,CS_HID4(r5) - sync - isync - mtspr SPRN_HID4,r3 - sync - isync - - /* Restore HID5 */ - ld r3,CS_HID5(r5) - sync - isync - mtspr SPRN_HID5,r3 - sync - isync - blr - Index: linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S =================================================================== --- /dev/null +++ linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S @@ -0,0 +1,175 @@ +/* + * This file contains low level CPU setup functions. + * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/config.h> +#include <asm/processor.h> +#include <asm/page.h> +#include <asm/cputable.h> +#include <asm/ppc_asm.h> +#include <asm/asm-offsets.h> +#include <asm/cache.h> + +_GLOBAL(__cpu_preinit_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + /* Make sure HID4:rm_ci is off before MMU is turned off, that large + * pages are enabled with HID4:61 and clear HID5:DCBZ_size and + * HID5:DCBZ32_ill + */ + li r0,0 + mfspr r3,SPRN_HID4 + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ + rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ + sync + mtspr SPRN_HID4,r3 + isync + sync + mfspr r3,SPRN_HID5 + rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ + sync + mtspr SPRN_HID5,r3 + isync + sync + + /* Setup some basic HID1 features */ + mfspr r0,SPRN_HID1 + li r3,0x1200 /* enable i-fetch cacheability */ + sldi r3,r3,44 /* and prefetch */ + or r0,r0,r3 + mtspr SPRN_HID1,r0 + mtspr SPRN_HID1,r0 + isync + + /* Clear HIOR */ + li r0,0 + sync + mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ + isync + blr + +/* Definitions for the table use to save CPU states */ +#define CS_HID0 0 +#define CS_HID1 8 +#define CS_HID4 16 +#define CS_HID5 24 +#define CS_SIZE 32 + + .data + .balign L1_CACHE_BYTES,0 +cpu_state_storage: + .space CS_SIZE + .balign L1_CACHE_BYTES,0 + .text + + +_GLOBAL(__setup_cpu_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + mfspr r0,SPRN_HID0 + li r11,5 /* clear DOZE and SLEEP */ + rldimi r0,r11,52,8 /* set NAP and DPM */ + mtspr SPRN_HID0,r0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + sync + isync + + /* Save away cpu state */ + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + + /* Save HID0,1,4 and 5 */ + mfspr r3,SPRN_HID0 + std r3,CS_HID0(r5) + mfspr r3,SPRN_HID1 + std r3,CS_HID1(r5) + mfspr r3,SPRN_HID4 + std r3,CS_HID4(r5) + mfspr r3,SPRN_HID5 + std r3,CS_HID5(r5) + + blr + +/* Called with no MMU context (typically MSR:IR/DR off) to + * restore CPU state as backed up by the previous + * function. This does not include cache setting + */ +_GLOBAL(__restore_cpu_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + /* Before accessing memory, we make sure rm_ci is clear */ + li r0,0 + mfspr r3,SPRN_HID4 + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ + sync + mtspr SPRN_HID4,r3 + isync + sync + + /* Clear interrupt prefix */ + li r0,0 + sync + mtspr SPRN_HIOR,0 + isync + + /* Restore HID0 */ + ld r3,CS_HID0(r5) + sync + isync + mtspr SPRN_HID0,r3 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + sync + isync + + /* Restore HID1 */ + ld r3,CS_HID1(r5) + sync + isync + mtspr SPRN_HID1,r3 + mtspr SPRN_HID1,r3 + sync + isync + + /* Restore HID4 */ + ld r3,CS_HID4(r5) + sync + isync + mtspr SPRN_HID4,r3 + sync + isync + + /* Restore HID5 */ + ld r3,CS_HID5(r5) + sync + isync + mtspr SPRN_HID5,r3 + sync + isync + blr + Index: linux-2.6/arch/powerpc/kernel/head_64.S =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/head_64.S +++ linux-2.6/arch/powerpc/kernel/head_64.S @@ -152,7 +152,7 @@ _GLOBAL(__secondary_hold) bne 100b #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) - LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) + LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init) mtctr r4 mr r3,r24 bctr @@ -1473,18 +1473,25 @@ fwnmi_data_area: . = 0x8000 /* - * On pSeries, secondary processors spin in the following code. + * On pSeries and most other platforms, secondary processors spin + * in the following code. * At entry, r3 = this processor's number (physical cpu id) */ -_GLOBAL(pSeries_secondary_smp_init) +_GLOBAL(generic_secondary_smp_init) mr r24,r3 /* turn on 64-bit mode */ bl .enable_64b_mode isync - /* Copy some CPU settings from CPU 0 */ - bl .__restore_cpu_setup + LOAD_REG_IMMEDIATE(r4, cur_cpu_spec) + ld r5, CPU_SPEC_RESTORE(r4) + cmpdi 0,r5,0 + beq 1f + ld r5,0(r5) + mtctr r5 + bctrl +1: /* Set up a paca value for this processor. Since we have the * physical cpu id in r24, we need to search the pacas to find @@ -1600,7 +1607,16 @@ _GLOBAL(__start_initialization_multiplat bl .enable_64b_mode /* Setup some critical 970 SPRs before switching MMU off */ - bl .__970_cpu_preinit + mfspr r0,SPRN_PVR + srwi r0,r0,16 + cmpwi r0,0x39 /* 970 */ + beq 1f + cmpwi r0,0x3c /* 970FX */ + beq 1f + cmpwi r0,0x44 /* 970MP */ + bne 2f +1: bl .__cpu_preinit_ppc970 +2: /* cpu # */ li r24,0 @@ -1771,7 +1787,7 @@ _GLOBAL(pmac_secondary_start) isync /* Copy some CPU settings from CPU 0 */ - bl .__restore_cpu_setup + bl .__restore_cpu_ppc970 /* pSeries do that early though I don't think we really need it */ mfmsr r3 @@ -1921,12 +1937,6 @@ _STATIC(start_here_multiplatform) mr r5,r26 bl .identify_cpu - /* Save some low level config HIDs of CPU0 to be copied to - * other CPUs later on, or used for suspend/resume - */ - bl .__save_cpu_setup - sync - /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ Index: linux-2.6/arch/powerpc/platforms/cell/smp.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/smp.c +++ linux-2.6/arch/powerpc/platforms/cell/smp.c @@ -58,7 +58,7 @@ */ static cpumask_t of_spin_map; -extern void pSeries_secondary_smp_init(unsigned long); +extern void generic_secondary_smp_init(unsigned long); /** * smp_startup_cpu() - start the given cpu @@ -75,7 +75,7 @@ static inline int __devinit smp_startup_ { int status; unsigned long start_here = __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)); + generic_secondary_smp_init)); unsigned int pcpu; int start_cpu; Index: linux-2.6/arch/powerpc/platforms/pseries/smp.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/pseries/smp.c +++ linux-2.6/arch/powerpc/platforms/pseries/smp.c @@ -63,7 +63,7 @@ */ static cpumask_t of_spin_map; -extern void pSeries_secondary_smp_init(unsigned long); +extern void generic_secondary_smp_init(unsigned long); #ifdef CONFIG_HOTPLUG_CPU @@ -271,7 +271,7 @@ static inline int __devinit smp_startup_ { int status; unsigned long start_here = __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)); + generic_secondary_smp_init)); unsigned int pcpu; int start_cpu; Index: linux-2.6/arch/powerpc/kernel/asm-offsets.c =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/asm-offsets.c +++ linux-2.6/arch/powerpc/kernel/asm-offsets.c @@ -241,6 +241,7 @@ int main(void) DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); #ifndef CONFIG_PPC64 DEFINE(pbe_address, offsetof(struct pbe, address)); Index: linux-2.6/arch/powerpc/kernel/cputable.c =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/cputable.c +++ linux-2.6/arch/powerpc/kernel/cputable.c @@ -40,7 +40,10 @@ extern void __setup_cpu_7400(unsigned lo extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); #endif /* CONFIG_PPC32 */ +#ifdef CONFIG_PPC64 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); +extern void __restore_cpu_ppc970(void); +#endif /* CONFIG_PPC64 */ /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... @@ -185,6 +188,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -200,6 +204,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -215,6 +220,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", Index: linux-2.6/include/asm-powerpc/cputable.h =================================================================== --- linux-2.6.orig/include/asm-powerpc/cputable.h +++ linux-2.6/include/asm-powerpc/cputable.h @@ -65,6 +65,8 @@ struct cpu_spec { * BHT, SPD, etc... from head.S before branching to identify_machine */ cpu_setup_t cpu_setup; + /* Used to restore cpu setup on secondary processors and at resume */ + void (*cpu_restore)(void); /* Used by oprofile userspace to select the right counters */ char *oprofile_cpu_type; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] powerpc: Do a bit more cpu init cleanups (v3) 2006-06-28 4:38 ` [PATCH] powerpc: Do a bit more cpu init cleanups (v2) Olof Johansson @ 2006-06-28 9:30 ` Olof Johansson 0 siblings, 0 replies; 7+ messages in thread From: Olof Johansson @ 2006-06-28 9:30 UTC (permalink / raw) To: paulus; +Cc: linuxppc-dev Last patch had two problems: * cur_cpu_spec isn't available that early for processors that are started from prom_init, so call it after release instead of before * Fumbled with the assembly It's a wonder that it booted on powermac (which it did). New version below: Cleanup CPU inits a bit more, Geoff Levand already did some earlier. * Rename cpu_setup_power4.S to cpu_setup_ppc970.S * Move CPU state save to cpu_setup, since cpu_setup is only ever done on cpu 0 on 64-bit and save is never done more than once. * Rename __restore_cpu_setup to __restore_cpu_ppc970 and add function pointers to the cputable to use instead. Powermac always has 970 so no need to check there. Call it a bit later so we have cputables set up properly. * Rename __970_cpu_preinit to __cpu_preinit_ppc970 and check PVR before calling it instead of in it, it's too early to use cputable. * Rename pSeries_secondary_smp_init to generic_secondary_smp_init since everyone but powermac and iSeries use it. Signed-off-by: Olof Johansson <olof@lixom•net> Index: linux-2.6/arch/powerpc/kernel/Makefile =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/Makefile +++ linux-2.6/arch/powerpc/kernel/Makefile @@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrac obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ - paca.o cpu_setup_power4.o \ + paca.o cpu_setup_ppc970.o \ firmware.o sysfs.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o Index: linux-2.6/arch/powerpc/kernel/cpu_setup_power4.S =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/cpu_setup_power4.S +++ /dev/null @@ -1,216 +0,0 @@ -/* - * This file contains low level CPU setup functions. - * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include <linux/config.h> -#include <asm/processor.h> -#include <asm/page.h> -#include <asm/cputable.h> -#include <asm/ppc_asm.h> -#include <asm/asm-offsets.h> -#include <asm/cache.h> - -_GLOBAL(__970_cpu_preinit) - /* - * Do nothing if not running in HV mode - */ - mfmsr r0 - rldicl. r0,r0,4,63 - beqlr - - /* - * Deal only with PPC970 and PPC970FX. - */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bnelr -1: - - /* Make sure HID4:rm_ci is off before MMU is turned off, that large - * pages are enabled with HID4:61 and clear HID5:DCBZ_size and - * HID5:DCBZ32_ill - */ - li r0,0 - mfspr r3,SPRN_HID4 - rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ - rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ - sync - mtspr SPRN_HID4,r3 - isync - sync - mfspr r3,SPRN_HID5 - rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ - sync - mtspr SPRN_HID5,r3 - isync - sync - - /* Setup some basic HID1 features */ - mfspr r0,SPRN_HID1 - li r3,0x1200 /* enable i-fetch cacheability */ - sldi r3,r3,44 /* and prefetch */ - or r0,r0,r3 - mtspr SPRN_HID1,r0 - mtspr SPRN_HID1,r0 - isync - - /* Clear HIOR */ - li r0,0 - sync - mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ - isync - blr - -_GLOBAL(__setup_cpu_ppc970) - mfspr r0,SPRN_HID0 - li r11,5 /* clear DOZE and SLEEP */ - rldimi r0,r11,52,8 /* set NAP and DPM */ - mtspr SPRN_HID0,r0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - mfspr r0,SPRN_HID0 - sync - isync - blr - -/* Definitions for the table use to save CPU states */ -#define CS_HID0 0 -#define CS_HID1 8 -#define CS_HID4 16 -#define CS_HID5 24 -#define CS_SIZE 32 - - .data - .balign L1_CACHE_BYTES,0 -cpu_state_storage: - .space CS_SIZE - .balign L1_CACHE_BYTES,0 - .text - -/* Called in normal context to backup CPU 0 state. This - * does not include cache settings. This function is also - * called for machine sleep. This does not include the MMU - * setup, BATs, etc... but rather the "special" registers - * like HID0, HID1, HID4, etc... - */ -_GLOBAL(__save_cpu_setup) - /* Some CR fields are volatile, we back it up all */ - mfcr r7 - - /* Get storage ptr */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) - - /* We only deal with 970 for now */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bne 2f - -1: /* Save HID0,1,4 and 5 */ - mfspr r3,SPRN_HID0 - std r3,CS_HID0(r5) - mfspr r3,SPRN_HID1 - std r3,CS_HID1(r5) - mfspr r3,SPRN_HID4 - std r3,CS_HID4(r5) - mfspr r3,SPRN_HID5 - std r3,CS_HID5(r5) - -2: - mtcr r7 - blr - -/* Called with no MMU context (typically MSR:IR/DR off) to - * restore CPU state as backed up by the previous - * function. This does not include cache setting - */ -_GLOBAL(__restore_cpu_setup) - /* Get storage ptr (FIXME when using anton reloc as we - * are running with translation disabled here - */ - LOAD_REG_IMMEDIATE(r5,cpu_state_storage) - - /* We only deal with 970 for now */ - mfspr r0,SPRN_PVR - srwi r0,r0,16 - cmpwi r0,0x39 - beq 1f - cmpwi r0,0x3c - beq 1f - cmpwi r0,0x44 - bnelr - -1: /* Before accessing memory, we make sure rm_ci is clear */ - li r0,0 - mfspr r3,SPRN_HID4 - rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ - sync - mtspr SPRN_HID4,r3 - isync - sync - - /* Clear interrupt prefix */ - li r0,0 - sync - mtspr SPRN_HIOR,0 - isync - - /* Restore HID0 */ - ld r3,CS_HID0(r5) - sync - isync - mtspr SPRN_HID0,r3 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - mfspr r3,SPRN_HID0 - sync - isync - - /* Restore HID1 */ - ld r3,CS_HID1(r5) - sync - isync - mtspr SPRN_HID1,r3 - mtspr SPRN_HID1,r3 - sync - isync - - /* Restore HID4 */ - ld r3,CS_HID4(r5) - sync - isync - mtspr SPRN_HID4,r3 - sync - isync - - /* Restore HID5 */ - ld r3,CS_HID5(r5) - sync - isync - mtspr SPRN_HID5,r3 - sync - isync - blr - Index: linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S =================================================================== --- /dev/null +++ linux-2.6/arch/powerpc/kernel/cpu_setup_ppc970.S @@ -0,0 +1,175 @@ +/* + * This file contains low level CPU setup functions. + * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel•crashing.org) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include <linux/config.h> +#include <asm/processor.h> +#include <asm/page.h> +#include <asm/cputable.h> +#include <asm/ppc_asm.h> +#include <asm/asm-offsets.h> +#include <asm/cache.h> + +_GLOBAL(__cpu_preinit_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + /* Make sure HID4:rm_ci is off before MMU is turned off, that large + * pages are enabled with HID4:61 and clear HID5:DCBZ_size and + * HID5:DCBZ32_ill + */ + li r0,0 + mfspr r3,SPRN_HID4 + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ + rldimi r3,r0,2,61 /* clear bit 61 (lg_pg_en) */ + sync + mtspr SPRN_HID4,r3 + isync + sync + mfspr r3,SPRN_HID5 + rldimi r3,r0,6,56 /* clear bits 56 & 57 (DCBZ*) */ + sync + mtspr SPRN_HID5,r3 + isync + sync + + /* Setup some basic HID1 features */ + mfspr r0,SPRN_HID1 + li r3,0x1200 /* enable i-fetch cacheability */ + sldi r3,r3,44 /* and prefetch */ + or r0,r0,r3 + mtspr SPRN_HID1,r0 + mtspr SPRN_HID1,r0 + isync + + /* Clear HIOR */ + li r0,0 + sync + mtspr SPRN_HIOR,0 /* Clear interrupt prefix */ + isync + blr + +/* Definitions for the table use to save CPU states */ +#define CS_HID0 0 +#define CS_HID1 8 +#define CS_HID4 16 +#define CS_HID5 24 +#define CS_SIZE 32 + + .data + .balign L1_CACHE_BYTES,0 +cpu_state_storage: + .space CS_SIZE + .balign L1_CACHE_BYTES,0 + .text + + +_GLOBAL(__setup_cpu_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + mfspr r0,SPRN_HID0 + li r11,5 /* clear DOZE and SLEEP */ + rldimi r0,r11,52,8 /* set NAP and DPM */ + mtspr SPRN_HID0,r0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + mfspr r0,SPRN_HID0 + sync + isync + + /* Save away cpu state */ + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + + /* Save HID0,1,4 and 5 */ + mfspr r3,SPRN_HID0 + std r3,CS_HID0(r5) + mfspr r3,SPRN_HID1 + std r3,CS_HID1(r5) + mfspr r3,SPRN_HID4 + std r3,CS_HID4(r5) + mfspr r3,SPRN_HID5 + std r3,CS_HID5(r5) + + blr + +/* Called with no MMU context (typically MSR:IR/DR off) to + * restore CPU state as backed up by the previous + * function. This does not include cache setting + */ +_GLOBAL(__restore_cpu_ppc970) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + LOAD_REG_IMMEDIATE(r5,cpu_state_storage) + /* Before accessing memory, we make sure rm_ci is clear */ + li r0,0 + mfspr r3,SPRN_HID4 + rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ + sync + mtspr SPRN_HID4,r3 + isync + sync + + /* Clear interrupt prefix */ + li r0,0 + sync + mtspr SPRN_HIOR,0 + isync + + /* Restore HID0 */ + ld r3,CS_HID0(r5) + sync + isync + mtspr SPRN_HID0,r3 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + mfspr r3,SPRN_HID0 + sync + isync + + /* Restore HID1 */ + ld r3,CS_HID1(r5) + sync + isync + mtspr SPRN_HID1,r3 + mtspr SPRN_HID1,r3 + sync + isync + + /* Restore HID4 */ + ld r3,CS_HID4(r5) + sync + isync + mtspr SPRN_HID4,r3 + sync + isync + + /* Restore HID5 */ + ld r3,CS_HID5(r5) + sync + isync + mtspr SPRN_HID5,r3 + sync + isync + blr + Index: linux-2.6/arch/powerpc/kernel/head_64.S =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/head_64.S +++ linux-2.6/arch/powerpc/kernel/head_64.S @@ -152,7 +152,7 @@ _GLOBAL(__secondary_hold) bne 100b #if defined(CONFIG_SMP) || defined(CONFIG_KEXEC) - LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init) + LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init) mtctr r4 mr r3,r24 bctr @@ -1473,19 +1473,17 @@ fwnmi_data_area: . = 0x8000 /* - * On pSeries, secondary processors spin in the following code. + * On pSeries and most other platforms, secondary processors spin + * in the following code. * At entry, r3 = this processor's number (physical cpu id) */ -_GLOBAL(pSeries_secondary_smp_init) +_GLOBAL(generic_secondary_smp_init) mr r24,r3 /* turn on 64-bit mode */ bl .enable_64b_mode isync - /* Copy some CPU settings from CPU 0 */ - bl .__restore_cpu_setup - /* Set up a paca value for this processor. Since we have the * physical cpu id in r24, we need to search the pacas to find * which logical id maps to our physical one. @@ -1511,15 +1509,28 @@ _GLOBAL(pSeries_secondary_smp_init) /* start. */ sync - /* Create a temp kernel stack for use before relocation is on. */ +#ifndef CONFIG_SMP + b 3b /* Never go on non-SMP */ +#else + cmpwi 0,r23,0 + beq 3b /* Loop until told to go */ + + /* See if we need to call a cpu state restore handler */ + LOAD_REG_IMMEDIATE(r23, cur_cpu_spec) + ld r23,0(r23) + ld r23,CPU_SPEC_RESTORE(r23) + cmpdi 0,r23,0 + beq 4f + ld r23,0(r23) + mtctr r23 + bctrl + +4: /* Create a temp kernel stack for use before relocation is on. */ ld r1,PACAEMERGSP(r13) subi r1,r1,STACK_FRAME_OVERHEAD - cmpwi 0,r23,0 -#ifdef CONFIG_SMP - bne .__secondary_start + b .__secondary_start #endif - b 3b /* Loop until told to go */ #ifdef CONFIG_PPC_ISERIES _STATIC(__start_initialization_iSeries) @@ -1600,7 +1611,16 @@ _GLOBAL(__start_initialization_multiplat bl .enable_64b_mode /* Setup some critical 970 SPRs before switching MMU off */ - bl .__970_cpu_preinit + mfspr r0,SPRN_PVR + srwi r0,r0,16 + cmpwi r0,0x39 /* 970 */ + beq 1f + cmpwi r0,0x3c /* 970FX */ + beq 1f + cmpwi r0,0x44 /* 970MP */ + bne 2f +1: bl .__cpu_preinit_ppc970 +2: /* cpu # */ li r24,0 @@ -1771,7 +1791,7 @@ _GLOBAL(pmac_secondary_start) isync /* Copy some CPU settings from CPU 0 */ - bl .__restore_cpu_setup + bl .__restore_cpu_ppc970 /* pSeries do that early though I don't think we really need it */ mfmsr r3 @@ -1921,12 +1941,6 @@ _STATIC(start_here_multiplatform) mr r5,r26 bl .identify_cpu - /* Save some low level config HIDs of CPU0 to be copied to - * other CPUs later on, or used for suspend/resume - */ - bl .__save_cpu_setup - sync - /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ Index: linux-2.6/arch/powerpc/platforms/cell/smp.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/cell/smp.c +++ linux-2.6/arch/powerpc/platforms/cell/smp.c @@ -58,7 +58,7 @@ */ static cpumask_t of_spin_map; -extern void pSeries_secondary_smp_init(unsigned long); +extern void generic_secondary_smp_init(unsigned long); /** * smp_startup_cpu() - start the given cpu @@ -75,7 +75,7 @@ static inline int __devinit smp_startup_ { int status; unsigned long start_here = __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)); + generic_secondary_smp_init)); unsigned int pcpu; int start_cpu; Index: linux-2.6/arch/powerpc/platforms/pseries/smp.c =================================================================== --- linux-2.6.orig/arch/powerpc/platforms/pseries/smp.c +++ linux-2.6/arch/powerpc/platforms/pseries/smp.c @@ -63,7 +63,7 @@ */ static cpumask_t of_spin_map; -extern void pSeries_secondary_smp_init(unsigned long); +extern void generic_secondary_smp_init(unsigned long); #ifdef CONFIG_HOTPLUG_CPU @@ -271,7 +271,7 @@ static inline int __devinit smp_startup_ { int status; unsigned long start_here = __pa((u32)*((unsigned long *) - pSeries_secondary_smp_init)); + generic_secondary_smp_init)); unsigned int pcpu; int start_cpu; Index: linux-2.6/arch/powerpc/kernel/asm-offsets.c =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/asm-offsets.c +++ linux-2.6/arch/powerpc/kernel/asm-offsets.c @@ -241,6 +241,7 @@ int main(void) DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); + DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore)); #ifndef CONFIG_PPC64 DEFINE(pbe_address, offsetof(struct pbe, address)); Index: linux-2.6/arch/powerpc/kernel/cputable.c =================================================================== --- linux-2.6.orig/arch/powerpc/kernel/cputable.c +++ linux-2.6/arch/powerpc/kernel/cputable.c @@ -40,7 +40,10 @@ extern void __setup_cpu_7400(unsigned lo extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec); extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); #endif /* CONFIG_PPC32 */ +#ifdef CONFIG_PPC64 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); +extern void __restore_cpu_ppc970(void); +#endif /* CONFIG_PPC64 */ /* This table only contains "desktop" CPUs, it need to be filled with embedded * ones as well... @@ -185,6 +188,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -200,6 +204,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", @@ -215,6 +220,7 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, + .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", Index: linux-2.6/include/asm-powerpc/cputable.h =================================================================== --- linux-2.6.orig/include/asm-powerpc/cputable.h +++ linux-2.6/include/asm-powerpc/cputable.h @@ -36,6 +36,7 @@ struct cpu_spec; typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec); +typedef void (*cpu_restore_t)(void); enum powerpc_oprofile_type { PPC_OPROFILE_INVALID = 0, @@ -65,6 +66,8 @@ struct cpu_spec { * BHT, SPD, etc... from head.S before branching to identify_machine */ cpu_setup_t cpu_setup; + /* Used to restore cpu setup on secondary processors and at resume */ + cpu_restore_t cpu_restore; /* Used by oprofile userspace to select the right counters */ char *oprofile_cpu_type; ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-06-28 9:31 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-06-27 19:22 [PATCH] powerpc: Do a bit more cpu init cleanups Olof Johansson 2006-06-27 22:20 ` Benjamin Herrenschmidt 2006-06-27 22:54 ` Olof Johansson 2006-06-27 23:07 ` Benjamin Herrenschmidt 2006-06-27 23:48 ` Olof Johansson 2006-06-28 4:38 ` [PATCH] powerpc: Do a bit more cpu init cleanups (v2) Olof Johansson 2006-06-28 9:30 ` [PATCH] powerpc: Do a bit more cpu init cleanups (v3) Olof Johansson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox