Search
lxdream.org :: lxdream/src/sh4/timer.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/timer.c
changeset 736:a02d1475ccfd
prev619:0800a0137472
next859:b941c703ccd6
author nkeynes
date Sat Aug 09 07:39:47 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Fix ITLB lookup ASID behaviour (was somewhat back-to-front)
file annotate diff log raw
1.1 --- a/src/sh4/timer.c Wed Jan 30 09:38:24 2008 +0000
1.2 +++ b/src/sh4/timer.c Sat Aug 09 07:39:47 2008 +0000
1.3 @@ -55,23 +55,23 @@
1.4 uint32_t div;
1.5 switch( reg ) {
1.6 case FRQCR: /* Frequency control */
1.7 - div = ifc_divider[(val >> 6) & 0x07];
1.8 - sh4_cpu_freq = sh4_input_freq / div;
1.9 - sh4_cpu_period = sh4_cpu_multiplier * div / sh4_input_freq;
1.10 - div = ifc_divider[(val >> 3) & 0x07];
1.11 - sh4_bus_freq = sh4_input_freq / div;
1.12 - sh4_bus_period = 1000 * div / sh4_input_freq;
1.13 - div = pfc_divider[val & 0x07];
1.14 - sh4_peripheral_freq = sh4_input_freq / div;
1.15 - sh4_peripheral_period = 1000 * div / sh4_input_freq;
1.16 + div = ifc_divider[(val >> 6) & 0x07];
1.17 + sh4_cpu_freq = sh4_input_freq / div;
1.18 + sh4_cpu_period = sh4_cpu_multiplier * div / sh4_input_freq;
1.19 + div = ifc_divider[(val >> 3) & 0x07];
1.20 + sh4_bus_freq = sh4_input_freq / div;
1.21 + sh4_bus_period = 1000 * div / sh4_input_freq;
1.22 + div = pfc_divider[val & 0x07];
1.23 + sh4_peripheral_freq = sh4_input_freq / div;
1.24 + sh4_peripheral_period = 1000 * div / sh4_input_freq;
1.25
1.26 - /* Update everything that depends on the peripheral frequency */
1.27 - SCIF_update_line_speed();
1.28 - break;
1.29 + /* Update everything that depends on the peripheral frequency */
1.30 + SCIF_update_line_speed();
1.31 + break;
1.32 case WTCSR: /* Watchdog timer */
1.33 - break;
1.34 + break;
1.35 }
1.36 -
1.37 +
1.38 MMIO_WRITE( CPG, reg, val );
1.39 }
1.40
1.41 @@ -136,14 +136,14 @@
1.42 {
1.43 switch( reg ) {
1.44 case TCNT0:
1.45 - TMU_count( 0, sh4r.slice_cycle );
1.46 - break;
1.47 + TMU_count( 0, sh4r.slice_cycle );
1.48 + break;
1.49 case TCNT1:
1.50 - TMU_count( 1, sh4r.slice_cycle );
1.51 - break;
1.52 + TMU_count( 1, sh4r.slice_cycle );
1.53 + break;
1.54 case TCNT2:
1.55 - TMU_count( 2, sh4r.slice_cycle );
1.56 - break;
1.57 + TMU_count( 2, sh4r.slice_cycle );
1.58 + break;
1.59 }
1.60 return MMIO_READ( TMU, reg );
1.61 }
1.62 @@ -154,45 +154,45 @@
1.63 uint32_t oldtcr = MMIO_READ( TMU, TCR0 + (12*timer) );
1.64
1.65 if( (oldtcr & TCR_UNF) == 0 ) {
1.66 - tcr = tcr & (~TCR_UNF);
1.67 + tcr = tcr & (~TCR_UNF);
1.68 } else {
1.69 - if( ((oldtcr & TCR_UNIE) == 0) &&
1.70 - (tcr & TCR_IRQ_ACTIVE) == TCR_IRQ_ACTIVE ) {
1.71 - intc_raise_interrupt( INT_TMU_TUNI0 + timer );
1.72 - } else if( (oldtcr & TCR_UNIE) != 0 &&
1.73 - (tcr & TCR_IRQ_ACTIVE) != TCR_IRQ_ACTIVE ) {
1.74 - intc_clear_interrupt( INT_TMU_TUNI0 + timer );
1.75 - }
1.76 + if( ((oldtcr & TCR_UNIE) == 0) &&
1.77 + (tcr & TCR_IRQ_ACTIVE) == TCR_IRQ_ACTIVE ) {
1.78 + intc_raise_interrupt( INT_TMU_TUNI0 + timer );
1.79 + } else if( (oldtcr & TCR_UNIE) != 0 &&
1.80 + (tcr & TCR_IRQ_ACTIVE) != TCR_IRQ_ACTIVE ) {
1.81 + intc_clear_interrupt( INT_TMU_TUNI0 + timer );
1.82 + }
1.83 }
1.84
1.85 switch( tcr & 0x07 ) {
1.86 case 0:
1.87 - period = sh4_peripheral_period << 2 ;
1.88 - break;
1.89 + period = sh4_peripheral_period << 2 ;
1.90 + break;
1.91 case 1:
1.92 - period = sh4_peripheral_period << 4;
1.93 - break;
1.94 + period = sh4_peripheral_period << 4;
1.95 + break;
1.96 case 2:
1.97 - period = sh4_peripheral_period << 6;
1.98 - break;
1.99 + period = sh4_peripheral_period << 6;
1.100 + break;
1.101 case 3:
1.102 - period = sh4_peripheral_period << 8;
1.103 - break;
1.104 + period = sh4_peripheral_period << 8;
1.105 + break;
1.106 case 4:
1.107 - period = sh4_peripheral_period << 10;
1.108 - break;
1.109 + period = sh4_peripheral_period << 10;
1.110 + break;
1.111 case 5:
1.112 - /* Illegal value. */
1.113 - ERROR( "TMU %d period set to illegal value (5)", timer );
1.114 - period = sh4_peripheral_period << 12; /* for something to do */
1.115 - break;
1.116 + /* Illegal value. */
1.117 + ERROR( "TMU %d period set to illegal value (5)", timer );
1.118 + period = sh4_peripheral_period << 12; /* for something to do */
1.119 + break;
1.120 case 6:
1.121 - period = rtc_output_period;
1.122 - break;
1.123 + period = rtc_output_period;
1.124 + break;
1.125 case 7:
1.126 - /* External clock... Hrm? */
1.127 - period = sh4_peripheral_period; /* I dunno... */
1.128 - break;
1.129 + /* External clock... Hrm? */
1.130 + period = sh4_peripheral_period; /* I dunno... */
1.131 + break;
1.132 }
1.133 TMU_timers[timer].timer_period = period;
1.134
1.135 @@ -202,9 +202,9 @@
1.136 void TMU_schedule_timer( int timer )
1.137 {
1.138 uint64_t duration = (uint64_t)((uint32_t)(MMIO_READ( TMU, TCNT0 + 12*timer )+1)) *
1.139 - (uint64_t)TMU_timers[timer].timer_period - TMU_timers[timer].timer_remainder;
1.140 + (uint64_t)TMU_timers[timer].timer_period - TMU_timers[timer].timer_remainder;
1.141 event_schedule_long( EVENT_TMU0+timer, (uint32_t)(duration / 1000000000),
1.142 - (uint32_t)(duration % 1000000000) );
1.143 + (uint32_t)(duration % 1000000000) );
1.144 }
1.145
1.146 void TMU_start( int timer )
1.147 @@ -229,26 +229,26 @@
1.148 uint32_t TMU_count( int timer, uint32_t nanosecs )
1.149 {
1.150 uint32_t run_ns = nanosecs + TMU_timers[timer].timer_remainder -
1.151 - TMU_timers[timer].timer_run;
1.152 + TMU_timers[timer].timer_run;
1.153 TMU_timers[timer].timer_remainder =
1.154 - run_ns % TMU_timers[timer].timer_period;
1.155 + run_ns % TMU_timers[timer].timer_period;
1.156 TMU_timers[timer].timer_run = nanosecs;
1.157 uint32_t count = run_ns / TMU_timers[timer].timer_period;
1.158 uint32_t value = MMIO_READ( TMU, TCNT0 + 12*timer );
1.159 uint32_t reset = MMIO_READ( TMU, TCOR0 + 12*timer );
1.160 if( count > value ) {
1.161 - uint32_t tcr = MMIO_READ( TMU, TCR0 + 12*timer );
1.162 - tcr |= TCR_UNF;
1.163 - count -= value;
1.164 + uint32_t tcr = MMIO_READ( TMU, TCR0 + 12*timer );
1.165 + tcr |= TCR_UNF;
1.166 + count -= value;
1.167 value = reset - (count % reset) + 1;
1.168 - MMIO_WRITE( TMU, TCR0 + 12*timer, tcr );
1.169 - if( tcr & TCR_UNIE )
1.170 - intc_raise_interrupt( INT_TMU_TUNI0 + timer );
1.171 - MMIO_WRITE( TMU, TCNT0 + 12*timer, value );
1.172 - TMU_schedule_timer(timer);
1.173 + MMIO_WRITE( TMU, TCR0 + 12*timer, tcr );
1.174 + if( tcr & TCR_UNIE )
1.175 + intc_raise_interrupt( INT_TMU_TUNI0 + timer );
1.176 + MMIO_WRITE( TMU, TCNT0 + 12*timer, value );
1.177 + TMU_schedule_timer(timer);
1.178 } else {
1.179 - value -= count;
1.180 - MMIO_WRITE( TMU, TCNT0 + 12*timer, value );
1.181 + value -= count;
1.182 + MMIO_WRITE( TMU, TCNT0 + 12*timer, value );
1.183 }
1.184 return value;
1.185 }
1.186 @@ -259,45 +259,45 @@
1.187 int i;
1.188 switch( reg ) {
1.189 case TSTR:
1.190 - oldval = MMIO_READ( TMU, TSTR );
1.191 - for( i=0; i<3; i++ ) {
1.192 - uint32_t tmp = 1<<i;
1.193 - if( (oldval & tmp) != 0 && (val&tmp) == 0 )
1.194 - TMU_stop(i);
1.195 - else if( (oldval&tmp) == 0 && (val&tmp) != 0 )
1.196 - TMU_start(i);
1.197 - }
1.198 - break;
1.199 + oldval = MMIO_READ( TMU, TSTR );
1.200 + for( i=0; i<3; i++ ) {
1.201 + uint32_t tmp = 1<<i;
1.202 + if( (oldval & tmp) != 0 && (val&tmp) == 0 )
1.203 + TMU_stop(i);
1.204 + else if( (oldval&tmp) == 0 && (val&tmp) != 0 )
1.205 + TMU_start(i);
1.206 + }
1.207 + break;
1.208 case TCR0:
1.209 - TMU_set_timer_control( 0, val );
1.210 - return;
1.211 + TMU_set_timer_control( 0, val );
1.212 + return;
1.213 case TCR1:
1.214 - TMU_set_timer_control( 1, val );
1.215 - return;
1.216 + TMU_set_timer_control( 1, val );
1.217 + return;
1.218 case TCR2:
1.219 - TMU_set_timer_control( 2, val );
1.220 - return;
1.221 + TMU_set_timer_control( 2, val );
1.222 + return;
1.223 case TCNT0:
1.224 - MMIO_WRITE( TMU, reg, val );
1.225 - if( TMU_IS_RUNNING(0) ) { // reschedule
1.226 - TMU_timers[0].timer_run = sh4r.slice_cycle;
1.227 - TMU_schedule_timer( 0 );
1.228 - }
1.229 - return;
1.230 + MMIO_WRITE( TMU, reg, val );
1.231 + if( TMU_IS_RUNNING(0) ) { // reschedule
1.232 + TMU_timers[0].timer_run = sh4r.slice_cycle;
1.233 + TMU_schedule_timer( 0 );
1.234 + }
1.235 + return;
1.236 case TCNT1:
1.237 - MMIO_WRITE( TMU, reg, val );
1.238 - if( TMU_IS_RUNNING(1) ) { // reschedule
1.239 - TMU_timers[1].timer_run = sh4r.slice_cycle;
1.240 - TMU_schedule_timer( 1 );
1.241 - }
1.242 - return;
1.243 + MMIO_WRITE( TMU, reg, val );
1.244 + if( TMU_IS_RUNNING(1) ) { // reschedule
1.245 + TMU_timers[1].timer_run = sh4r.slice_cycle;
1.246 + TMU_schedule_timer( 1 );
1.247 + }
1.248 + return;
1.249 case TCNT2:
1.250 - MMIO_WRITE( TMU, reg, val );
1.251 - if( TMU_IS_RUNNING(2) ) { // reschedule
1.252 - TMU_timers[2].timer_run = sh4r.slice_cycle;
1.253 - TMU_schedule_timer( 2 );
1.254 - }
1.255 - return;
1.256 + MMIO_WRITE( TMU, reg, val );
1.257 + if( TMU_IS_RUNNING(2) ) { // reschedule
1.258 + TMU_timers[2].timer_run = sh4r.slice_cycle;
1.259 + TMU_schedule_timer( 2 );
1.260 + }
1.261 + return;
1.262 }
1.263 MMIO_WRITE( TMU, reg, val );
1.264 }
1.265 @@ -306,13 +306,13 @@
1.266 {
1.267 int tcr = MMIO_READ( TMU, TSTR );
1.268 if( tcr & 0x01 ) {
1.269 - TMU_count( 0, nanosecs );
1.270 + TMU_count( 0, nanosecs );
1.271 }
1.272 if( tcr & 0x02 ) {
1.273 - TMU_count( 1, nanosecs );
1.274 + TMU_count( 1, nanosecs );
1.275 }
1.276 if( tcr & 0x04 ) {
1.277 - TMU_count( 2, nanosecs );
1.278 + TMU_count( 2, nanosecs );
1.279 }
1.280 }
1.281
.