Subject: Re: mfdcr/mtdcr
To: Matt Thomas <matt@3am-software.com>
From: Jachym Holecek <freza@liberouter.org>
List: port-powerpc
Date: 05/10/2006 20:34:54
> Jachym Holecek wrote:
> > [... change ({}) macro to static inline function ...]
> > Will this work given that the address parameter _needs_ to be a
> > compile-time constant? (it's encoded as immediate operand)
>=20
> Yes.

Mmm, 'static inline' version pasted below produces:

  #    create  WALNUT/assym.h
  cat /home/jh/netbsd-current/sys/arch/powerpc/ibm4xx/genassym.cf  |  /usr/=
tools/bin/nbgenassym -- /usr/tools/bin/powerpc--netbsd-gcc  -mcpu=3D403 -ms=
oft-float  -Wa,-maltivec -ffreestanding  -g -O2 -Wreturn-type -Werror -Wall=
 -Wno-main -Wno-format-zero-length -Wpointer-arith -Wmissing-prototypes -Ws=
trict-prototypes -Wreturn-type -Wswitch -Wshadow -Wcast-qual -Wwrite-string=
s -Wno-sign-compare  -fno-zero-initialized-in-bss    -D__walnut__ -Devbppc=
=3Devbppc -I.  -I/home/jh/netbsd-current/sys/arch -I/home/jh/netbsd-current=
/sys -nostdinc -DPPC_INTR_IMPL=3D"<powerpc/ibm4xx/ibm4xx_intr.h>" -DPPC_PCI=
_MACHDEP_IMPL=3D"<powerpc/ibm4xx/pci_machdep.h>" -DKERNBASE=3D"0x25000" -DT=
RAP_PANICWAIT -DEXT2FS_SYSTEM_FLAGS -DEMAC_EVENT_COUNTERS -DMAXUSERS=3D32 -=
D_KERNEL -D_KERNEL_OPT -I/home/jh/netbsd-current/sys/lib/libkern/../../../c=
ommon/lib/libc/quad -I/home/jh/netbsd-current/sys/lib/libkern/../../../comm=
on/lib/libc/string -I/home/jh/netbsd-current/sys/lib/libkern/../../../commo=
n/lib/libc/arch/powerpc/string  -I/home/jh/netbsd-current/sys/dist/ipf   > =
assym.h.tmp &&  mv -f assym.h.tmp assym.h
  powerpc/cpu.h: In function `mtdcr':
  powerpc/cpu.h:264: warning: asm operand 0 probably doesn't match constrai=
nts
  powerpc/cpu.h: In function `mfdcr':
  powerpc/cpu.h:272: warning: asm operand 1 probably doesn't match constrai=
nts

This is during test-compile of WALNUT, my toolchain is:

  $ /usr/tools/bin/powerpc--netbsd-gcc --version
  powerpc--netbsd-gcc (GCC) 3.3.3 (NetBSD nb3 20040520)
  [... FSF ...]

I'll try updating gcc later in the evening, just in case. Marking
'reg' as 'const' didn't help. Any clue?

	-- Jachym

Index: sys/arch/powerpc/include/cpu.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.47
diff -u -r1.47 cpu.h
--- sys/arch/powerpc/include/cpu.h	16 Feb 2006 20:17:14 -0000	1.47
+++ sys/arch/powerpc/include/cpu.h	10 May 2006 17:53:05 -0000
@@ -252,6 +252,28 @@
 	return (pvr);
 }
=20
+#if defined(PPC_IBM4XX) || defined(PPC_IBM403)
+/*
+ * DCR (Device Control Register) access. These have to be
+ * macros because register address is encoded as immediate
+ * operand.
+ */
+static inline void
+mtdcr(uint32_t reg, uint32_t val)
+{
+	__asm volatile("mtdcr %0,%1" : : "K"(reg), "r"(val));
+}
+
+static inline uint32_t
+mfdcr(uint32_t reg)
+{
+	uint32_t val;
+
+	__asm volatile ("mfdcr %0,%1" : "=3Dr"(val) : "K"(reg));
+	return (val);
+}
+#endif /* PPC_IBM4XX || PPC_IBM403 */
+
 /*
  * CLKF_BASEPRI is dependent on the underlying interrupt code
  * and can not be defined here.  It should be defined in