]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ppc32: add "indirect" DCR access, pass 2
authorAndrew Morton <akpm@osdl.org>
Thu, 3 Jun 2004 00:58:14 +0000 (17:58 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 3 Jun 2004 00:58:14 +0000 (17:58 -0700)
From: Matt Porter <mporter@kernel.crashing.org>

DCR number is encoded in mfdcr/mtdcr command itself and this prevents easy
DCR access when register number is not known on compile time.  This patch
adds __mfdcr & __mtdcr helpers which use pre-generated mfdcr/mtdcr
sequences for all possible DCR numbers.  We also use GCC extension
__builtin_constant_p to optimize cases when DCR number is in fact known
during compilation.

Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
Signed-off-by: Matt Porter <mporter@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/ppc/syslib/Makefile
arch/ppc/syslib/dcr.S [new file with mode: 0644]
include/asm-ppc/reg_booke.h

index 626b77acd7b00d83d608c065806f69b9ebcaec99..7274fbf1a79da796eb0bd89ba86ae9357926262d 100644 (file)
@@ -72,3 +72,5 @@ obj-$(CONFIG_SERIAL_TEXT_DEBUG)       += gen550_dbg.o
 endif
 obj-$(CONFIG_BOOTX_TEXT)       += btext.o
 obj-$(CONFIG_MPC10X_BRIDGE)     += mpc10x_common.o indirect_pci.o
+obj-$(CONFIG_40x)              += dcr.o
+obj-$(CONFIG_BOOKE)            += dcr.o
diff --git a/arch/ppc/syslib/dcr.S b/arch/ppc/syslib/dcr.S
new file mode 100644 (file)
index 0000000..895f102
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * arch/ppc/syslib/dcr.S
+ *
+ * "Indirect" DCR access
+ *
+ * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net>
+ *
+ * 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 <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+#define DCR_ACCESS_PROLOG(table) \
+       rlwinm  r3,r3,4,18,27;   \
+       lis     r5,table@h;      \
+       ori     r5,r5,table@l;   \
+       add     r3,r3,r5;        \
+       mtctr   r3;              \
+       bctr
+
+_GLOBAL(__mfdcr)
+       DCR_ACCESS_PROLOG(__mfdcr_table)
+
+_GLOBAL(__mtdcr)
+       DCR_ACCESS_PROLOG(__mtdcr_table)
+
+__mfdcr_table:
+       mfdcr  r3,0; blr
+__mtdcr_table:
+       mtdcr  0,r4; blr
+
+dcr     = 1
+        .rept   1023
+       mfdcr   r3,dcr; blr
+       mtdcr   dcr,r4; blr
+       dcr     = dcr + 1
+       .endr
index 2267f08d254f1e6232c7c5d1f64101f3cd27d2e0..2c688c1fd2d58e25bb84819b66d9697b6d746e51 100644 (file)
 
 #ifndef __ASSEMBLY__
 /* Device Control Registers */
-#define mfdcr(rn) mfdcr_or_dflt(rn, 0)
-#define mfdcr_or_dflt(rn,default_rval)                                 \
-       ({unsigned int rval;                                            \
-       if (rn == 0)                                                    \
-               rval = default_rval;                                    \
-       else                                                            \
-               asm volatile("mfdcr %0," __stringify(rn) : "=r" (rval)); \
+void __mtdcr(int reg, unsigned int val);
+unsigned int __mfdcr(int reg);
+#define mfdcr(rn)                                              \
+       ({unsigned int rval;                                    \
+       if (__builtin_constant_p(rn))                           \
+               asm volatile("mfdcr %0," __stringify(rn)        \
+                             : "=r" (rval));                   \
+       else                                                    \
+               rval = __mfdcr(rn);                             \
        rval;})
 
-#define mtdcr(rn, v)                                                   \
-do {                                                                   \
-       if (rn != 0)                                                    \
-               asm volatile("mtdcr " __stringify(rn) ",%0" : : "r" (v)); \
+#define mtdcr(rn, v)                                           \
+do {                                                           \
+       if (__builtin_constant_p(rn))                           \
+               asm volatile("mtdcr " __stringify(rn) ",%0"     \
+                             : : "r" (v));                     \
+       else                                                    \
+               __mtdcr(rn, v);                                 \
 } while (0)
 
 /* R/W of indirect DCRs make use of standard naming conventions for DCRs */