>>[quick Q: is there any way to access physical memory locations,
>>specifically the GPIO registers, from userspace on SA-linux ? mmap(2) or
>>read(2) from either /dev/mem or /dev/kmem don't seem to work]
>
>Mmap'ing /dev/mem ought to give you access to physical memory and is
>probably the right way to do this.  I can't think of any reason why it
>shouldn't work on the SA-1100 offhand.

Theory: The SA-1100 doesn't like cache line reads from the internal control
registers.

I wrote a small app[1] that memmaps a page and tries to read the first
longword. It works as expected for all areas *except* the space between
0x8000 0000 and 0xBFFF FFFF. That's where the internal control registers of
the SA live; if I point my app there, the mmap(2) will succeed but reading
the data invariably yields

Internal error: External abort on linefetch: 6

My guess is that the memory is mapped cacheable, and the SA is allergic to
the ensuing line fills.

A) Does this sound plausible ?
B) Is there a way to fix this ?

>>gcc version egcs-2.91.57 19980901 (egcs-1.1 release)
>>binutils 2.9.1.0.15
>
>What version of modutils?

2.1.121.

>>Bad mode in prefetch abort handler detected: mode SVC_32
>>CPU: 0
>>pc : [<c401ca64>]    lr : [<c2800060>]
>>sp : c1635ed4  ip : c1635f2c  fp : c1635f28
>
>My best guess is that something is going wrong with the code that resolves
>branches when the module is loaded.

Anything I can do to fix/resolve that ?

JDB.

[1] Simple mmapper:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
  __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0)

#define MAP_SIZE 4096

int main(int argc, char **argv) {
    int fd;
    unsigned long *addr;
        off_t target = 0xE0000000;

        if(argc > 1)
                target = strtol(argv[1], 0, 0) & 0xFFFFF000;

    if((fd = open("/dev/mem", O_RDWR)) == -1) FATAL;
    printf("/dev/mem opened.\n"); fflush(stdout);

    /* Map one page of the always-zero memory */
    addr = (unsigned long *) mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, target);
    if(addr == (unsigned long *) -1) FATAL;
    printf("Memory mapped at address %p.\n", addr); fflush(stdout);
    printf("Value at address 0x%X (%p): 0x%X\n", target, addr, *addr);
fflush(stdout);

        if(munmap(addr, MAP_SIZE) == -1) FATAL;
    close(fd);
    return 0;
}

--
Jan-Derk Bakker, [EMAIL PROTECTED]

The lazy man's proverb:
    'There's no business like slow business !'


unsubscribe: body of `unsubscribe linux-arm' to [EMAIL PROTECTED]

Reply via email to