Search
lxdream.org :: lxdream :: r821:4398dafeb77d
lxdream 0.9.1
released Jun 29
Download Now
changeset821:4398dafeb77d
parent820:de3af5480989
child822:6e0536758465
authornkeynes
dateWed Aug 20 11:25:46 2008 +0000 (15 years ago)
Setup the interrupt/exception vectors properly in the arm crt0
Use fully guarded memcpy_to_aica for program transfer
test/lib-arm/crt0.s
test/testaica.c
1.1 --- a/test/lib-arm/crt0.s Tue Aug 19 23:39:14 2008 +0000
1.2 +++ b/test/lib-arm/crt0.s Wed Aug 20 11:25:46 2008 +0000
1.3 @@ -5,8 +5,17 @@
1.4 .global ___exit
1.5 .global _atexit
1.6 start:
1.7 + b real_entry
1.8 + b exception_entry
1.9 + b exception_entry /* SWI - not used so jump to general exception */
1.10 + b exception_entry
1.11 + b exception_entry
1.12 + b exception_entry /* Not a vector, but if we ever get here... */
1.13 + b irq_entry
1.14 + b fiq_entry
1.15
1.16 /* Start by setting up a stack */
1.17 +real_entry:
1.18 /* Set up the stack pointer to a fixed value */
1.19 ldr r3, .LC0
1.20 mov sp, r3
1.21 @@ -18,7 +27,20 @@
1.22 However, it ensures that this simple crt0 world will not
1.23 immediately cause an overflow event: */
1.24 sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
1.25 + b .LB0
1.26
1.27 +.syscall:
1.28 + .word -1 /* Syscall # */
1.29 + .word 0 /* Arguments */
1.30 + .word 0
1.31 + .word 0
1.32 +
1.33 +irq_counter:
1.34 + .word 0
1.35 +fiq_counter:
1.36 + .word 0
1.37 +
1.38 +.LB0:
1.39 /* Zero-out the BSS segment */
1.40 mov a2, #0 /* Second arg: fill value */
1.41 mov fp, a2 /* Null frame pointer */
1.42 @@ -28,17 +50,8 @@
1.43 ldr a3, .LC2
1.44 sub a3, a3, a1 /* Third arg: length of block */
1.45 bl memset
1.46 - b .LB0
1.47 - .word 0 /* padding */
1.48 -
1.49 -.syscall:
1.50 - .word -1 /* Syscall # */
1.51 - .word 0 /* Arguments */
1.52 - .word 0
1.53 - .word 0
1.54
1.55 /* Enter main with no arguments for now */
1.56 -.LB0:
1.57 mov r0, #0 /* no arguments */
1.58 mov r1, #0 /* no argv either */
1.59 bl main
1.60 @@ -47,7 +60,26 @@
1.61
1.62 /* For Thumb, constants must be after the code since only
1.63 positive offsets are supported for PC relative addresses. */
1.64 +
1.65 +exception_entry:
1.66 + mov r13, #-2
1.67 + str r13, .syscall
1.68 +.die:
1.69 + b .die
1.70
1.71 +irq_entry:
1.72 + /* Increment IRQ counter and return */
1.73 + ldr r13, irq_counter
1.74 + add r13, r13, #1
1.75 + str r13, irq_counter
1.76 + subs r15, r14, #4
1.77 +fiq_entry:
1.78 + /* Increment FIQ counter and return */
1.79 + ldr r13, fiq_counter
1.80 + add r13, r13, #1
1.81 + str r13, fiq_counter
1.82 + subs r15, r14, #4
1.83 +
1.84 .align 0
1.85 .LC0:
1.86 .word _stack
2.1 --- a/test/testaica.c Tue Aug 19 23:39:14 2008 +0000
2.2 +++ b/test/testaica.c Wed Aug 20 11:25:46 2008 +0000
2.3 @@ -17,10 +17,13 @@
2.4 */
2.5
2.6 #include <stdio.h>
2.7 +#include <stdlib.h>
2.8 +#include <assert.h>
2.9
2.10 #include "lib.h"
2.11 +#include "dma.h"
2.12
2.13 -#define AICA_RAM_BASE 0x00800000
2.14 +#define AICA_RAM_BASE 0xA0800000
2.15
2.16 #define AICA_SYSCALL (AICA_RAM_BASE+0x30)
2.17 #define AICA_SYSCALL_ARG1 (AICA_SYSCALL+4)
2.18 @@ -53,25 +56,33 @@
2.19 {
2.20 uint32_t fd, len;
2.21 char *data;
2.22 + char *tmp;
2.23 + int rv;
2.24 +
2.25 + printf( "Got syscall: %d\n", syscall );
2.26
2.27 switch( syscall ) {
2.28 case SYS_READ:
2.29 fd = arg1;
2.30 data = (char *)(AICA_RAM_BASE + (arg2 & 0x001FFFFF));
2.31 len = arg3;
2.32 - return read( fd, data, len );
2.33 + tmp = malloc(len);
2.34 + rv = read( fd, data, len );
2.35 + if( rv >= 0 )
2.36 + memcpy_to_aica( data, tmp, rv );
2.37 + free(tmp);
2.38 + return rv;
2.39 case SYS_WRITE:
2.40 fd = arg1;
2.41 data = (char *)(AICA_RAM_BASE + (arg2 & 0x001FFFFF));
2.42 len = arg3;
2.43 - return write( fd, data, len );
2.44 - break;
2.45 - case SYS_EXIT:
2.46 - aica_disable();
2.47 - exit(arg1);
2.48 - default:
2.49 - return 0;
2.50 - }
2.51 + tmp = malloc(len);
2.52 + memcpy(tmp, data, len);
2.53 + rv = write( fd, tmp, len );
2.54 + free(tmp);
2.55 + return rv;
2.56 + }
2.57 + return 0;
2.58 }
2.59
2.60
2.61 @@ -80,23 +91,44 @@
2.62 char buf[65536] __attribute__((aligned(32)));
2.63 uint32_t aica_addr = AICA_RAM_BASE;
2.64 int len;
2.65 + int totallen = 0;
2.66
2.67 aica_disable();
2.68 /* Load ARM program from stdin and copy to ARM memory */
2.69 while( (len = read(0, buf, sizeof(buf))) > 0 ) {
2.70 - aica_dma_write( aica_addr, buf, len );
2.71 + if(memcpy_to_aica( aica_addr, buf, len ) != 0 ) {
2.72 + printf( "Failed to load program!\n" );
2.73 + return 1;
2.74 + }
2.75 aica_addr += len;
2.76 + totallen += len;
2.77 }
2.78 + printf( "Program loaded (%d bytes)\n", totallen);
2.79
2.80 /* Main loop waiting for IO commands */
2.81 aica_enable();
2.82 do {
2.83 + g2_fifo_wait();
2.84 + irq_disable();
2.85 int syscall = long_read(AICA_SYSCALL);
2.86 + irq_enable();
2.87 if( syscall != -1 ) {
2.88 - uint32_t result = do_syscall( syscall, long_read(AICA_SYSCALL_ARG1),
2.89 - long_read(AICA_SYSCALL_ARG2), long_read(AICA_SYSCALL_ARG3) );
2.90 - long_write( AICA_SYSCALL_RETURN, result );
2.91 - long_write( AICA_SYSCALL, -1 );
2.92 + if( syscall == -2 ) {
2.93 + fprintf( stderr, "ARM aborted with general exception\n" );
2.94 + return -2;
2.95 + } else if( syscall == SYS_EXIT ) {
2.96 + printf( "Exiting at ARM request\n" );
2.97 + aica_disable();
2.98 + return long_read(AICA_SYSCALL_ARG1);
2.99 + } else {
2.100 + uint32_t result = do_syscall( syscall, long_read(AICA_SYSCALL_ARG1),
2.101 + long_read(AICA_SYSCALL_ARG2), long_read(AICA_SYSCALL_ARG3) );
2.102 + g2_fifo_wait();
2.103 + irq_disable();
2.104 + long_write( AICA_SYSCALL_RETURN, result );
2.105 + long_write( AICA_SYSCALL, -1 );
2.106 + irq_enable();
2.107 + }
2.108 }
2.109 } while( 1 );
2.110 -}
2.111 \ No newline at end of file
2.112 +}
.