[PATCH 1/3] imx: make IMX_IO_ADDRESS assembly compatible
Uwe Kleine-König
u.kleine-koenig at pengutronix.de
Tue Mar 16 06:30:52 EDT 2010
Hi Baruch,
> > > -#define IMX_IO_ADDRESS(addr, module) \
> > > - ((void __force __iomem *) \
> > > - (((unsigned long)((addr) - (module ## _BASE_ADDR)) < module ## _SIZE) ?\
> > > - (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0))
> > > +#ifdef __ASSEMBLER__
> > > +#define IOMEM(addr,base,size,virt) ((addr) - (base) + (virt))
> > > +#else
> > > +#define IOMEM(addr,base,size,virt) \
> > > + ((void __force __iomem *) \
> > > + ((unsigned long) ((addr) - (base)) < size) ? \
> > > + (addr) - (base) + (virt) : 0)
> > > +#endif
> > > +
> > > +#define IMX_IO_ADDRESS(addr, module) \
> > > + IOMEM(addr, module ## _BASE_ADDR, module ## _SIZE, \
> > > + module ## _BASE_ADDR_VIRT)
> > hmmm, the construct used to define MX27_IO_ADDRESS et al. does only work
> > without __ASSEMBLER__ anyhow, still I think it might be at least
> > surprising that e.g.
> >
> > IOMEM(MX27_WDOG_BASE_ADDR, MX27_SAHB1_BASE_ADDR, MX27_SAHB1_SIZE, MX27_SAHB1_BASE_ADDR_VIRT)
> >
> > evaluates to 0x84102000 if __ASSEMBLER__ is defined but 0 if not.
> >
> > I tend to think we should use a different solution.
> >
> > IMHO it would be great to have a macro that maps physical to virtual
> > addresses for both assembler and C. E.g. ns9xxx has something like
> > that[1], other probably, too, but for imx it would be harder as the used
> > addresses differ and are spread over the whole address space. Some time
> > ago I found a function that would do the task, but Sascha didn't agree
> > to use it because it involved too much magic.
>
> So, what you actually suggest is to use the simple arithmetic IOMEM version
> which is assembly compatible, and remove the C only ?: error checking, as is
> being done in ns9xxx, right? Or are you suggesting to change the P2V mapping
> of the entire i.MX platform so that this error checking is not needed?
We currently need the ?: construct for the definition of
MX.._IO_ADDRESS. Maybe using it would work for assembler, too, as
there are only constants involved?
For reference: The function I found back then is:
#define io_p2v(x) (0xf4000000 + \
(((x) & 0x50000000) >> 8) + \
(((x) & 0x02000000) >> 4) + \
(((x) & 0x000fffff)))
This would introduce an injective mapping of the io space to
[0xf4000000;0xf47fffff] for mx1, mx21, mx25, mx27, mx31 and mx35.
(Skipping the chip select mappings that are (AFAIK unnecessarily)
currently used on some socs.):
mx1: 0x00200000 -> 0xf4000000
mx2[17]: 0x10000000 -> 0xf4100000
0x80000000 -> 0xf4000000
mx21: 0xdf000000 -> 0xf4700000
mx27: 0xd8000000 -> 0xf4500000
mx3[15]: 0xb8000000 -> 0xf4100000
mx{25,31,35}: 0x68000000 -> 0xf4400000
0x43f00000 -> 0xf4600000
0x53f00000 -> 0xf4700000
The upside of this approach is that it just works in C and Assembler,
but it's ugly and the mapped sections are spread over
[0xf4000000;0xf47fffff] instead of being one after another as they are
now. For mx51 this might need further adaption.
So in my order of preference the possibilities are:
1) IOMEM with ?: for Assembler, too
2) "my" io_p2v as above
3) IOMEM as you suggested
The nice thing about 1) (and 2)) is that we could just use
MX.._IO_ADDRESS in debug-macro.h.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
More information about the linux-arm-kernel
mailing list