Linux MIPS Architecture development
 help / color / mirror / Atom feed
* how to access structured registers correctly
@ 2005-07-26  9:25 Hiroshi DOYU
  2005-07-26 19:06 ` Ralf Baechle
  0 siblings, 1 reply; 4+ messages in thread
From: Hiroshi DOYU @ 2005-07-26  9:25 UTC (permalink / raw)
  To: linux-mips

Hello experts,

I am wondering how to access registers correctly by usging structured 
register definitions in TX4938 particularly.

Some time ago, Linus told "volatile" on a data structure as described 
below,

	http://www.ussg.iu.edu/hypermail/linux/kernel/0401.0/1387.html


In tx4938, every register access is done by using "volatile" like below.

 
    include/asm-mips/tx4938/tx4938.h:
    
       313  struct tx4938_ccfg_reg {
       314          volatile unsigned long long ccfg;
                    ^^^^^^^^
       315          volatile unsigned long long crir;
       316          volatile unsigned long long pcfg;
       317          volatile unsigned long long tear;

    
    arch/mips/tx4938/toshiba_rbtx4938/setup.c:
    
       410  int __init tx4938_pciclk66_setup(void)
       411  {
       412          int pciclk;
       413  
       414          /* Assert M66EN */
       415          tx4938_ccfgptr->ccfg |= TX4938_CCFG_PCI66;
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


In order to remove "volatile" on data structure and fix the above situation, I gues, 
some functions are provided in header files:

	1. "reg_rd08(r)" family
	2. "TX4938_RD08(r)" family
	3. "readb(r)" family

Could you tell me which is suitable for this situation?

For exmaple, if #"2" is applied, the code would become like below:

    arch/mips/tx4938/toshiba_rbtx4938/setup.c:

       433  int __init tx4938_pciclk66_setup(void)
       434  {
       435          int pciclk;
       436          unsigned long long v;
       437          /* Assert M66EN */
       438          v = TX4938_RD64(&tx4938_ccfgptr->ccfg);
       439          TX4938_WR64(&tx4938_ccfgptr->ccfg, v | TX4938_CCFG_PCI66);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Any information would be appreciated.

	Hiroshi DOYU

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: how to access structured registers correctly
  2005-07-26  9:25 how to access structured registers correctly Hiroshi DOYU
@ 2005-07-26 19:06 ` Ralf Baechle
  2005-07-27  7:28   ` Dominic Sweetman
  0 siblings, 1 reply; 4+ messages in thread
From: Ralf Baechle @ 2005-07-26 19:06 UTC (permalink / raw)
  To: Hiroshi DOYU; +Cc: linux-mips

On Tue, Jul 26, 2005 at 06:25:31PM +0900, Hiroshi DOYU wrote:
> Date:	Tue, 26 Jul 2005 18:25:31 +0900
> From:	Hiroshi DOYU <Hiroshi_DOYU@montavista.co.jp>
> To:	linux-mips@linux-mips.org
> Subject: how to access structured registers correctly
> Content-Type: text/plain; charset=US-ASCII
> 
> Hello experts,
> 
> I am wondering how to access registers correctly by usging structured 
> register definitions in TX4938 particularly.
> 
> Some time ago, Linus told "volatile" on a data structure as described 
> below,
> 
> 	http://www.ussg.iu.edu/hypermail/linux/kernel/0401.0/1387.html
> 
> 
> In tx4938, every register access is done by using "volatile" like below.

Linus is right, volatile is a dangerous thing.  If you want to write
portable code there's a bunch of things that are not being taken care of
by plain C - even though in my opinion foo->somereg = 42 is more
readable than writel(somereg, 42).  Among the things the pointer to
volatile struct method doesn't catch are endianess conversion that might
be necessary on some systems, write merging, dealing with write buffers
or completly insane methods of attaching the bus such as the infamous
ISA / EISA cage that's attached to the host system through a USB
interface.

Now, how does that affect your TX4928 code?  Probably not terribly much
because you're using a SOC so the configuration of the system is fixed.

  Ralf

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: how to access structured registers correctly
  2005-07-26 19:06 ` Ralf Baechle
@ 2005-07-27  7:28   ` Dominic Sweetman
  2005-08-01  7:51     ` Ralf Baechle
  0 siblings, 1 reply; 4+ messages in thread
From: Dominic Sweetman @ 2005-07-27  7:28 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Hiroshi DOYU, linux-mips


Ralf Baechle (ralf@linux-mips.org) writes:

> > In tx4938, every register access is done by using "volatile" like below.
> 
> Linus is right, volatile is a dangerous thing.  If you want to write
> portable code there's a bunch of things that are not being taken care of
> by plain C - even though in my opinion foo->somereg = 42 is more
> readable than writel(somereg, 42).  Among the things the pointer to
> volatile struct method doesn't catch are endianess conversion that might
> be necessary on some systems, write merging, dealing with write buffers
> or completly insane methods of attaching the bus such as the infamous
> ISA / EISA cage that's attached to the host system through a USB
> interface.

Yes, this is far outside the compiler's reach.

All of which suggests that it would make sense to define a standard function
which:

o will produce just one fixed-width write cycle to the destination;

o will deliver the data ordered so that the MSB of the C value is on
  the "most significant" bit of the device's data bus, usually the
  highest numbered bit (this doesn't solve all device endianess
  issues, but it gives you a well-defined place to start solving them);

o has a variant which returns only after some indication that the
  data was delivered;

The implementation of this function can then conceal the details of
the CPU and interconnect.

Such a function should probably not be called "writel()" because that
sounds like "write long", and "long" is not a fixed-size data type,
which undermines the promises above...  Tediously, you probably need
"writei32()", "writei16()", "writei8()"...

--
Dominic Sweetman
MIPS Technologies

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: how to access structured registers correctly
  2005-07-27  7:28   ` Dominic Sweetman
@ 2005-08-01  7:51     ` Ralf Baechle
  0 siblings, 0 replies; 4+ messages in thread
From: Ralf Baechle @ 2005-08-01  7:51 UTC (permalink / raw)
  To: Dominic Sweetman; +Cc: Hiroshi DOYU, linux-mips

On Wed, Jul 27, 2005 at 08:28:38AM +0100, Dominic Sweetman wrote:

> > > In tx4938, every register access is done by using "volatile" like below.
> > 
> > Linus is right, volatile is a dangerous thing.  If you want to write
> > portable code there's a bunch of things that are not being taken care of
> > by plain C - even though in my opinion foo->somereg = 42 is more
> > readable than writel(somereg, 42).  Among the things the pointer to
> > volatile struct method doesn't catch are endianess conversion that might
> > be necessary on some systems, write merging, dealing with write buffers
> > or completly insane methods of attaching the bus such as the infamous
> > ISA / EISA cage that's attached to the host system through a USB
> > interface.
> 
> Yes, this is far outside the compiler's reach.
> 
> All of which suggests that it would make sense to define a standard function
> which:
> 
> o will produce just one fixed-width write cycle to the destination;
> 
> o will deliver the data ordered so that the MSB of the C value is on
>   the "most significant" bit of the device's data bus, usually the
>   highest numbered bit (this doesn't solve all device endianess
>   issues, but it gives you a well-defined place to start solving them);
> 
> o has a variant which returns only after some indication that the
>   data was delivered;
> 
> The implementation of this function can then conceal the details of
> the CPU and interconnect.
> 
> Such a function should probably not be called "writel()" because that
> sounds like "write long", and "long" is not a fixed-size data type,
> which undermines the promises above...  Tediously, you probably need
> "writei32()", "writei16()", "writei8()"...

Linux has a long tradition of grossly missnaming things, so readw reads
16-bit words, readl reads 32-bit words and readq 64-bit words, that is
each of them operates on just half the quantity a MIPS programmer would
expect. Same for writew, writel and writeq.  Blame the Intel guys for it ;-)

Ranting about grossly missnaming things, the DMA API calls coherent what
MIPS calls non-coherent and vice versa.  I'll stop now, birds are
whistling way to nice behind The Fruit Farm for me to write a good rant
today ;-)

There are ioread8, ioread16, ioread32, iowrite8, iowrite16, iowrite32
already except they're primarily used with I/O busses such as PCI but
that's not really an issue.

   Ralf

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-08-01  8:18 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-26  9:25 how to access structured registers correctly Hiroshi DOYU
2005-07-26 19:06 ` Ralf Baechle
2005-07-27  7:28   ` Dominic Sweetman
2005-08-01  7:51     ` Ralf Baechle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox