revision 617:476a717a54f3
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 617:476a717a54f3 |
parent | 616:527ab167712b |
child | 618:3ade50e8603c |
author | nkeynes |
date | Tue Jan 29 10:39:56 2008 +0000 (16 years ago) |
Start getting SLEEP into order
src/sh4/sh4.c | view | annotate | diff | log | ||
src/sh4/sh4core.c | view | annotate | diff | log | ||
src/sh4/sh4core.h | view | annotate | diff | log | ||
src/sh4/sh4core.in | view | annotate | diff | log | ||
src/sh4/sh4trans.c | view | annotate | diff | log | ||
src/sh4/sh4trans.h | view | annotate | diff | log | ||
src/sh4/xltcache.c | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4.c Tue Jan 29 10:38:34 2008 +00001.2 +++ b/src/sh4/sh4.c Tue Jan 29 10:39:56 2008 +00001.3 @@ -19,6 +19,7 @@1.5 #define MODULE sh4_module1.6 #include <math.h>1.7 +#include <assert.h>1.8 #include "dream.h"1.9 #include "dreamcast.h"1.10 #include "sh4/sh4core.h"1.11 @@ -26,6 +27,7 @@1.12 #include "sh4/intc.h"1.13 #include "sh4/xltcache.h"1.14 #include "sh4/sh4stat.h"1.15 +#include "sh4/sh4trans.h"1.16 #include "mem.h"1.17 #include "clock.h"1.18 #include "syscall.h"1.19 @@ -332,16 +334,80 @@1.20 *fr = sinf(angle);1.21 }1.23 +/**1.24 + * Enter sleep mode (eg by executing a SLEEP instruction).1.25 + * Sets sh4_state appropriately and ensures any stopping peripheral modules1.26 + * are up to date.1.27 + */1.28 void sh4_sleep(void)1.29 {1.30 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {1.31 sh4r.sh4_state = SH4_STATE_STANDBY;1.32 + /* Bring all running peripheral modules up to date, and then halt them. */1.33 + TMU_run_slice( sh4r.slice_cycle );1.34 + SCIF_run_slice( sh4r.slice_cycle );1.35 } else {1.36 - sh4r.sh4_state = SH4_STATE_SLEEP;1.37 + if( MMIO_READ( CPG, STBCR2 ) & 0x80 ) {1.38 + sh4r.sh4_state = SH4_STATE_DEEP_SLEEP;1.39 + /* Halt DMAC but other peripherals still running */1.40 +1.41 + } else {1.42 + sh4r.sh4_state = SH4_STATE_SLEEP;1.43 + }1.44 + }1.45 + if( sh4_xlat_is_running() ) {1.46 + sh4_translate_exit( XLAT_EXIT_SLEEP );1.47 }1.48 }1.50 /**1.51 + * Wakeup following sleep mode (IRQ or reset). Sets state back to running,1.52 + * and restarts any peripheral devices that were stopped.1.53 + */1.54 +void sh4_wakeup(void)1.55 +{1.56 + switch( sh4r.sh4_state ) {1.57 + case SH4_STATE_STANDBY:1.58 + break;1.59 + case SH4_STATE_DEEP_SLEEP:1.60 + break;1.61 + case SH4_STATE_SLEEP:1.62 + break;1.63 + }1.64 + sh4r.sh4_state = SH4_STATE_RUNNING;1.65 +}1.66 +1.67 +/**1.68 + * Run a time slice (or portion of a timeslice) while the SH4 is sleeping.1.69 + * Returns when either the SH4 wakes up (interrupt received) or the end of1.70 + * the slice is reached. Updates sh4.slice_cycle with the exit time and1.71 + * returns the same value.1.72 + */1.73 +uint32_t sh4_sleep_run_slice( uint32_t nanosecs )1.74 +{1.75 + int sleep_state = sh4r.sh4_state;1.76 + assert( sleep_state != SH4_STATE_RUNNING );1.77 + while( sh4r.event_pending < nanosecs ) {1.78 + sh4r.slice_cycle = sh4r.event_pending;1.79 + if( sh4r.event_types & PENDING_EVENT ) {1.80 + event_execute();1.81 + }1.82 + if( sh4r.event_types & PENDING_IRQ ) {1.83 + sh4_wakeup();1.84 + nanosecs = sh4r.event_pending;1.85 + break;1.86 + }1.87 + }1.88 + sh4r.slice_cycle = nanosecs;1.89 + if( sleep_state != SH4_STATE_STANDBY ) {1.90 + TMU_run_slice( nanosecs );1.91 + SCIF_run_slice( nanosecs );1.92 + }1.93 + return sh4r.slice_cycle;1.94 +}1.95 +1.96 +1.97 +/**1.98 * Compute the matrix tranform of fv given the matrix xf.1.99 * Both fv and xf are word-swapped as per the sh4r.fr banks1.100 */
2.1 --- a/src/sh4/sh4core.c Tue Jan 29 10:38:34 2008 +00002.2 +++ b/src/sh4/sh4core.c Tue Jan 29 10:39:56 2008 +00002.3 @@ -45,10 +45,7 @@2.4 sh4r.slice_cycle = 0;2.6 if( sh4r.sh4_state != SH4_STATE_RUNNING ) {2.7 - if( sh4r.event_pending < nanosecs ) {2.8 - sh4r.sh4_state = SH4_STATE_RUNNING;2.9 - sh4r.slice_cycle = sh4r.event_pending;2.10 - }2.11 + sh4_sleep_run_slice(nanosecs);2.12 }2.14 if( sh4_breakpoint_count == 0 ) {
3.1 --- a/src/sh4/sh4core.h Tue Jan 29 10:38:34 2008 +00003.2 +++ b/src/sh4/sh4core.h Tue Jan 29 10:39:56 2008 +00003.3 @@ -77,6 +77,9 @@3.4 void sh4_reset( void );3.5 void sh4_run( void );3.6 void sh4_stop( void );3.7 +uint32_t sh4_run_slice( uint32_t nanos ); // Run single timeslice using emulator3.8 +uint32_t sh4_xlat_run_slice( uint32_t nanos ); // Run single timeslice using translator3.9 +uint32_t sh4_sleep_run_slice( uint32_t nanos ); // Run single timeslice while the CPU is asleep3.11 /* SH4 peripheral module functions */3.12 void CPG_reset( void );
4.1 --- a/src/sh4/sh4core.in Tue Jan 29 10:38:34 2008 +00004.2 +++ b/src/sh4/sh4core.in Tue Jan 29 10:39:56 2008 +00004.3 @@ -45,10 +45,7 @@4.4 sh4r.slice_cycle = 0;4.6 if( sh4r.sh4_state != SH4_STATE_RUNNING ) {4.7 - if( sh4r.event_pending < nanosecs ) {4.8 - sh4r.sh4_state = SH4_STATE_RUNNING;4.9 - sh4r.slice_cycle = sh4r.event_pending;4.10 - }4.11 + sh4_sleep_run_slice(nanosecs);4.12 }4.14 if( sh4_breakpoint_count == 0 ) {
5.1 --- a/src/sh4/sh4trans.c Tue Jan 29 10:38:34 2008 +00005.2 +++ b/src/sh4/sh4trans.c Tue Jan 29 10:39:56 2008 +00005.3 @@ -42,10 +42,7 @@5.4 sh4r.slice_cycle = 0;5.6 if( sh4r.sh4_state != SH4_STATE_RUNNING ) {5.7 - if( sh4r.event_pending < nanosecs ) {5.8 - sh4r.sh4_state = SH4_STATE_RUNNING;5.9 - sh4r.slice_cycle = sh4r.event_pending;5.10 - }5.11 + sh4_sleep_run_slice(nanosecs);5.12 }5.14 switch( setjmp(xlat_jmp_buf) ) {5.15 @@ -62,6 +59,9 @@5.16 case XLAT_EXIT_SYSRESET:5.17 dreamcast_reset();5.18 break;5.19 + case XLAT_EXIT_SLEEP:5.20 + sh4_sleep_run_slice(nanosecs);5.21 + break;5.22 }5.24 xlat_running = TRUE;5.25 @@ -162,6 +162,10 @@5.26 }5.27 } while( !done );5.28 pc += (done - 2);5.29 +5.30 + // Add end-of-block recovery for post-instruction checks5.31 + sh4_translate_add_recovery( (pc - start)>>1 );5.32 +5.33 int epilogue_size = sh4_translate_end_block_size();5.34 uint32_t recovery_size = sizeof(struct xlat_recovery_record)*xlat_recovery_posn;5.35 uint32_t finalsize = xlat_output - xlat_current_block->code + epilogue_size + recovery_size;
6.1 --- a/src/sh4/sh4trans.h Tue Jan 29 10:38:34 2008 +00006.2 +++ b/src/sh4/sh4trans.h Tue Jan 29 10:39:56 2008 +00006.3 @@ -57,6 +57,11 @@6.4 #define XLAT_EXIT_SYSRESET 46.6 /**6.7 + * Translation flag - exit the current block and continue after the next IRQ.6.8 + */6.9 +#define XLAT_EXIT_SLEEP 56.10 +6.11 +/**6.12 */6.13 uint32_t sh4_xlat_run_slice( uint32_t nanosecs );
7.1 --- a/src/sh4/xltcache.c Tue Jan 29 10:38:34 2008 +00007.2 +++ b/src/sh4/xltcache.c Tue Jan 29 10:39:56 2008 +00007.3 @@ -217,7 +217,7 @@7.4 xlat_recovery_record_t records = (xlat_recovery_record_t)(&block->code[block->recover_table_offset]);7.5 uint32_t posn;7.6 if( recover_after ) {7.7 - if( records[count-1].xlat_offset <= pc_offset ) {7.8 + if( records[count-1].xlat_offset < pc_offset ) {7.9 return NULL;7.10 }7.11 for( posn=count-1; posn > 0; posn-- ) {
.