Search
lxdream.org :: lxdream/src/dcload.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/dcload.c
changeset 209:ff67a7b9aa17
prev183:5938ecc01dc8
next422:61a0598e07ff
author nkeynes
date Mon Jan 15 08:32:09 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Break vram routines out into pvr2mem.c
Initial (untested) implementation of stride textures
Hookup YUV converter code in pvr2.c
file annotate diff log raw
1.1 --- a/src/dcload.c Thu Jul 06 22:44:39 2006 +0000
1.2 +++ b/src/dcload.c Mon Jan 15 08:32:09 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: dcload.c,v 1.5 2006-07-06 22:44:39 nkeynes Exp $
1.6 + * $Id: dcload.c,v 1.6 2006-08-07 13:18:16 nkeynes Exp $
1.7 *
1.8 * DC-load syscall implementation.
1.9 *
1.10 @@ -48,40 +48,104 @@
1.11 #define SYS_MAGIC_ADDR 0x8c004004
1.12 #define SYSCALL_ADDR 0x8c004008
1.13
1.14 -static gboolean dcload_allow_exit = FALSE;
1.15 +static gboolean dcload_allow_unsafe = FALSE;
1.16
1.17 -void dcload_set_allow_exit( gboolean allow )
1.18 +void dcload_set_allow_unsafe( gboolean allow )
1.19 {
1.20 - dcload_allow_exit = allow;
1.21 + dcload_allow_unsafe = allow;
1.22 +}
1.23 +
1.24 +#define MAX_OPEN_FDS 16
1.25 +/**
1.26 + * Mapping from emulator fd to real fd (so we can limit read/write
1.27 + * to only fds we've explicitly granted access to).
1.28 + */
1.29 +int open_fds[MAX_OPEN_FDS];
1.30 +
1.31 +int dcload_alloc_fd()
1.32 +{
1.33 + int i;
1.34 + for( i=0; i<MAX_OPEN_FDS; i++ ) {
1.35 + if( open_fds[i] == -1 ) {
1.36 + return i;
1.37 + }
1.38 + }
1.39 + return -1;
1.40 }
1.41
1.42 void dcload_syscall( uint32_t syscall_id )
1.43 {
1.44 uint32_t syscall = sh4r.r[4];
1.45 + int fd;
1.46 switch( sh4r.r[4] ) {
1.47 case SYS_READ:
1.48 - if( sh4r.r[5] == 0 ) {
1.49 + fd = sh4r.r[5];
1.50 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.51 + sh4r.r[0] = -1;
1.52 + } else {
1.53 char *buf = mem_get_region( sh4r.r[6] );
1.54 int length = sh4r.r[7];
1.55 - sh4r.r[0] = read( 0, buf, length );
1.56 + sh4r.r[0] = read( open_fds[fd], buf, length );
1.57 + }
1.58 + break;
1.59 + case SYS_WRITE:
1.60 + fd = sh4r.r[5];
1.61 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.62 + sh4r.r[0] = -1;
1.63 } else {
1.64 + char *buf = mem_get_region( sh4r.r[6] );
1.65 + int length = sh4r.r[7];
1.66 + sh4r.r[0] = write( open_fds[fd], buf, length );
1.67 + }
1.68 + break;
1.69 + case SYS_LSEEK:
1.70 + fd = sh4r.r[5];
1.71 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.72 + sh4r.r[0] = -1;
1.73 + } else {
1.74 + sh4r.r[0] = lseek( open_fds[fd], sh4r.r[6], sh4r.r[7] );
1.75 + }
1.76 + break;
1.77 +
1.78 +/* Secure access only */
1.79 + case SYS_OPEN:
1.80 + if( dcload_allow_unsafe ) {
1.81 + fd = dcload_alloc_fd();
1.82 + if( fd == -1 ) {
1.83 + sh4r.r[0] = -1;
1.84 + } else {
1.85 + char *filename = mem_get_region( sh4r.r[5] );
1.86 + int realfd = open( filename, sh4r.r[6] );
1.87 + open_fds[fd] = realfd;
1.88 + sh4r.r[0] = realfd;
1.89 + }
1.90 + } else {
1.91 + ERROR( "Denying access to local filesystem" );
1.92 sh4r.r[0] = -1;
1.93 }
1.94 break;
1.95 - case SYS_WRITE:
1.96 - if( sh4r.r[5] == 1 || sh4r.r[5] == 2 ) {
1.97 - char *buf = mem_get_region( sh4r.r[6] );
1.98 - int length = sh4r.r[7];
1.99 - sh4r.r[0] = write( sh4r.r[5], buf, length );
1.100 - } else {
1.101 - sh4r.r[0] = -1;
1.102 + case SYS_CLOSE:
1.103 + if( dcload_allow_unsafe ) {
1.104 + fd = sh4r.r[5];
1.105 + if( fd < 0 || fd >= MAX_OPEN_FDS || open_fds[fd] == -1 ) {
1.106 + sh4r.r[0] = -1;
1.107 + } else {
1.108 + if( open_fds[fd] > 2 ) {
1.109 + sh4r.r[0] = close( open_fds[fd] );
1.110 + } else {
1.111 + /* Don't actually close real fds 0-2 */
1.112 + sh4r.r[0] = 0;
1.113 + }
1.114 + open_fds[fd] = -1;
1.115 + }
1.116 }
1.117 break;
1.118 case SYS_EXIT:
1.119 - if( dcload_allow_exit )
1.120 + if( dcload_allow_unsafe ) {
1.121 exit( sh4r.r[5] );
1.122 - else
1.123 + } else {
1.124 dreamcast_stop();
1.125 + }
1.126 default:
1.127 sh4r.r[0] = -1;
1.128 }
1.129 @@ -90,6 +154,10 @@
1.130
1.131 void dcload_install()
1.132 {
1.133 + memset( &open_fds, -1, sizeof(open_fds) );
1.134 + open_fds[0] = 0;
1.135 + open_fds[1] = 1;
1.136 + open_fds[2] = 2;
1.137 syscall_add_hook_vector( 0xF0, SYSCALL_ADDR, dcload_syscall );
1.138 sh4_write_long( SYS_MAGIC_ADDR, SYS_MAGIC );
1.139 }
.