Skip to content

Commit

Permalink
[POWERPC] Cleanup CPU inits
Browse files Browse the repository at this point in the history
Cleanup CPU inits a bit more, Geoff Levand already did some earlier.

* 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.
* 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>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Olof Johansson authored and Paul Mackerras committed Aug 25, 2006
1 parent 2e97425 commit f39b7a5
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 98 deletions.
1 change: 1 addition & 0 deletions arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,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));
Expand Down
99 changes: 24 additions & 75 deletions arch/powerpc/kernel/cpu_setup_ppc970.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,12 @@
#include <asm/asm-offsets.h>
#include <asm/cache.h>

_GLOBAL(__970_cpu_preinit)
/*
* Do nothing if not running in HV mode
*/
_GLOBAL(__cpu_preinit_ppc970)
/* 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
Expand Down Expand Up @@ -72,21 +57,6 @@ _GLOBAL(__970_cpu_preinit)
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
Expand All @@ -101,33 +71,28 @@ cpu_state_storage:
.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: /* skip if not running in HV mode */
_GLOBAL(__setup_cpu_ppc970)
/* Do nothing if not running in HV mode */
mfmsr r0
rldicl. r0,r0,4,63
beq 2f
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
Expand All @@ -139,35 +104,19 @@ _GLOBAL(__save_cpu_setup)
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: /* skip if not running in HV mode */
_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
Expand Down
6 changes: 6 additions & 0 deletions arch/powerpc/kernel/cputable.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
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...
Expand Down Expand Up @@ -184,6 +187,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",
Expand All @@ -199,6 +203,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",
Expand All @@ -214,6 +219,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",
Expand Down
52 changes: 33 additions & 19 deletions arch/powerpc/kernel/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,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
Expand Down Expand Up @@ -1484,19 +1484,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.
Expand All @@ -1522,15 +1520,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)
Expand Down Expand Up @@ -1611,7 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform)
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:

/* Switch off MMU if not already */
LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
Expand Down Expand Up @@ -1782,7 +1802,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
Expand Down Expand Up @@ -1932,12 +1952,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. */

Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/platforms/cell/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,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
Expand All @@ -74,7 +74,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
{
int status;
unsigned long start_here = __pa((u32)*((unsigned long *)
pSeries_secondary_smp_init));
generic_secondary_smp_init));
unsigned int pcpu;
int start_cpu;

Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/platforms/pseries/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,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

Expand Down Expand Up @@ -270,7 +270,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
{
int status;
unsigned long start_here = __pa((u32)*((unsigned long *)
pSeries_secondary_smp_init));
generic_secondary_smp_init));
unsigned int pcpu;
int start_cpu;

Expand Down
3 changes: 3 additions & 0 deletions include/asm-powerpc/cputable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f39b7a5

Please sign in to comment.