How to access DCR registers in powerpc440gx? Got err when use macro def in Linux kernel

4 messages, 3 authors, 2009-09-14 · open the first message on its own page

How to access DCR registers in powerpc440gx? Got err when use macro def in Linux kernel

From: g r1x <hidden>
Date: 2009-09-10 17:24:26

Now, I'm writing a DMA driver on powerpc
440gx platform(2.6.26.5), as the only way to set up DMA Controller is
to access it's dcr registers with 'mfdcr' and 'mtdcr'.

I've found some dma code in Linux kernel 2.6.26.5, so I copy the code
u wrote to my driver module directory, and include them, but when I
compile my driver, gcc complains following err messages:
--------------------------------------------------------
{standard input}: Assembler messages:
{standard input}:83: Error: unsupported relocation against dmanr
---------------------------------------------------------


code I copy from kernel 2.6.26.5 (arch/ppc/syslib/ppc4xx_dma.c)
--------------------------------------------
#include "dcr.h"
/* #inlcude <asm/dcr-native.h> */
ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS];

int ppc4xx_get_dma_status(void)
{
       return (mfdcr(DCRN_DMASR));
}


void ppc4xx_enable_dma(unsigned int dmanr)
{
      unsigned int control;
      ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];

      .........

      / * for other xfer modes, the addresses are already set */
      control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8)); <----------------err
}
void ppc4xx_set_src_addr(int dmanr, phys_addr_t src_addr)
{
       if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
               printk("set_src_addr: bad channel: %d\n", dmanr);
               return;
       }

#ifdef PPC4xx_DMA_64BIT
       mtdcr(DCRN_DMASAH0 + dmanr*2, (u32)(src_addr >> 32));
#else
       mtdcr(DCRN_DMASA0 + dmanr*2, (u32)src_addr);
#endif
}




--------------------------------------------------

DCR access micro I copied:
----------------------------------
#define mfdcr(rn) \
      ({      \
              unsigned long rval; \
              asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \
              rval; \
      })
#define mtdcr(rn, val) \
      asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val))
-----------------------------------------------------

Makefile I worte
-------------------------
obj-m := dmatest.o
dmatest-objs += dma.o core.o
KBUILD_CFLAGS += -m440 -mregnames -Wa, -booke
KBUILD_ASFAGS += -m440 -mregnames -Wa, -booke
---------

KBUILD_CFLAGS += -m440 -mregnames -Wa, -booke
KBUILD_ASFAGS += -m440 -mregnames -Wa, -booke
I add these two sentences when I read these
http://sourceware.org/ml/binutils/2004-09/msg00161.html.

When I change it to mfdcr(DCRN_DMACR0); then everything is fine. but
from the result I got when I insmod my module driver, dcr reg is not
changed.

It seems that it's the problem with gnu assembler, my GNU assembler ver is 2.17

The attachments are the c source file I copy from linux 2.6.26.5, and
I use these dma function to directly manipulate dcr registers, but
when I  make my driver module outside kernel source tree, it complains
the error I mentioned above.

Thanks!

How to access DCR registers in powerpc440gx? Got err when use macro def in Linux kernel

From: g r1x <hidden>
Date: 2009-09-11 04:14:59

Now, I'm writing a DMA driver on powerpc
440gx platform(2.6.26.5), as the only way to set up DMA Controller is
to access it's dcr registers with 'mfdcr' and 'mtdcr'.

I've found some dma code in Linux kernel 2.6.26.5, so I copy the code
u wrote to my driver module directory, and include them, but when I
compile my driver, gcc complains following err messages:
--------------------------------------------------------
{standard input}: Assembler messages:
{standard input}:83: Error: unsupported relocation against dmanr
---------------------------------------------------------


code I copy from kernel 2.6.26.5 (arch/ppc/syslib/ppc4xx_dma.c)
--------------------------------------------
#include "dcr.h"
/* #inlcude <asm/dcr-native.h> */
ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS];

int ppc4xx_get_dma_status(void)
{
      return (mfdcr(DCRN_DMASR));
}


void ppc4xx_enable_dma(unsigned int dmanr)
{
     unsigned int control;
     ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];

     .........

     / * for other xfer modes, the addresses are already set */
     control = mfdcr(DCRN_DMACR0 + (dmanr * 0x8)); <----------------err
}
void ppc4xx_set_src_addr(int dmanr, phys_addr_t src_addr)
{
      if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
              printk("set_src_addr: bad channel: %d\n", dmanr);
              return;
      }

#ifdef PPC4xx_DMA_64BIT
      mtdcr(DCRN_DMASAH0 + dmanr*2, (u32)(src_addr >> 32));
#else
      mtdcr(DCRN_DMASA0 + dmanr*2, (u32)src_addr);
#endif
}




--------------------------------------------------

DCR access micro I copied:
----------------------------------
#define mfdcr(rn) \
     ({      \
             unsigned long rval; \
             asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \
             rval; \
     })
#define mtdcr(rn, val) \
     asm volatile("mtdcr %0,%1" : : "i"(rn), "r"(val))
-----------------------------------------------------

Makefile I worte
-------------------------
obj-m := dmatest.o
dmatest-objs += dma.o core.o
KBUILD_CFLAGS += -m440 -mregnames -Wa, -booke
KBUILD_ASFAGS += -m440 -mregnames -Wa, -booke
---------

KBUILD_CFLAGS += -m440 -mregnames -Wa, -booke
KBUILD_ASFAGS += -m440 -mregnames -Wa, -booke
I add these two sentences when I read these
http://sourceware.org/ml/binutils/2004-09/msg00161.html.

When I change it to mfdcr(DCRN_DMACR0); then everything is fine. but
from the result I got when I insmod my module driver, dcr reg is not
changed.

It seems that it's the problem with gnu assembler, my GNU assembler ver is 2.17

The attachments are the c source file I copy from linux 2.6.26.5, and
I use these dma function to directly manipulate dcr registers, but
when I  make my driver module outside kernel source tree, it complains
the error I mentioned above.

Thanks!

Re: How to access DCR registers in powerpc440gx? Got err when use macro def in Linux kernel

From: David Gibson <hidden>
Date: 2009-09-11 05:31:06

On Fri, Sep 11, 2009 at 12:14:55PM +0800, g r1x wrote:
Now, I'm writing a DMA driver on powerpc
440gx platform(2.6.26.5), as the only way to set up DMA Controller is
to access it's dcr registers with 'mfdcr' and 'mtdcr'.

I've found some dma code in Linux kernel 2.6.26.5, so I copy the code
u wrote to my driver module directory, and include them, but when I
compile my driver, gcc complains following err messages:
[snip]
#define mfdcr(rn) \
     ({      \
             unsigned long rval; \
             asm volatile("mfdcr %0,%1" : "=r"(rval) : "i"(rn)); \
             rval; \
     })
This form of mfdcr macro will only work when passed a constant DCR
number.  That's a limitation in the actual CPU implementation of the
mfdcr instruction (the DCR number is part of the instruction opcode).

Some newer cores have an indirect for of mfdcr which allows the DCR
number to be specified in a register, but I don't know if 440gx is one
of them.

In current kernels we have some DCR macros that use a big table of
pre-generated instructions in order to allow accesses to runtime
computed DCR numbers.  But either they didn't exist in 2.6.26, or they
have a different name, I don't remember.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Re: How to access DCR registers in powerpc440gx? Got err when use macro def in Linux kernel

From: Arnd Bergmann <arnd@arndb.de>
Date: 2009-09-14 13:05:02

On Friday 11 September 2009, David Gibson wrote:
On Fri, Sep 11, 2009 at 12:14:55PM +0800, g r1x wrote:
quoted
Now, I'm writing a DMA driver on powerpc
440gx platform(2.6.26.5), as the only way to set up DMA Controller is
to access it's dcr registers with 'mfdcr' and 'mtdcr'.

I've found some dma code in Linux kernel 2.6.26.5, so I copy the code
u wrote to my driver module directory, and include them, but when I
compile my driver, gcc complains following err messages:
In current kernels we have some DCR macros that use a big table of
pre-generated instructions in order to allow accesses to runtime
computed DCR numbers.  But either they didn't exist in 2.6.26, or they
have a different name, I don't remember.
The portable way to access DCRs is the API from asm/dcr.h, using dcr_map(),
dcr_read() and dcr_write().

	Arnd <><
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help