filename | src/sh4/dmac.c |
changeset | 736:a02d1475ccfd |
prev | 561:533f6b478071 |
next | 929:fd8cb0c82f5f |
author | nkeynes |
date | Sun Dec 14 07:50:48 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Setup a 'proper' stackframe in translated blocks. This doesn't affect performance noticeably, but does ensure that a) The stack is aligned correctly on OS X with no extra effort, and b) We can't mess up the stack and crash that way anymore. Replace all PUSH/POP instructions (outside of prologue/epilogue) with ESP-rel moves to stack local variables. Finally merge ia32mac and ia32abi together, since they're pretty much the same now anyway (and thereby simplifying maintenance a good deal) |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/dmac.c Tue Jan 01 05:08:38 2008 +00001.2 +++ b/src/sh4/dmac.c Sun Dec 14 07:50:48 2008 +00001.3 @@ -63,18 +63,18 @@1.4 uint32_t oldval = DMA_CONTROL(channel);1.5 int resource;1.6 MMIO_WRITE( DMAC, CHCR0 + (channel<<4), val );1.7 -1.8 +1.9 /* If TE or IE are cleared, clear the interrupt request */1.10 if( IS_CHANNEL_IRQ_ACTIVE(oldval) &&1.11 - !IS_CHANNEL_IRQ_ACTIVE(val) )1.12 - intc_clear_interrupt( INT_DMA_DMTE0+channel );1.13 -1.14 + !IS_CHANNEL_IRQ_ACTIVE(val) )1.15 + intc_clear_interrupt( INT_DMA_DMTE0+channel );1.16 +1.17 resource = CHANNEL_RESOURCE(val);1.18 if( IS_CHANNEL_ENABLED(val) ) {1.19 - if( resource >= DMARES_MEMORY_TO_MEMORY_AUTO &&1.20 - resource < DMARES_SCI_TRANSMIT_EMPTY ) {1.21 - /* Autorun */1.22 - }1.23 + if( resource >= DMARES_MEMORY_TO_MEMORY_AUTO &&1.24 + resource < DMARES_SCI_TRANSMIT_EMPTY ) {1.25 + /* Autorun */1.26 + }1.27 }1.29 /* Everything else we don't need to care about until we actually try to1.30 @@ -91,14 +91,14 @@1.31 {1.32 switch( reg ) {1.33 case DMAOR:1.34 - MMIO_WRITE( DMAC, reg, val );1.35 - break;1.36 + MMIO_WRITE( DMAC, reg, val );1.37 + break;1.38 case CHCR0: DMAC_set_control( 0, val ); break;1.39 case CHCR1: DMAC_set_control( 1, val ); break;1.40 case CHCR2: DMAC_set_control( 2, val ); break;1.41 case CHCR3: DMAC_set_control( 3, val ); break;1.42 default:1.43 - MMIO_WRITE( DMAC, reg, val );1.44 + MMIO_WRITE( DMAC, reg, val );1.45 }1.46 }1.48 @@ -118,46 +118,46 @@1.49 uint32_t control = DMA_CONTROL(channel);1.51 if( IS_CHANNEL_ENABLED(control) ) {1.52 - uint32_t source = DMA_SOURCE(channel);1.53 - uint32_t dest = DMA_DEST(channel);1.54 - uint32_t count = DMA_COUNT( channel );1.55 - if( count == 0 )1.56 - count = 0x01000000;1.57 - if( run_count == 0 || run_count > count )1.58 - run_count = count;1.59 - uint32_t xfersize = DMAC_xfer_size[ (control >> 4)&0x07 ];1.60 - int source_step, dest_step;1.61 - int resource = (control >> 8) & 0x0F;1.62 - switch( (control >> 14) & 0x03 ) {1.63 - case 0: dest_step = 0; break;1.64 - case 1: dest_step = xfersize; break;1.65 - case 2: dest_step = -xfersize; break;1.66 - case 3: dest_step = 0; break; /* Illegal */1.67 - }1.68 - switch( (control >> 12) & 0x03 ) {1.69 - case 0: source_step = 0; break;1.70 - case 1: source_step = xfersize; break;1.71 - case 2: source_step = -xfersize; break;1.72 - case 3: source_step = 0; break; /* Illegal */1.73 - }1.74 -1.75 - while( run_count > 0 ) {1.76 - /* Origin */1.77 - if( (resource & 0x02) == 0 ) {1.78 - /* Source is a normal memory address */1.79 -1.80 - } else {1.81 - /* Device */1.82 - }1.83 -1.84 - /* Destination */1.85 - if( (resource & 0x01) == 0 ) {1.86 - /* Destination is a normal memory address */1.87 - } else {1.88 - }1.89 - run_count--;1.90 - count--;1.91 - }1.92 + uint32_t source = DMA_SOURCE(channel);1.93 + uint32_t dest = DMA_DEST(channel);1.94 + uint32_t count = DMA_COUNT( channel );1.95 + if( count == 0 )1.96 + count = 0x01000000;1.97 + if( run_count == 0 || run_count > count )1.98 + run_count = count;1.99 + uint32_t xfersize = DMAC_xfer_size[ (control >> 4)&0x07 ];1.100 + int source_step, dest_step;1.101 + int resource = (control >> 8) & 0x0F;1.102 + switch( (control >> 14) & 0x03 ) {1.103 + case 0: dest_step = 0; break;1.104 + case 1: dest_step = xfersize; break;1.105 + case 2: dest_step = -xfersize; break;1.106 + case 3: dest_step = 0; break; /* Illegal */1.107 + }1.108 + switch( (control >> 12) & 0x03 ) {1.109 + case 0: source_step = 0; break;1.110 + case 1: source_step = xfersize; break;1.111 + case 2: source_step = -xfersize; break;1.112 + case 3: source_step = 0; break; /* Illegal */1.113 + }1.114 +1.115 + while( run_count > 0 ) {1.116 + /* Origin */1.117 + if( (resource & 0x02) == 0 ) {1.118 + /* Source is a normal memory address */1.119 +1.120 + } else {1.121 + /* Device */1.122 + }1.123 +1.124 + /* Destination */1.125 + if( (resource & 0x01) == 0 ) {1.126 + /* Destination is a normal memory address */1.127 + } else {1.128 + }1.129 + run_count--;1.130 + count--;1.131 + }1.132 }1.133 #endif1.134 }1.135 @@ -177,14 +177,14 @@1.136 char tmp[32];1.138 if( !IS_CHANNEL_ENABLED(control) || !IS_DMAC_ENABLED() )1.139 - return 0;1.140 -1.141 + return 0;1.142 +1.143 if( ((control >> 8) & 0x0F) != DMARES_MEMORY_TO_DEVICE ) {1.144 - /* Error? */1.145 -1.146 - return 0;1.147 + /* Error? */1.148 +1.149 + return 0;1.150 }1.151 -1.152 +1.153 source = DMA_SOURCE(channel);1.154 count = DMA_COUNT(channel);1.155 if( count == 0 ) count = 0x01000000;1.156 @@ -192,33 +192,33 @@1.157 size = DMAC_xfer_size[ (control >> 4)&0x07 ];1.158 run_count = numBytes / size;1.159 if( run_count > count || run_count == 0 )1.160 - run_count = count;1.161 + run_count = count;1.163 /* Do copy - FIXME: doesn't work when crossing regions */1.164 sh4ptr_t region = mem_get_region( source );1.165 switch( (control >> 12) & 0x03 ) {1.166 case 0:1.167 - memcpy( tmp, region, size );1.168 - for( i=0; i<run_count; i++ ) {1.169 - memcpy( buf, tmp, size );1.170 - buf += size;1.171 - }1.172 - break;1.173 + memcpy( tmp, region, size );1.174 + for( i=0; i<run_count; i++ ) {1.175 + memcpy( buf, tmp, size );1.176 + buf += size;1.177 + }1.178 + break;1.179 case 1:1.180 - i = run_count * size;1.181 - memcpy( buf, region, i );1.182 - source += i;1.183 - break;1.184 + i = run_count * size;1.185 + memcpy( buf, region, i );1.186 + source += i;1.187 + break;1.188 case 2:1.189 - for( i=0; i<run_count; i++ ) {1.190 - memcpy( buf, region, size );1.191 - buf += size;1.192 - region -= size;1.193 - }1.194 - source -= (run_count * size);1.195 - break;1.196 + for( i=0; i<run_count; i++ ) {1.197 + memcpy( buf, region, size );1.198 + buf += size;1.199 + region -= size;1.200 + }1.201 + source -= (run_count * size);1.202 + break;1.203 default:1.204 - return 0; /* Illegal */1.205 + return 0; /* Illegal */1.206 }1.208 /* Update the channel registers */1.209 @@ -226,10 +226,10 @@1.210 MMIO_WRITE( DMAC, SAR0 + (channel<<4), source );1.211 MMIO_WRITE( DMAC, DMATCR0 + (channel<<4), count );1.212 if( count == 0 ) {1.213 - control |= CHCR_TE;1.214 - if( IS_CHANNEL_IRQ_ENABLED(control) )1.215 - intc_raise_interrupt( INT_DMA_DMTE0 + channel );1.216 - MMIO_WRITE( DMAC, CHCR0 + (channel<<4), control );1.217 + control |= CHCR_TE;1.218 + if( IS_CHANNEL_IRQ_ENABLED(control) )1.219 + intc_raise_interrupt( INT_DMA_DMTE0 + channel );1.220 + MMIO_WRITE( DMAC, CHCR0 + (channel<<4), control );1.221 }1.223 return run_count * size;1.224 @@ -241,13 +241,13 @@1.225 uint32_t dest, count, run_count, size, i;1.227 if( !IS_CHANNEL_ENABLED(control) || !IS_DMAC_ENABLED() )1.228 - return 0;1.229 -1.230 + return 0;1.231 +1.232 if( ((control >> 8) & 0x0F) != DMARES_DEVICE_TO_MEMORY ) {1.233 - /* Error? */1.234 - return 0;1.235 + /* Error? */1.236 + return 0;1.237 }1.238 -1.239 +1.240 dest = DMA_DEST(channel);1.241 count = DMA_COUNT(channel);1.242 if( count == 0 ) count = 0x01000000;1.243 @@ -255,33 +255,33 @@1.244 size = DMAC_xfer_size[ (control >> 4)&0x07 ];1.245 run_count = numBytes / size;1.246 if( run_count > count || run_count == 0 )1.247 - run_count = count;1.248 + run_count = count;1.250 /* Do copy - FIXME: doesn't work when crossing regions */1.251 sh4ptr_t region = mem_get_region( dest );1.252 switch( (control >> 12) & 0x03 ) {1.253 case 0:1.254 - for( i=0; i<run_count; i++ ) {1.255 - /* Doesn't make a whole lot of sense, but hey... */1.256 - memcpy( region, buf, size );1.257 - buf += size;1.258 - }1.259 - break;1.260 + for( i=0; i<run_count; i++ ) {1.261 + /* Doesn't make a whole lot of sense, but hey... */1.262 + memcpy( region, buf, size );1.263 + buf += size;1.264 + }1.265 + break;1.266 case 1:1.267 - i = run_count * size;1.268 - memcpy( region, buf, i );1.269 - dest += i;1.270 - break;1.271 + i = run_count * size;1.272 + memcpy( region, buf, i );1.273 + dest += i;1.274 + break;1.275 case 2:1.276 - for( i=0; i<run_count; i++ ) {1.277 - memcpy( region, buf, size );1.278 - buf += size;1.279 - region -= size;1.280 - }1.281 - dest -= (run_count * size);1.282 - break;1.283 + for( i=0; i<run_count; i++ ) {1.284 + memcpy( region, buf, size );1.285 + buf += size;1.286 + region -= size;1.287 + }1.288 + dest -= (run_count * size);1.289 + break;1.290 default:1.291 - return 0; /* Illegal */1.292 + return 0; /* Illegal */1.293 }1.295 /* Update the channel registers */1.296 @@ -289,10 +289,10 @@1.297 MMIO_WRITE( DMAC, DAR0 + (channel<<4), dest );1.298 MMIO_WRITE( DMAC, DMATCR0 + (channel<<4), count );1.299 if( count == 0 ) {1.300 - control |= CHCR_TE;1.301 - if( IS_CHANNEL_IRQ_ENABLED(control) )1.302 - intc_raise_interrupt( INT_DMA_DMTE0 + channel );1.303 - MMIO_WRITE( DMAC, CHCR0 + (channel<<4), control );1.304 + control |= CHCR_TE;1.305 + if( IS_CHANNEL_IRQ_ENABLED(control) )1.306 + intc_raise_interrupt( INT_DMA_DMTE0 + channel );1.307 + MMIO_WRITE( DMAC, CHCR0 + (channel<<4), control );1.308 }1.309 return run_count * size;1.310 }1.311 @@ -316,37 +316,37 @@1.312 {1.313 int i;1.314 if( !IS_DMAC_ENABLED() )1.315 - return;1.316 + return;1.317 for( i=0; i<4; i++ ) {1.318 - uint32_t control = DMA_CONTROL(i);1.319 - if( IS_CHANNEL_ENABLED(control) ) {1.320 - uint32_t channel_res = CHANNEL_RESOURCE(control);1.321 - switch( resource ) {1.322 - case DMAC_EXTERNAL:1.323 - if( channel_res == DMARES_MEMORY_TO_MEMORY )1.324 - DMAC_run_channel(i,1);1.325 - break;1.326 - case DMAC_SCI_TDE:1.327 - if( channel_res == DMARES_SCI_TRANSMIT_EMPTY )1.328 - DMAC_run_channel(i,1);1.329 - break;1.330 - case DMAC_SCI_RDF:1.331 - if( channel_res == DMARES_SCI_RECEIVE_FULL )1.332 - DMAC_run_channel(i,1);1.333 - break;1.334 - case DMAC_SCIF_TDE:1.335 - if( channel_res == DMARES_SCIF_TRANSMIT_EMPTY )1.336 - DMAC_run_channel(i,1);1.337 - break;1.338 - case DMAC_SCIF_RDF:1.339 - if( channel_res == DMARES_SCIF_RECEIVE_FULL )1.340 - DMAC_run_channel(i,1);1.341 - break;1.342 - case DMAC_TMU_ICI:1.343 - if( channel_res >= DMARES_MEMORY_TO_MEMORY_TMU )1.344 - DMAC_run_channel(i,1);1.345 - break;1.346 - }1.347 - }1.348 + uint32_t control = DMA_CONTROL(i);1.349 + if( IS_CHANNEL_ENABLED(control) ) {1.350 + uint32_t channel_res = CHANNEL_RESOURCE(control);1.351 + switch( resource ) {1.352 + case DMAC_EXTERNAL:1.353 + if( channel_res == DMARES_MEMORY_TO_MEMORY )1.354 + DMAC_run_channel(i,1);1.355 + break;1.356 + case DMAC_SCI_TDE:1.357 + if( channel_res == DMARES_SCI_TRANSMIT_EMPTY )1.358 + DMAC_run_channel(i,1);1.359 + break;1.360 + case DMAC_SCI_RDF:1.361 + if( channel_res == DMARES_SCI_RECEIVE_FULL )1.362 + DMAC_run_channel(i,1);1.363 + break;1.364 + case DMAC_SCIF_TDE:1.365 + if( channel_res == DMARES_SCIF_TRANSMIT_EMPTY )1.366 + DMAC_run_channel(i,1);1.367 + break;1.368 + case DMAC_SCIF_RDF:1.369 + if( channel_res == DMARES_SCIF_RECEIVE_FULL )1.370 + DMAC_run_channel(i,1);1.371 + break;1.372 + case DMAC_TMU_ICI:1.373 + if( channel_res >= DMARES_MEMORY_TO_MEMORY_TMU )1.374 + DMAC_run_channel(i,1);1.375 + break;1.376 + }1.377 + }1.378 }1.379 }
.