linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: David Hawkins <dwh@ovro.caltech.edu>
To: linuxppc-embedded@ozlabs.org
Subject: Yosemite/440EP why are readl()/ioread32() setup to read little-endian?
Date: Tue, 24 Jan 2006 10:08:06 -0800	[thread overview]
Message-ID: <43D66D06.9090904@ovro.caltech.edu> (raw)
In-Reply-To: <43CC3E37.4040707@softadvances.com>

Hi all,

I was writing a simple driver to test IRQ handling on the
AMCC Yosemite board. The board has an 8x2 header with several
GPIO pins, a number of which can be configured as IRQ inputs.

I plan to setup GPIO46 as output, and GPIO47 as input, and
select IRQ8 on that pin.

The GPIO46 and GPIO47 are configured via the GPIO1 registers
at 0xEF600C00. U-Boot can be used to read the register values:

=> md ef600c00 b
ef600c00: 00000000 c2000000 50080000 00000000    ........P.......
ef600c10: 00000000 00000000 00000000 3ffcfffd    ............?...
ef600c20: 00000000 00000000 00000000    ............

=> md ef600c30 6
ef600c30: 00000400 00000000 00010000 00000000    ................
ef600c40: 00000000 00000000    ........
=>

So

ef600c00  GPIO1_OR    = 00000000
ef600c04  GPIO1_TCR   = c2000000
ef600c30  GPIO1_ISR1L = 00000400

However, if I read those same registers back under Linux,
using the driver code pasted at the end of this message
I get:

# insmod yosemite_gpio.ko
- remap the GPIO registers
- remapped to address 0xD1008C00

- Read some GPIO1 registers using readl()
- GPIO1_OR    = 0x00000000
- GPIO1_TCR   = 0x000000C2
- GPIO1_ISR1L = 0x00040000

- Read some GPIO1 registers using ioread32()
- GPIO1_OR    = 0x00000000
- GPIO1_TCR   = 0x000000C2
- GPIO1_ISR1L = 0x00040000

- Read some GPIO1 registers using an integer pointer
- GPIO1_OR    = 0x00000000
- GPIO1_TCR   = 0xC2000000
- GPIO1_ISR1L = 0x00000400

readl() and ioread32() read the registers in little-endian format!

Looking at asm-ppc/io.h

  - ioread32() is just a readl()
  - line 180 (2.6.13) has readl() as in_le32()
    (the code is the same in the 2.6.15-denx kernel too)

So, this explains why the data is read in little-endian format,
but not why this was done.

If the processor was reading from the PCI bus, then sure, I
could understand why this might be used, but even then, that
should be up to the user, eg. by using cpu_to_le32 etc.

Should I just be using pointers for remapped processor
registers, and only use readl(), ioread32(), etc, on external
memory?

I know this is just a big-endian/little-endian issue, I'm
really just asking for the driver writing 'best practices'
in this regard.

Looking forward to enlightenment :)

Cheers
Dave





--------------------------driver code----------------------------

/* yosemite_gpio.c */

#include <linux/module.h>   /* kernel modules                    */
#include <asm/io.h>         /* ioremap64(), iounmap(), readl()   */

static unsigned long long base = 0x0EF600C00; // 36-bit address
static unsigned int size = 0x44;
static char *kernel;

static int __init simple_init(void)
{
	int *p;
	
	/* Get the GPIO control registers */
	printk(" - remap the GPIO registers\n");
	kernel = ioremap64(base, size);
	printk(" - remapped to address 0x%.8X\n", (int)kernel);

	printk(" - Read some GPIO1 registers using readl()\n");
	printk(" - GPIO1_OR    = 0x%.8X\n", readl(kernel));
	printk(" - GPIO1_TCR   = 0x%.8X\n", readl(kernel+0x04));
	printk(" - GPIO1_ISR1L = 0x%.8X\n", readl(kernel+0x30));

	printk(" - Read some GPIO1 registers using ioread32()\n");
	printk(" - GPIO1_OR    = 0x%.8X\n", ioread32(kernel));
	printk(" - GPIO1_TCR   = 0x%.8X\n", ioread32(kernel+0x04));
	printk(" - GPIO1_ISR1L = 0x%.8X\n", ioread32(kernel+0x30));
	
	p = (int *)kernel;
	printk(" - Read some GPIO1 registers using an integer pointer\n");
	printk(" - GPIO1_OR    = 0x%.8X\n", p[0]);
	printk(" - GPIO1_TCR   = 0x%.8X\n", p[1]);
	printk(" - GPIO1_ISR1L = 0x%.8X\n", p[12]);
	
	/* Don't load */
	iounmap(kernel);
	return -EINVAL;
	
}
module_init(simple_init);
MODULE_LICENSE("GPL");

  reply	other threads:[~2006-01-24 18:08 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-17  0:45 [Patch 3/3] Add Yellowstone Platform defconfig John Otken
2006-01-24 18:08 ` David Hawkins [this message]
2006-01-24 19:07   ` Yosemite/440EP is there a global interrupt enable mask? David Hawkins
2006-01-25 10:28     ` Stefan Roese
2006-01-25 18:30       ` David Hawkins
2006-01-25 18:55         ` Eugene Surovegin
2006-01-25 19:46           ` David Hawkins
2006-01-25 20:13             ` Eugene Surovegin
2006-01-25 20:34               ` David Hawkins
2006-01-25  9:57   ` Yosemite/440EP why are readl()/ioread32() setup to read little-endian? Stefan Roese
2006-01-25 18:26     ` David Hawkins
2006-01-25 18:51       ` Eugene Surovegin
2006-01-25 19:36         ` David Hawkins
2006-01-25 19:48           ` Eugene Surovegin
2006-01-26 10:20           ` Stefan Roese
2006-01-27  0:10             ` David Hawkins
2006-01-27 23:29             ` David Hawkins

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=43D66D06.9090904@ovro.caltech.edu \
    --to=dwh@ovro.caltech.edu \
    --cc=linuxppc-embedded@ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).