Re: Writing to a device at a known physical address



On Dec 13, 4:22 am, Juergen Beisert <jbeis...@xxxxxxxxxxxx> wrote:
Hi Janaka,



Janaka wrote:
On Dec 12, 6:51 pm, Juergen Beisert <jbeis...@xxxxxxxxxxxx> wrote:
Janaka wrote:
//Turn some GPIO Pins on
*(volatile unsigned int *)(regmap_addr + GPIO2_DATA_REG_OFFSET) =
GPIO2_FAULT_PIN | GPIO2_PROGB_PIN;
//Get some values of GPIO lines
uiGet = *(volatile unsigned int *)(regmap_addr +
GPIO2_DATA_REG_OFFSET);

As you are talking to hardware, at this point you should consider there
are architectures in the wild that do some kind of access reordering in
hardware.
For example PowerPC: In your example it will do the read access prior the
(buffered) write access (even if the compiler generates code in the other
order!). Your program would fail at least on this architecture.

So: Do not use volatile types in this way. Use the read?()/write?()
inline functions from the architecture specific part of the linux source
instead (refer include/asm-<your-arch>/io.h). Its more save, more
portable and the source is easier to read.

JB

Thanks Juergen. Anything else that I should lookout for when
accessing mmaped space ? I have come up with one HW design flaw where
some of the registers on the chip are middle-endian while others are
little-endian.
BTW I am using MPC8349 in little-endian mode with PowerPC arch type
(not PPC). And it works as expected so far. Does this re-ordering
happen with optimized compiler options or is this HW architecture
cache lining caveat ?

That's the problem. This reordering happens in hardware. So the compiler has
*no* effect on it. But I'm not sure if it happens on all PPC cores. Its
easy to understand: A read access would stop program execution, while a
write access can be done in background later while program execution
continues. This increases the execution speed when you are working with
regular RAM (with or without cache). But could crash, when there is no RAM
and hardware registers instead.
As the CPU works with the same mnemonics, it cannot differentiate if it
talks to RAM or hardware. Same is done on x86: But there are chipset
related register bits to set, that forbits reordering in *some* address
areas. Don't know if something like this also exists on PPC/PowerPC.

You need the "sync" command between all hardware access commands.
The "volatile" keeps command order in assembler in sync with your C code
and the "sync" command keeps assembler command order and execution order in
sync. Very easy ;-)

JB

This is a follow on question to the above. The program described above
is a user space program.
Of course because I'm working directly with hardware this should be
done as a driver. My question
is how do I access /dev/mem from user space? Every example driver I've
seen requires the user
space program to open the device in order to call the driver functions
on that device. But a normal
user cannot open /dev/mem. Do I need a device pointer (sort of like /
dev/modem and /dev/Stty)
that has general user access?

I'm really looking for the best way to approach this. I've never
written anything but a trivial driver and
I want this to be as efficient as possible. (Yes, I've got the Rubini
book on order....).

Thanks for any input you can give me..
.



Relevant Pages