Commit b5f6a5b1 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc32: add "indirect" DCR access, pass 2

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: default avatarEugene Surovegin <ebs@ebshome.net>
Signed-off-by: default avatarMatt Porter <mporter@kernel.crashing.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 114b0865
......@@ -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
/*
* 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
......@@ -11,19 +11,24 @@
#ifndef __ASSEMBLY__
/* Device Control Registers */
#define mfdcr(rn) mfdcr_or_dflt(rn, 0)
#define mfdcr_or_dflt(rn,default_rval) \
void __mtdcr(int reg, unsigned int val);
unsigned int __mfdcr(int reg);
#define mfdcr(rn) \
({unsigned int rval; \
if (rn == 0) \
rval = default_rval; \
if (__builtin_constant_p(rn)) \
asm volatile("mfdcr %0," __stringify(rn) \
: "=r" (rval)); \
else \
asm volatile("mfdcr %0," __stringify(rn) : "=r" (rval)); \
rval = __mfdcr(rn); \
rval;})
#define mtdcr(rn, v) \
do { \
if (rn != 0) \
asm volatile("mtdcr " __stringify(rn) ",%0" : : "r" (v)); \
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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment