MIPS: Store core & VP IDs in GlobalNumber-style variable
authorPaul Burton <paul.burton@imgtec.com>
Sun, 13 Aug 2017 02:49:36 +0000 (19:49 -0700)
committerRalf Baechle <ralf@linux-mips.org>
Tue, 29 Aug 2017 22:57:27 +0000 (00:57 +0200)
This patch modifies the way we store core & VP IDs such that we store
them in a single 32 bit integer whose format matches that of the MIPSr6
GlobalNumber register. Whereas we have previously stored core & VP IDs
in separate fields, storing them in a single GlobalNumber-like field:

  1) Reduces the size of struct cpuinfo_mips by 4 bytes, and will allow
     it to not grow when cluster support is added.

  2) Gives us a natural place to store cluster number, which matches up
     with what the architecture provides.

  3) Will be useful in the future as a parameter to the MIPSr6 GINVI
     instruction to specify a target CPU whose icache that instruction
     should operate on.

The cpu_set*() accessor functions are moved out of the asm/cpu-info.h
header in order to allow them to use the WARN_ON macro, which is
unusable in asm/cpu-info.h due to include ordering.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/17010/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/cpu-info.h
arch/mips/kernel/cpu-probe.c

index 2b2f97023705331e0b5069fa3baaa0565f652d05..9ae927282b121db0796c6b698703ccb141023169 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/cache.h>
 #include <linux/types.h>
 
+#include <asm/mipsregs.h>
+
 /*
  * Descriptor for a cache
  */
@@ -77,16 +79,9 @@ struct cpuinfo_mips {
        struct cache_desc       tcache; /* Tertiary/split secondary cache */
        int                     srsets; /* Shadow register sets */
        int                     package;/* physical package number */
-       int                     core;   /* physical core number */
+       unsigned int            globalnumber;
 #ifdef CONFIG_64BIT
        int                     vmbits; /* Virtual memory size in bits */
-#endif
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-       /*
-        * There is not necessarily a 1:1 mapping of VPE num to CPU number
-        * in particular on multi-core systems.
-        */
-       int                     vpe_id;  /* Virtual Processor number */
 #endif
        void                    *data;  /* Additional data */
        unsigned int            watch_reg_count;   /* Number that exist */
@@ -146,31 +141,23 @@ struct proc_cpuinfo_notifier_args {
 
 static inline unsigned int cpu_core(struct cpuinfo_mips *cpuinfo)
 {
-       return cpuinfo->core;
-}
-
-static inline void cpu_set_core(struct cpuinfo_mips *cpuinfo,
-                               unsigned int core)
-{
-       cpuinfo->core = core;
+       return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_CORE) >>
+               MIPS_GLOBALNUMBER_CORE_SHF;
 }
 
 static inline unsigned int cpu_vpe_id(struct cpuinfo_mips *cpuinfo)
 {
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-       return cpuinfo->vpe_id;
-#endif
-       return 0;
-}
+       /* Optimisation for systems where VP(E)s aren't used */
+       if (!IS_ENABLED(CONFIG_MIPS_MT_SMP) && !IS_ENABLED(CONFIG_CPU_MIPSR6))
+               return 0;
 
-static inline void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo,
-                                 unsigned int vpe)
-{
-#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6)
-       cpuinfo->vpe_id = vpe;
-#endif
+       return (cpuinfo->globalnumber & MIPS_GLOBALNUMBER_VP) >>
+               MIPS_GLOBALNUMBER_VP_SHF;
 }
 
+extern void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core);
+extern void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe);
+
 static inline unsigned long cpu_asid_inc(void)
 {
        return 1 << CONFIG_MIPS_ASID_SHIFT;
index b17b819852b8d5135ba0c605a638947d7322430f..32aabd2387375090e79dabde780ff24bb7c56841 100644 (file)
@@ -2098,3 +2098,25 @@ void cpu_report(void)
        if (cpu_has_msa)
                pr_info("MSA revision is: %08x\n", c->msa_id);
 }
+
+void cpu_set_core(struct cpuinfo_mips *cpuinfo, unsigned int core)
+{
+       /* Ensure the core number fits in the field */
+       WARN_ON(core > (MIPS_GLOBALNUMBER_CORE >> MIPS_GLOBALNUMBER_CORE_SHF));
+
+       cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_CORE;
+       cpuinfo->globalnumber |= core << MIPS_GLOBALNUMBER_CORE_SHF;
+}
+
+void cpu_set_vpe_id(struct cpuinfo_mips *cpuinfo, unsigned int vpe)
+{
+       /* Ensure the VP(E) ID fits in the field */
+       WARN_ON(vpe > (MIPS_GLOBALNUMBER_VP >> MIPS_GLOBALNUMBER_VP_SHF));
+
+       /* Ensure we're not using VP(E)s without support */
+       WARN_ON(vpe && !IS_ENABLED(CONFIG_MIPS_MT_SMP) &&
+               !IS_ENABLED(CONFIG_CPU_MIPSR6));
+
+       cpuinfo->globalnumber &= ~MIPS_GLOBALNUMBER_VP;
+       cpuinfo->globalnumber |= vpe << MIPS_GLOBALNUMBER_VP_SHF;
+}