in asm-mips/io.h we have:
extern inline void * ioremap(unsigned long offset, unsigned long size)
{
return (void *) KSEG1ADDR(offset);
}
#define readb(addr) (*(volatile unsigned char *) (0xa0000000 + (unsigned
long)(addr)))
and in asm-mips/addrspace.h:
#define KSEG1 0xa0000000
#define KSEG1ADDR(a) ((__typeof__(a))(((unsigned long)(a) &
0x1fffffff) | KSEG1))
Hence if I map physical address range 0x1fa00300-0x1fa0033f and read from it:
mapped = ioremap(0x1fa00300, 0x40); /* returns 0xbfa00300 */
data = readb(mapped+0x20);
then this fails miserably with
Unable to handle kernel paging request at virtual address 5fa00320
My questions:
1. Is it really necessary to add anything to the addr in the readb() et al.
macros? ioremap() already takes care of that.
2. If yes, isn't it better to or (`|') instead of add ('+') 0xa0000000 in the
readb() et al. macros (or to use the macro KSEG1ADDR())?
FYI, I'm trying to make the UART in the NEC Vrc-5074 hosty bridge work cleanly
with serial.c. And serial.c first ioremap()s it.
Furthermore I see problems with
#define isa_readb(a) readb(a)
since ISA I/O space is not at 0xa0000000 but at 0xa6000000 on the NEC DDB
Vrc-5074. Don't we need an offset mips_io_mem_base, like is done on most other
non-ia32 architectures (cfr. mips_io_port_base for inb() and friends)?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven ------------- Sony Software Development Center Europe (SDCE)
Geert.Uytterhoeven@sonycom.com ------------------- Sint-Stevens-Woluwestraat 55
Voice +32-2-7248632 Fax +32-2-7262686 ---------------- B-1130 Brussels, Belgium
|