From: Matt Porter 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 Signed-off-by: Matt Porter Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc/syslib/Makefile | 2 + 25-akpm/arch/ppc/syslib/dcr.S | 41 ++++++++++++++++++++++++++++++++++++ 25-akpm/include/asm-ppc/reg_booke.h | 27 ++++++++++++++--------- 3 files changed, 59 insertions(+), 11 deletions(-) diff -puN /dev/null arch/ppc/syslib/dcr.S --- /dev/null 2003-09-15 06:40:47.000000000 -0700 +++ 25-akpm/arch/ppc/syslib/dcr.S 2004-06-03 00:02:32.314027088 -0700 @@ -0,0 +1,41 @@ +/* + * arch/ppc/syslib/dcr.S + * + * "Indirect" DCR access + * + * Copyright (c) 2004 Eugene Surovegin + * + * 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 +#include + +#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 diff -puN arch/ppc/syslib/Makefile~ppc32-add-indirect-dcr-access-pass-2 arch/ppc/syslib/Makefile --- 25/arch/ppc/syslib/Makefile~ppc32-add-indirect-dcr-access-pass-2 2004-06-03 00:02:32.309027848 -0700 +++ 25-akpm/arch/ppc/syslib/Makefile 2004-06-03 00:02:32.314027088 -0700 @@ -72,3 +72,5 @@ obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen55 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 -puN include/asm-ppc/reg_booke.h~ppc32-add-indirect-dcr-access-pass-2 include/asm-ppc/reg_booke.h --- 25/include/asm-ppc/reg_booke.h~ppc32-add-indirect-dcr-access-pass-2 2004-06-03 00:02:32.311027544 -0700 +++ 25-akpm/include/asm-ppc/reg_booke.h 2004-06-03 00:02:32.315026936 -0700 @@ -11,19 +11,24 @@ #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 */ _