diff -Nru a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile --- a/arch/ppc/syslib/Makefile Wed Jun 2 20:40:14 2004 +++ b/arch/ppc/syslib/Makefile Wed Jun 2 20:40:14 2004 @@ -72,3 +72,5 @@ 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 -Nru a/arch/ppc/syslib/dcr.S b/arch/ppc/syslib/dcr.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/syslib/dcr.S Wed Jun 2 20:40:14 2004 @@ -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 -Nru a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h --- a/include/asm-ppc/reg_booke.h Wed Jun 2 20:40:14 2004 +++ b/include/asm-ppc/reg_booke.h Wed Jun 2 20:40:14 2004 @@ -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 */