linux-mips
[Top] [All Lists]

ioremap() broken?

To: linux@cthulhu.engr.sgi.com
Subject: ioremap() broken?
From: geert@linux-m68k.org
Date: Mon, 14 Feb 2000 10:40:12 -0800
Sender: owner-linuxmips@oss.sgi.com
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

<Prev in Thread] Current Thread [Next in Thread>