Endian problem when accessing internel regs on 8347

Bruce_Leonard at selinc.com Bruce_Leonard at selinc.com
Thu Jan 17 17:26:53 EST 2008


I've got an MPC8347 running the 2.6.24-rc5 kernel and I'm trying to access 
the GPIO registers.  I already have a driver that's doing related work 
(tho across PCI) and I just want to remap the internal CPU address to a 
kernal address and be able to read/write the register using an IOCTL call 
from user space.  My problem is, every accessor I try does an endian 
conversion before giving me my data.  So here's some code snipits of what 
I'm doing:

request_mem_region(0xe0000c00, 24, "my driver");  // 0xe0000c00 is the 
memory mapped location of the GPIO regs
data_ptr2 = ioremap(0xe0000c00, 24);

Then in the IOCTL function I try to read from the register.  First I 


I know that the mapping is working okay because I got the data from the 
GPIO direction register, but it's been byte swapped.  The contents of the 
register are 0xFFFFFFE7, but what my user space app gets back is 
0xE7FFFFFF.  I've tried all the varients I can find, readl(), inl(), 
in_be32(), in_le32(), even __raw_readl().  They all give me back byte 
swapped data.  I'm very confused.  Especially since I've looked at 
in_be32() and in_le32(), they're both inline assembly, and they use 
different instructions.  They can't be giving me the same results.  I'm 
sure I'm not the first person to want to access PowerPC internal registers 
through a driver.  Can anyone give me a hint what I'm doing wrong?

As an additional question related to PowerPC inline assembly, can anyone 
tell me what "%U1%X1" means in the following:

__asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync" : "=r" (ret) : 
"m" (*addr));


See 'ya!


More information about the Linuxppc-embedded mailing list