* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.