>>[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]