On Fri, Dec 19, 2008 at 04:13:22PM +1100, Benjamin Herrenschmidt wrote:
>This adds supports to the "extended" DCR addressing via
>the indirect mfdcrx/mtdcrx instructions supported by some
>4xx cores (440H6 and later)
>
>I enabled the feature for now only on AMCC 460 chips
>
>Signed-off-by: Benjamin Herrenschmidt <b...@kernel.crashing.org>

Acked-by: Josh Boyer <jwbo...@linux.vnet.ibm.com>

In general, if you just carry over my previous Acks it'll make life
easier ;)

josh

>---
>
>This variant uses "440x6" instead of "440H6". I made no other
>changes to the code as I think the codegen is the less bad I've
>had so far and I rely on Josh further work on cleaning up the
>type of 440core selection at Kconfig time so the feature are
>properly reflected in the POSSIBLE and ALWAYS masks based on
>the core selection. That way, if only one core type is selected
>the feature test should resolve at compile time.
>
>
> arch/powerpc/include/asm/cputable.h   |    7 ++-
> arch/powerpc/include/asm/dcr-native.h |   63 
> +++++++++++++++++++++++++++-------
> arch/powerpc/kernel/cputable.c        |    4 +-
> arch/powerpc/sysdev/dcr-low.S         |    8 +++-
> 4 files changed, 65 insertions(+), 17 deletions(-)
>
>--- linux-work.orig/arch/powerpc/include/asm/cputable.h        2008-12-17 
>12:28:23.000000000 +1100
>+++ linux-work/arch/powerpc/include/asm/cputable.h     2008-12-17 
>12:30:52.000000000 +1100
>@@ -164,6 +164,7 @@ extern const char *powerpc_base_platform
> #define CPU_FTR_NEED_PAIRED_STWCX     ASM_CONST(0x0000000004000000)
> #define CPU_FTR_LWSYNC                        ASM_CONST(0x0000000008000000)
> #define CPU_FTR_NOEXECUTE             ASM_CONST(0x0000000010000000)
>+#define CPU_FTR_INDEXED_DCR           ASM_CONST(0x0000000020000000)
>
> /*
>  * Add the 64-bit processor unique features in the top half of the word;
>@@ -369,6 +370,8 @@ extern const char *powerpc_base_platform
> #define CPU_FTRS_8XX  (CPU_FTR_USE_TB)
> #define CPU_FTRS_40X  (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | 
> CPU_FTR_NOEXECUTE)
> #define CPU_FTRS_44X  (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | 
> CPU_FTR_NOEXECUTE)
>+#define CPU_FTRS_440x6        (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | 
>CPU_FTR_NOEXECUTE | \
>+          CPU_FTR_INDEXED_DCR)
> #define CPU_FTRS_E200 (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
>           CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
>           CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE)
>@@ -455,7 +458,7 @@ enum {
>           CPU_FTRS_40X |
> #endif
> #ifdef CONFIG_44x
>-          CPU_FTRS_44X |
>+          CPU_FTRS_44X | CPU_FTRS_440x6 |
> #endif
> #ifdef CONFIG_E200
>           CPU_FTRS_E200 |
>@@ -495,7 +498,7 @@ enum {
>           CPU_FTRS_40X &
> #endif
> #ifdef CONFIG_44x
>-          CPU_FTRS_44X &
>+          CPU_FTRS_44X & CPU_FTRS_440x6 &
> #endif
> #ifdef CONFIG_E200
>           CPU_FTRS_E200 &
>Index: linux-work/arch/powerpc/include/asm/dcr-native.h
>===================================================================
>--- linux-work.orig/arch/powerpc/include/asm/dcr-native.h      2008-09-29 
>14:21:37.000000000 +1000
>+++ linux-work/arch/powerpc/include/asm/dcr-native.h   2008-12-17 
>12:30:52.000000000 +1100
>@@ -23,6 +23,7 @@
> #ifndef __ASSEMBLY__
>
> #include <linux/spinlock.h>
>+#include <asm/cputable.h>
>
> typedef struct {
>       unsigned int base;
>@@ -39,23 +40,45 @@ static inline bool dcr_map_ok_native(dcr
> #define dcr_read_native(host, dcr_n)          mfdcr(dcr_n + host.base)
> #define dcr_write_native(host, dcr_n, value)  mtdcr(dcr_n + host.base, value)
>
>-/* Device Control Registers */
>-void __mtdcr(int reg, unsigned int val);
>-unsigned int __mfdcr(int reg);
>+/* Table based DCR accessors */
>+extern void __mtdcr(unsigned int reg, unsigned int val);
>+extern unsigned int __mfdcr(unsigned int reg);
>+
>+/* mfdcrx/mtdcrx instruction based accessors. We hand code
>+ * the opcodes in order not to depend on newer binutils
>+ */
>+static inline unsigned int mfdcrx(unsigned int reg)
>+{
>+      unsigned int ret;
>+      asm volatile(".long 0x7c000206 | (%0 << 21) | (%1 << 16)"
>+                   : "=r" (ret) : "r" (reg));
>+      return ret;
>+}
>+
>+static inline void mtdcrx(unsigned int reg, unsigned int val)
>+{
>+      asm volatile(".long 0x7c000306 | (%0 << 21) | (%1 << 16)"
>+                   : : "r" (val), "r" (reg));
>+}
>+
> #define mfdcr(rn)                                             \
>       ({unsigned int rval;                                    \
>-      if (__builtin_constant_p(rn))                           \
>+      if (__builtin_constant_p(rn) && rn < 1024)              \
>               asm volatile("mfdcr %0," __stringify(rn)        \
>                             : "=r" (rval));                   \
>+      else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR)))  \
>+              rval = mfdcrx(rn);                              \
>       else                                                    \
>               rval = __mfdcr(rn);                             \
>       rval;})
>
> #define mtdcr(rn, v)                                          \
> do {                                                          \
>-      if (__builtin_constant_p(rn))                           \
>+      if (__builtin_constant_p(rn) && rn < 1024)              \
>               asm volatile("mtdcr " __stringify(rn) ",%0"     \
>                             : : "r" (v));                     \
>+      else if (likely(cpu_has_feature(CPU_FTR_INDEXED_DCR)))  \
>+              mtdcrx(rn, v);                                  \
>       else                                                    \
>               __mtdcr(rn, v);                                 \
> } while (0)
>@@ -69,8 +92,13 @@ static inline unsigned __mfdcri(int base
>       unsigned int val;
>
>       spin_lock_irqsave(&dcr_ind_lock, flags);
>-      __mtdcr(base_addr, reg);
>-      val = __mfdcr(base_data);
>+      if (cpu_has_feature(CPU_FTR_INDEXED_DCR)) {
>+              mtdcrx(base_addr, reg);
>+              val = mfdcrx(base_data);
>+      } else {
>+              __mtdcr(base_addr, reg);
>+              val = __mfdcr(base_data);
>+      }
>       spin_unlock_irqrestore(&dcr_ind_lock, flags);
>       return val;
> }
>@@ -81,8 +109,13 @@ static inline void __mtdcri(int base_add
>       unsigned long flags;
>
>       spin_lock_irqsave(&dcr_ind_lock, flags);
>-      __mtdcr(base_addr, reg);
>-      __mtdcr(base_data, val);
>+      if (cpu_has_feature(CPU_FTR_INDEXED_DCR)) {
>+              mtdcrx(base_addr, reg);
>+              mtdcrx(base_data, val);
>+      } else {
>+              __mtdcr(base_addr, reg);
>+              __mtdcr(base_data, val);
>+      }
>       spin_unlock_irqrestore(&dcr_ind_lock, flags);
> }
>
>@@ -93,9 +126,15 @@ static inline void __dcri_clrset(int bas
>       unsigned int val;
>
>       spin_lock_irqsave(&dcr_ind_lock, flags);
>-      __mtdcr(base_addr, reg);
>-      val = (__mfdcr(base_data) & ~clr) | set;
>-      __mtdcr(base_data, val);
>+      if (cpu_has_feature(CPU_FTR_INDEXED_DCR)) {
>+              mtdcrx(base_addr, reg);
>+              val = (mfdcrx(base_data) & ~clr) | set;
>+              mtdcrx(base_data, val);
>+      } else {
>+              __mtdcr(base_addr, reg);
>+              val = (__mfdcr(base_data) & ~clr) | set;
>+              __mtdcr(base_data, val);
>+      }
>       spin_unlock_irqrestore(&dcr_ind_lock, flags);
> }
>
>Index: linux-work/arch/powerpc/sysdev/dcr-low.S
>===================================================================
>--- linux-work.orig/arch/powerpc/sysdev/dcr-low.S      2008-07-07 
>13:45:04.000000000 +1000
>+++ linux-work/arch/powerpc/sysdev/dcr-low.S   2008-12-17 12:30:52.000000000 
>+1100
>@@ -11,14 +11,20 @@
>
> #include <asm/ppc_asm.h>
> #include <asm/processor.h>
>+#include <asm/bug.h>
>
> #define DCR_ACCESS_PROLOG(table) \
>+      cmpli   cr0,r3,1024;     \
>       rlwinm  r3,r3,4,18,27;   \
>       lis     r5,ta...@h;      \
>       ori     r5,r5,ta...@l;   \
>       add     r3,r3,r5;        \
>+      bge-    1f;              \
>       mtctr   r3;              \
>-      bctr
>+      bctr;                    \
>+1:    trap;                    \
>+      EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0;  \
>+      blr
>
> _GLOBAL(__mfdcr)
>       DCR_ACCESS_PROLOG(__mfdcr_table)
>Index: linux-work/arch/powerpc/kernel/cputable.c
>===================================================================
>--- linux-work.orig/arch/powerpc/kernel/cputable.c     2008-12-17 
>12:28:23.000000000 +1100
>+++ linux-work/arch/powerpc/kernel/cputable.c  2008-12-17 12:30:52.000000000 
>+1100
>@@ -1509,7 +1509,7 @@ static struct cpu_spec __initdata cpu_sp
>               .pvr_mask               = 0xffff0002,
>               .pvr_value              = 0x13020002,
>               .cpu_name               = "460EX",
>-              .cpu_features           = CPU_FTRS_44X,
>+              .cpu_features           = CPU_FTRS_440x6,
>               .cpu_user_features      = COMMON_USER_BOOKE | 
> PPC_FEATURE_HAS_FPU,
>               .icache_bsize           = 32,
>               .dcache_bsize           = 32,
>@@ -1521,7 +1521,7 @@ static struct cpu_spec __initdata cpu_sp
>               .pvr_mask               = 0xffff0002,
>               .pvr_value              = 0x13020000,
>               .cpu_name               = "460GT",
>-              .cpu_features           = CPU_FTRS_44X,
>+              .cpu_features           = CPU_FTRS_440x6,
>               .cpu_user_features      = COMMON_USER_BOOKE | 
> PPC_FEATURE_HAS_FPU,
>               .icache_bsize           = 32,
>               .dcache_bsize           = 32,
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to