nkeynes@812: /** nkeynes@1022: * $Id$ nkeynes@812: * nkeynes@812: * AICA test loader nkeynes@812: * nkeynes@812: * Copyright (c) 2006 Nathan Keynes. nkeynes@812: * nkeynes@812: * This program is free software; you can redistribute it and/or modify nkeynes@812: * it under the terms of the GNU General Public License as published by nkeynes@812: * the Free Software Foundation; either version 2 of the License, or nkeynes@812: * (at your option) any later version. nkeynes@812: * nkeynes@812: * This program is distributed in the hope that it will be useful, nkeynes@812: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@812: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@812: * GNU General Public License for more details. nkeynes@812: */ nkeynes@812: nkeynes@812: #include nkeynes@821: #include nkeynes@821: #include nkeynes@812: nkeynes@812: #include "lib.h" nkeynes@821: #include "dma.h" nkeynes@812: nkeynes@821: #define AICA_RAM_BASE 0xA0800000 nkeynes@812: nkeynes@812: #define AICA_SYSCALL (AICA_RAM_BASE+0x30) nkeynes@812: #define AICA_SYSCALL_ARG1 (AICA_SYSCALL+4) nkeynes@812: #define AICA_SYSCALL_ARG2 (AICA_SYSCALL+8) nkeynes@812: #define AICA_SYSCALL_ARG3 (AICA_SYSCALL+12) nkeynes@812: #define AICA_SYSCALL_RETURN (AICA_SYSCALL+4) nkeynes@812: nkeynes@812: #define SYS_READ 0 nkeynes@812: #define SYS_WRITE 1 nkeynes@812: #define SYS_OPEN 2 nkeynes@812: #define SYS_CLOSE 3 nkeynes@812: #define SYS_CREAT 4 nkeynes@812: #define SYS_LINK 5 nkeynes@812: #define SYS_UNLINK 6 nkeynes@812: #define SYS_CHDIR 7 nkeynes@812: #define SYS_CHMOD 8 nkeynes@812: #define SYS_LSEEK 9 nkeynes@812: #define SYS_FSTAT 10 nkeynes@812: #define SYS_TIME 11 nkeynes@812: #define SYS_STAT 12 nkeynes@812: #define SYS_UTIME 13 nkeynes@812: #define SYS_ASSIGNWRKMEM 14 nkeynes@812: #define SYS_EXIT 15 nkeynes@812: #define SYS_OPENDIR 16 nkeynes@812: #define SYS_CLOSEDIR 17 nkeynes@812: #define SYS_READDIR 18 nkeynes@812: #define SYS_GETHOSTINFO 19 nkeynes@812: nkeynes@812: uint32_t do_syscall( uint32_t syscall, uint32_t arg1, uint32_t arg2, uint32_t arg3 ) nkeynes@812: { nkeynes@812: uint32_t fd, len; nkeynes@812: char *data; nkeynes@821: char *tmp; nkeynes@821: int rv; nkeynes@821: nkeynes@821: printf( "Got syscall: %d\n", syscall ); nkeynes@812: nkeynes@812: switch( syscall ) { nkeynes@812: case SYS_READ: nkeynes@812: fd = arg1; nkeynes@812: data = (char *)(AICA_RAM_BASE + (arg2 & 0x001FFFFF)); nkeynes@812: len = arg3; nkeynes@821: tmp = malloc(len); nkeynes@821: rv = read( fd, data, len ); nkeynes@821: if( rv >= 0 ) nkeynes@821: memcpy_to_aica( data, tmp, rv ); nkeynes@821: free(tmp); nkeynes@821: return rv; nkeynes@812: case SYS_WRITE: nkeynes@812: fd = arg1; nkeynes@812: data = (char *)(AICA_RAM_BASE + (arg2 & 0x001FFFFF)); nkeynes@812: len = arg3; nkeynes@821: tmp = malloc(len); nkeynes@821: memcpy(tmp, data, len); nkeynes@821: rv = write( fd, tmp, len ); nkeynes@821: free(tmp); nkeynes@821: return rv; nkeynes@821: } nkeynes@821: return 0; nkeynes@812: } nkeynes@812: nkeynes@812: nkeynes@812: int main( int argc, char *argv[] ) nkeynes@812: { nkeynes@812: char buf[65536] __attribute__((aligned(32))); nkeynes@812: uint32_t aica_addr = AICA_RAM_BASE; nkeynes@812: int len; nkeynes@821: int totallen = 0; nkeynes@812: nkeynes@812: aica_disable(); nkeynes@812: /* Load ARM program from stdin and copy to ARM memory */ nkeynes@812: while( (len = read(0, buf, sizeof(buf))) > 0 ) { nkeynes@821: if(memcpy_to_aica( aica_addr, buf, len ) != 0 ) { nkeynes@821: printf( "Failed to load program!\n" ); nkeynes@821: return 1; nkeynes@821: } nkeynes@812: aica_addr += len; nkeynes@821: totallen += len; nkeynes@812: } nkeynes@821: printf( "Program loaded (%d bytes)\n", totallen); nkeynes@812: nkeynes@812: /* Main loop waiting for IO commands */ nkeynes@812: aica_enable(); nkeynes@812: do { nkeynes@821: g2_fifo_wait(); nkeynes@821: irq_disable(); nkeynes@812: int syscall = long_read(AICA_SYSCALL); nkeynes@821: irq_enable(); nkeynes@812: if( syscall != -1 ) { nkeynes@821: if( syscall == -2 ) { nkeynes@821: fprintf( stderr, "ARM aborted with general exception\n" ); nkeynes@821: return -2; nkeynes@821: } else if( syscall == SYS_EXIT ) { nkeynes@821: printf( "Exiting at ARM request\n" ); nkeynes@821: aica_disable(); nkeynes@821: return long_read(AICA_SYSCALL_ARG1); nkeynes@821: } else { nkeynes@821: uint32_t result = do_syscall( syscall, long_read(AICA_SYSCALL_ARG1), nkeynes@821: long_read(AICA_SYSCALL_ARG2), long_read(AICA_SYSCALL_ARG3) ); nkeynes@821: g2_fifo_wait(); nkeynes@821: irq_disable(); nkeynes@821: long_write( AICA_SYSCALL_RETURN, result ); nkeynes@821: long_write( AICA_SYSCALL, -1 ); nkeynes@821: irq_enable(); nkeynes@821: } nkeynes@812: } nkeynes@812: } while( 1 ); nkeynes@821: }