All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.