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");
next prev parent 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.