Hi guys,
I've been looking at why the hardware accelerated Allegro doesn't work, and I've narrowed it down to a very short segment of code. This fragment is a standalone program, and I've inlined all the MMIO addresses and register numbers so it's very straightforward. The code does basically the same thing that the hardware accelerated SDL initialization code does. It's at the end of the post, for reference. On my setup, it hangs after printing "reading...", at which point it should be reading the MMSP2's status register.
I started off just opening /dev/mem, mmapping the MMSP2 blitter regs (size 0x100 at 0xe0020000), and reading the register. Since then I've added various other things the SDL code does, in case it makes some difference - it now also maps the GPIO registers, and sets the two clock bits that the SDL code sets; it also opens the framebuffer device (but doesn't do anything with it); and I added a few memory sync points just to be sure that wasn't affecting anything. None of this changes the result. It also doesn't seem to matter whether I kill the gp2xmenu before running my program.
My hardware is using firmware 2. I'd appreciate it if anyone else could compile and run this sample and say whether it terminates properly, or whether it crashes like mine does. When the crash happens, the whole device stops working - SMB shares, telnet, and all. I added the "sleep" lines to give it time to send the printouts down the telnet link before crashing.
Here's the code:
I've been looking at why the hardware accelerated Allegro doesn't work, and I've narrowed it down to a very short segment of code. This fragment is a standalone program, and I've inlined all the MMIO addresses and register numbers so it's very straightforward. The code does basically the same thing that the hardware accelerated SDL initialization code does. It's at the end of the post, for reference. On my setup, it hangs after printing "reading...", at which point it should be reading the MMSP2's status register.
I started off just opening /dev/mem, mmapping the MMSP2 blitter regs (size 0x100 at 0xe0020000), and reading the register. Since then I've added various other things the SDL code does, in case it makes some difference - it now also maps the GPIO registers, and sets the two clock bits that the SDL code sets; it also opens the framebuffer device (but doesn't do anything with it); and I added a few memory sync points just to be sure that wasn't affecting anything. None of this changes the result. It also doesn't seem to matter whether I kill the gp2xmenu before running my program.
My hardware is using firmware 2. I'd appreciate it if anyone else could compile and run this sample and say whether it terminates properly, or whether it crashes like mine does. When the crash happens, the whole device stops working - SMB shares, telnet, and all. I added the "sleep" lines to give it time to send the printouts down the telnet link before crashing.
Here's the code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int mem_fd;
char *gpio_regs;
char *mmsp2_regs;
int value;
int main(void)
{
int fb_fd = open( "/dev/fb0", O_RDWR );
if( fb_fd < 0 )
{
printf( "failed to open /dev/fb0\n" );
return -1;
}
mem_fd = open( "/dev/mem", O_RDWR );
if( mem_fd < 0 )
{
printf( "failed to open /dev/mem\n" );
return -1;
}
gpio_regs = mmap( NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, 0xc0000000 );
if( gpio_regs == MAP_FAILED )
{
printf( "gpio mmap failed\n" );
return -1;
}
mmsp2_regs = mmap( NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, 0xe0020000 );
if( mmsp2_regs == MAP_FAILED )
{
printf( "mmsp2 mmap failed\n" );
return -1;
}
printf( "setup...\n" );
sleep(1);
asm volatile ("":::"memory");
*(short*)(gpio_regs + 0x0904) |= (1 << 10);
asm volatile ("":::"memory");
*(short*)(gpio_regs + 0x090A) |= (1 << 2);
asm volatile ("":::"memory");
printf( "reading...\n" );
sleep(1);
value = *(int *)(mmsp2_regs + 0x34);
printf( "done, read %d\n", value );
sleep(1);
return 0;
}