[PATCH] powerpc: merged asm/cputable.h
Michael Ellerman
michael at ellerman.id.au
Mon Sep 26 11:57:36 EST 2005
On Sun, 25 Sep 2005 01:35, Kumar Gala wrote:
> On Sep 23, 2005, at 7:48 PM, Stephen Rothwell wrote:
> > On Sat, 24 Sep 2005 10:04:12 +1000 Paul Mackerras
> >
> > <paulus at samba.org> wrote:
> >> Kumar Gala writes:
> >>> +#ifdef __powerpc64__
> >>> +extern struct cpu_spec *cur_cpu_spec;
> >>> +#else /* __powerpc64__ */
> >>> +extern struct cpu_spec *cur_cpu_spec[];
> >>> +#endif /* __powerpc64__ */
> >>
> >> I would like to see this unified - it makes no sense for them to be
> >> different. We are unlikely to support asymmetric multiprocessing any
> >> time soon, so let's go with the single cur_cpu_spec pointer (a la
> >> ppc64).
> >
> > Michael Ellerman also has a patch that makes this a struct (i.e. not a
> > pointer) which allows us to mark the array of cpuspec's that we test
> > against at boot time as __init. Maybe he could do the ppc32 single
> > cpu_spec as part of that.
>
> I'm all for unifying this as well. If Michael can post his patch
> I'll look at fixing up this issue. Let's merge the current patch and
> follow it up with an update that includes this fix and Michael's work.
Here's a version of my patch updated to apply on top of the merge tree.
It'll be a lot cleaner when ppc32 has a single cur_cpu_spec, as we'll
be able to remove a lot of the #ifdefs.
cheers
Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---
arch/powerpc/oprofile/common.c | 8 +++----
arch/powerpc/oprofile/op_model_power4.c | 6 ++---
arch/ppc64/kernel/asm-offsets.c | 4 ---
arch/ppc64/kernel/cputable.c | 33 ++++++++++++++++++++++++++------
arch/ppc64/kernel/head.S | 11 ----------
arch/ppc64/kernel/idle_power4.S | 5 +---
arch/ppc64/kernel/misc.S | 32 -------------------------------
arch/ppc64/kernel/prom.c | 12 +++++------
arch/ppc64/kernel/setup.c | 8 +++----
arch/ppc64/kernel/sysfs.c | 32 +++++++++++++++----------------
include/asm-powerpc/cputable.h | 24 +++++++++++++++++------
include/asm-powerpc/elf.h | 2 -
Index: kexec/include/asm-powerpc/cputable.h
===================================================================
--- kexec.orig/include/asm-powerpc/cputable.h
+++ kexec/include/asm-powerpc/cputable.h
@@ -26,7 +26,7 @@ struct cpu_spec;
struct op_powerpc_model;
#ifdef __powerpc64__
-typedef void (*cpu_setup_t)(unsigned long offset, struct cpu_spec* spec);
+typedef void (*cpu_setup_t)(struct cpu_spec* spec);
#else /* __powerpc64__ */
typedef void (*cpu_setup_t)(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
#endif /* __powerpc64__ */
@@ -61,10 +61,10 @@ struct cpu_spec {
#endif /* __powerpc64__ */
};
-extern struct cpu_spec cpu_specs[];
+extern void identify_cpu(void);
#ifdef __powerpc64__
-extern struct cpu_spec *cur_cpu_spec;
+extern struct cpu_spec cur_cpu_spec;
#else /* __powerpc64__ */
extern struct cpu_spec *cur_cpu_spec[];
#endif /* __powerpc64__ */
@@ -398,14 +398,26 @@ static inline int cpu_has_feature(unsign
{
return (CPU_FTRS_ALWAYS & feature) ||
(CPU_FTRS_POSSIBLE
-#ifndef __powerpc64__
- & cur_cpu_spec[0]->cpu_features
+#ifdef __powerpc64__
+ & cur_cpu_spec.cpu_features
#else
- & cur_cpu_spec->cpu_features
+ & cur_cpu_spec[0].cpu_features
#endif
& feature);
}
+#ifdef __powerpc64__
+static inline void cpu_set_feature(unsigned long feature)
+{
+ cur_cpu_spec.cpu_features |= feature;
+}
+
+static inline void cpu_unset_feature(unsigned long feature)
+{
+ cur_cpu_spec.cpu_features &= ~feature;
+}
+#endif
+
#endif /* !__ASSEMBLY__ */
#ifdef __ASSEMBLY__
Index: kexec/arch/ppc64/kernel/cputable.c
===================================================================
--- kexec.orig/arch/ppc64/kernel/cputable.c
+++ kexec/arch/ppc64/kernel/cputable.c
@@ -22,7 +22,7 @@
#include <asm/oprofile_impl.h>
#include <asm/cputable.h>
-struct cpu_spec* cur_cpu_spec = NULL;
+struct cpu_spec cur_cpu_spec;
EXPORT_SYMBOL(cur_cpu_spec);
/* NOTE:
@@ -32,12 +32,12 @@ EXPORT_SYMBOL(cur_cpu_spec);
* part of the cputable though. That has to be fixed for both ppc32
* and ppc64
*/
-extern void __setup_cpu_power3(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_power4(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
-extern void __setup_cpu_be(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_power3(struct cpu_spec* spec);
+extern void __setup_cpu_power4(struct cpu_spec* spec);
+extern void __setup_cpu_ppc970(struct cpu_spec* spec);
+extern void __setup_cpu_be(struct cpu_spec* spec);
-struct cpu_spec cpu_specs[] = {
+static __initdata struct cpu_spec cpu_specs[] = {
{ /* Power3 */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00400000,
@@ -258,3 +258,24 @@ struct cpu_spec cpu_specs[] = {
.cpu_setup = __setup_cpu_power4,
}
};
+
+void __init identify_cpu(void)
+{
+ unsigned int pvr, mask, value;
+ int i;
+
+ pvr = mfspr(SPRN_PVR);
+
+ /* We rely on the default match at the end of the cpu_spec array */
+ for (i = 0; ; i++) {
+ mask = cpu_specs[i].pvr_mask;
+ value = cpu_specs[i].pvr_value;
+
+ if ((pvr & mask) == value)
+ break;
+ }
+
+ cur_cpu_spec = cpu_specs[i];
+
+ cur_cpu_spec.cpu_setup(&cur_cpu_spec);
+}
Index: kexec/arch/ppc64/kernel/asm-offsets.c
===================================================================
--- kexec.orig/arch/ppc64/kernel/asm-offsets.c
+++ kexec/arch/ppc64/kernel/asm-offsets.c
@@ -165,11 +165,7 @@ int main(void)
DEFINE(CLONE_UNTRACED, CLONE_UNTRACED);
/* About the CPU features table */
- DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec));
- DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask));
- 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));
/* systemcfg offsets for use by vdso */
DEFINE(CFG_TB_ORIG_STAMP, offsetof(struct systemcfg, tb_orig_stamp));
Index: kexec/arch/ppc64/kernel/head.S
===================================================================
--- kexec.orig/arch/ppc64/kernel/head.S
+++ kexec/arch/ppc64/kernel/head.S
@@ -1354,15 +1354,11 @@ _STATIC(__start_initialization_iSeries)
li r0,0
stdu r0,-STACK_FRAME_OVERHEAD(r1)
- LOADADDR(r3,cpu_specs)
- LOADADDR(r4,cur_cpu_spec)
- li r5,0
- bl .identify_cpu
-
LOADADDR(r2,__toc_start)
addi r2,r2,0x4000
addi r2,r2,0x4000
+ bl .identify_cpu
bl .iSeries_early_setup
/* relocation is on at this point */
@@ -1771,11 +1767,6 @@ _STATIC(start_here_multiplatform)
addi r2,r2,0x4000
sub r2,r2,r26
- LOADADDR(r3,cpu_specs)
- sub r3,r3,r26
- LOADADDR(r4,cur_cpu_spec)
- sub r4,r4,r26
- mr r5,r26
bl .identify_cpu
/* Save some low level config HIDs of CPU0 to be copied to
Index: kexec/arch/ppc64/kernel/misc.S
===================================================================
--- kexec.orig/arch/ppc64/kernel/misc.S
+++ kexec/arch/ppc64/kernel/misc.S
@@ -508,35 +508,6 @@ _GLOBAL(cvt_df)
blr
/*
- * identify_cpu and calls setup_cpu
- * In: r3 = base of the cpu_specs array
- * r4 = address of cur_cpu_spec
- * r5 = relocation offset
- */
-_GLOBAL(identify_cpu)
- mfpvr r7
-1:
- lwz r8,CPU_SPEC_PVR_MASK(r3)
- and r8,r8,r7
- lwz r9,CPU_SPEC_PVR_VALUE(r3)
- cmplw 0,r9,r8
- beq 1f
- addi r3,r3,CPU_SPEC_ENTRY_SIZE
- b 1b
-1:
- add r0,r3,r5
- std r0,0(r4)
- ld r4,CPU_SPEC_SETUP(r3)
- sub r4,r4,r5
- ld r4,0(r4)
- sub r4,r4,r5
- mtctr r4
- /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */
- mr r4,r3
- mr r3,r5
- bctr
-
-/*
* do_cpu_ftr_fixups - goes through the list of CPU feature fixups
* and writes nop's over sections of code that don't apply for this cpu.
* r3 = data offset (not changed)
@@ -545,9 +516,8 @@ _GLOBAL(do_cpu_ftr_fixups)
/* Get CPU 0 features */
LOADADDR(r6,cur_cpu_spec)
sub r6,r6,r3
- ld r4,0(r6)
+ ld r4,CPU_SPEC_FEATURES(r6)
sub r4,r4,r3
- ld r4,CPU_SPEC_FEATURES(r4)
/* Get the fixup table */
LOADADDR(r6,__start___ftr_fixup)
sub r6,r6,r3
Index: kexec/arch/ppc64/kernel/idle_power4.S
===================================================================
--- kexec.orig/arch/ppc64/kernel/idle_power4.S
+++ kexec/arch/ppc64/kernel/idle_power4.S
@@ -38,9 +38,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
/* We must dynamically check for the NAP feature as it
* can be cleared by CPU init after the fixups are done
*/
- LOADBASE(r3,cur_cpu_spec)
- ld r4,cur_cpu_spec at l(r3)
- ld r4,CPU_SPEC_FEATURES(r4)
+ LOADADDR(r3,cur_cpu_spec)
+ ld r4,CPU_SPEC_FEATURES(r3)
andi. r0,r4,CPU_FTR_CAN_NAP
beqlr
/* Now check if user or arch enabled NAP mode */
Index: kexec/arch/ppc64/kernel/prom.c
===================================================================
--- kexec.orig/arch/ppc64/kernel/prom.c
+++ kexec/arch/ppc64/kernel/prom.c
@@ -1032,15 +1032,15 @@ static int __init early_init_dt_scan_cpu
/* Check if we have a VMX and eventually update CPU features */
prop = (u32 *)get_flat_dt_prop(node, "ibm,vmx", NULL);
if (prop && (*prop) > 0) {
- cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
- cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+ cpu_set_feature(CPU_FTR_ALTIVEC);
+ cpu_set_feature(PPC_FEATURE_HAS_ALTIVEC);
}
/* Same goes for Apple's "altivec" property */
prop = (u32 *)get_flat_dt_prop(node, "altivec", NULL);
if (prop) {
- cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC;
- cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC;
+ cpu_set_feature(CPU_FTR_ALTIVEC);
+ cpu_set_feature(PPC_FEATURE_HAS_ALTIVEC);
}
#endif /* CONFIG_ALTIVEC */
@@ -1051,9 +1051,9 @@ static int __init early_init_dt_scan_cpu
*/
prop = (u32 *)get_flat_dt_prop(node, "ibm,ppc-interrupt-server#s",
&size);
- cur_cpu_spec->cpu_features &= ~CPU_FTR_SMT;
+ cpu_unset_feature(CPU_FTR_SMT);
if (prop && ((size / sizeof(u32)) > 1))
- cur_cpu_spec->cpu_features |= CPU_FTR_SMT;
+ cpu_set_feature(CPU_FTR_SMT);
return 0;
}
Index: kexec/arch/ppc64/kernel/setup.c
===================================================================
--- kexec.orig/arch/ppc64/kernel/setup.c
+++ kexec/arch/ppc64/kernel/setup.c
@@ -448,7 +448,7 @@ static void __init initialize_cache_info
}
size = 0;
- lsize = cur_cpu_spec->dcache_bsize;
+ lsize = cur_cpu_spec.dcache_bsize;
sizep = (u32 *)get_property(np, "d-cache-size", NULL);
if (sizep != NULL)
size = *sizep;
@@ -466,7 +466,7 @@ static void __init initialize_cache_info
ppc64_caches.dlines_per_page = PAGE_SIZE / lsize;
size = 0;
- lsize = cur_cpu_spec->icache_bsize;
+ lsize = cur_cpu_spec.icache_bsize;
sizep = (u32 *)get_property(np, "i-cache-size", NULL);
if (sizep != NULL)
size = *sizep;
@@ -736,8 +736,8 @@ static int show_cpuinfo(struct seq_file
seq_printf(m, "processor\t: %lu\n", cpu_id);
seq_printf(m, "cpu\t\t: ");
- if (cur_cpu_spec->pvr_mask)
- seq_printf(m, "%s", cur_cpu_spec->cpu_name);
+ if (cur_cpu_spec.pvr_mask)
+ seq_printf(m, "%s", cur_cpu_spec.cpu_name);
else
seq_printf(m, "unknown (%08x)", pvr);
Index: kexec/arch/ppc64/kernel/sysfs.c
===================================================================
--- kexec.orig/arch/ppc64/kernel/sysfs.c
+++ kexec/arch/ppc64/kernel/sysfs.c
@@ -215,21 +215,21 @@ static void register_cpu_online(unsigned
if (cpu_has_feature(CPU_FTR_MMCRA))
sysdev_create_file(s, &attr_mmcra);
- if (cur_cpu_spec->num_pmcs >= 1)
+ if (cur_cpu_spec.num_pmcs >= 1)
sysdev_create_file(s, &attr_pmc1);
- if (cur_cpu_spec->num_pmcs >= 2)
+ if (cur_cpu_spec.num_pmcs >= 2)
sysdev_create_file(s, &attr_pmc2);
- if (cur_cpu_spec->num_pmcs >= 3)
+ if (cur_cpu_spec.num_pmcs >= 3)
sysdev_create_file(s, &attr_pmc3);
- if (cur_cpu_spec->num_pmcs >= 4)
+ if (cur_cpu_spec.num_pmcs >= 4)
sysdev_create_file(s, &attr_pmc4);
- if (cur_cpu_spec->num_pmcs >= 5)
+ if (cur_cpu_spec.num_pmcs >= 5)
sysdev_create_file(s, &attr_pmc5);
- if (cur_cpu_spec->num_pmcs >= 6)
+ if (cur_cpu_spec.num_pmcs >= 6)
sysdev_create_file(s, &attr_pmc6);
- if (cur_cpu_spec->num_pmcs >= 7)
+ if (cur_cpu_spec.num_pmcs >= 7)
sysdev_create_file(s, &attr_pmc7);
- if (cur_cpu_spec->num_pmcs >= 8)
+ if (cur_cpu_spec.num_pmcs >= 8)
sysdev_create_file(s, &attr_pmc8);
if (cpu_has_feature(CPU_FTR_SMT))
@@ -257,21 +257,21 @@ static void unregister_cpu_online(unsign
if (cpu_has_feature(CPU_FTR_MMCRA))
sysdev_remove_file(s, &attr_mmcra);
- if (cur_cpu_spec->num_pmcs >= 1)
+ if (cur_cpu_spec.num_pmcs >= 1)
sysdev_remove_file(s, &attr_pmc1);
- if (cur_cpu_spec->num_pmcs >= 2)
+ if (cur_cpu_spec.num_pmcs >= 2)
sysdev_remove_file(s, &attr_pmc2);
- if (cur_cpu_spec->num_pmcs >= 3)
+ if (cur_cpu_spec.num_pmcs >= 3)
sysdev_remove_file(s, &attr_pmc3);
- if (cur_cpu_spec->num_pmcs >= 4)
+ if (cur_cpu_spec.num_pmcs >= 4)
sysdev_remove_file(s, &attr_pmc4);
- if (cur_cpu_spec->num_pmcs >= 5)
+ if (cur_cpu_spec.num_pmcs >= 5)
sysdev_remove_file(s, &attr_pmc5);
- if (cur_cpu_spec->num_pmcs >= 6)
+ if (cur_cpu_spec.num_pmcs >= 6)
sysdev_remove_file(s, &attr_pmc6);
- if (cur_cpu_spec->num_pmcs >= 7)
+ if (cur_cpu_spec.num_pmcs >= 7)
sysdev_remove_file(s, &attr_pmc7);
- if (cur_cpu_spec->num_pmcs >= 8)
+ if (cur_cpu_spec.num_pmcs >= 8)
sysdev_remove_file(s, &attr_pmc8);
if (cpu_has_feature(CPU_FTR_SMT))
Index: kexec/arch/powerpc/oprofile/common.c
===================================================================
--- kexec.orig/arch/powerpc/oprofile/common.c
+++ kexec/arch/powerpc/oprofile/common.c
@@ -173,12 +173,12 @@ int __init oprofile_arch_init(struct opr
ops->cpu_type = cpu_type;
#else /* __powerpc64__ */
- if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
+ if (!cur_cpu_spec.oprofile_model || !cur_cpu_spec.oprofile_cpu_type)
return -ENODEV;
- model = cur_cpu_spec->oprofile_model;
- model->num_counters = cur_cpu_spec->num_pmcs;
+ model = cur_cpu_spec.oprofile_model;
+ model->num_counters = cur_cpu_spec.num_pmcs;
- ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
+ ops->cpu_type = cur_cpu_spec.oprofile_cpu_type;
#endif /* __powerpc64__ */
ops->create_files = op_powerpc_create_files;
ops->setup = op_powerpc_setup;
Index: kexec/arch/powerpc/oprofile/op_model_power4.c
===================================================================
--- kexec.orig/arch/powerpc/oprofile/op_model_power4.c
+++ kexec/arch/powerpc/oprofile/op_model_power4.c
@@ -64,7 +64,7 @@ static void power4_reg_setup(struct op_c
backtrace_spinlocks = sys->backtrace_spinlocks;
- for (i = 0; i < cur_cpu_spec->num_pmcs; ++i)
+ for (i = 0; i < cur_cpu_spec.num_pmcs; ++i)
reset_value[i] = 0x80000000UL - ctr[i].count;
/* setup user and kernel profiling */
@@ -117,7 +117,7 @@ static void power4_start(struct op_count
/* set the PMM bit (see comment below) */
mtmsrd(mfmsr() | MSR_PMM);
- for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
+ for (i = 0; i < cur_cpu_spec.num_pmcs; ++i) {
if (ctr[i].enabled) {
ctr_write(i, reset_value[i]);
} else {
@@ -268,7 +268,7 @@ static void power4_handle_interrupt(stru
/* set the PMM bit (see comment below) */
mtmsrd(mfmsr() | MSR_PMM);
- for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
+ for (i = 0; i < cur_cpu_spec.num_pmcs; ++i) {
val = ctr_read(i);
if (val < 0) {
if (oprofile_running && ctr[i].enabled) {
Index: kexec/include/asm-powerpc/elf.h
===================================================================
--- kexec.orig/include/asm-powerpc/elf.h
+++ kexec/include/asm-powerpc/elf.h
@@ -213,7 +213,7 @@ extern int dump_task_fpu(struct task_str
instruction set this cpu supports. This could be done in userspace,
but it's not easy, and we've already done it here. */
#ifdef __powerpc64__
-# define ELF_HWCAP (cur_cpu_spec->cpu_user_features)
+# define ELF_HWCAP (cur_cpu_spec.cpu_user_features)
# define ELF_PLAT_INIT(_r, load_addr) do { \
memset(_r->gpr, 0, sizeof(_r->gpr)); \
_r->ctr = _r->link = _r->xer = _r->ccr = 0; \
More information about the Linuxppc-dev
mailing list