filename | src/sh4/intc.c |
changeset | 157:fbe03268ad8a |
prev | 114:1cc849575bc7 |
next | 265:5daf59b7f31b |
author | nkeynes |
date | Thu Jun 15 10:27:10 2006 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Add preliminary call-stack tracing ability Fix INTC state save/load/reset |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/intc.c Fri Mar 17 12:12:49 2006 +00001.2 +++ b/src/sh4/intc.c Thu Jun 15 10:27:10 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: intc.c,v 1.5 2006-03-17 12:12:49 nkeynes Exp $1.6 + * $Id: intc.c,v 1.6 2006-06-15 10:27:10 nkeynes Exp $1.7 *1.8 * SH4 onboard interrupt controller (INTC) implementation1.9 *1.10 @@ -21,36 +21,36 @@1.11 #include "sh4core.h"1.12 #include "intc.h"1.14 -int priorities[12] = {0,0,0,0,0,0,0,0,0,0,0,0};1.15 -1.16 struct intc_sources_t {1.17 char *name;1.18 uint32_t code;1.19 - int priority;1.20 -};1.21 +} intc_sources[INT_NUM_SOURCES] = {1.22 + { "IRQ0", 0x200 }, { "IRQ1", 0x220 }, { "IRQ2", 0x240 },1.23 + { "IRQ3", 0x260 }, { "IRQ4", 0x280 }, { "IRQ5", 0x2A0 },1.24 + { "IRQ6", 0x2C0 }, { "IRQ7", 0x2E0 }, { "IRQ8", 0x300 },1.25 + { "IRQ9", 0x320 }, { "IRQ10",0x340 }, { "IRQ11",0x360 },1.26 + { "IRQ12",0x380 }, { "IRQ13",0x3A0 }, { "IRQ14",0x3C0 },1.27 + { "NMI", 0x1C0 }, { "H-UDI",0x600 }, { "GPIOI",0x620 },1.28 + { "DMTE0",0x640 }, { "DMTE1",0x660 }, { "DMTE2",0x680 },1.29 + { "DMTE3",0x6A0 }, { "DMTAE",0x6C0 }, { "TUNI0",0x400 },1.30 + { "TUNI1",0x420 }, { "TUNI2",0x440 }, { "TICPI2",0x460 },1.31 + { "RTC_ATI",0x480 },{ "RTC_PRI",0x4A0 },{ "RTC_CUI",0x4C0 },1.32 + { "SCI_ERI",0x4E0 },{ "SCI_RXI",0x500 },{ "SCI_TXI",0x520 },1.33 + { "SCI_TEI",0x540 },1.34 + { "SCIF_ERI",0x700 },{ "SCIF_RXI",0x720, 0 },{ "SCIF_BRI",0x740 },1.35 + { "SCIF_TXI",0x760 },1.36 + { "WDT_ITI",0x560 },{ "RCMI",0x580 }, { "ROVI",0x5A0 } };1.38 -#define PRIORITY(which) intc_sources[which].priority1.39 +static int intc_default_priority[INT_NUM_SOURCES] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 16 };1.40 +1.41 +#define PRIORITY(which) intc_state.priority[which]1.42 #define INTCODE(which) intc_sources[which].code1.44 -static struct intc_sources_t intc_sources[] = {1.45 - { "IRQ0", 0x200, 15 }, { "IRQ1", 0x220, 14 }, { "IRQ2", 0x240, 13 },1.46 - { "IRQ3", 0x260, 12 }, { "IRQ4", 0x280, 11 }, { "IRQ5", 0x2A0, 10 },1.47 - { "IRQ6", 0x2C0, 9 }, { "IRQ7", 0x2E0, 8 }, { "IRQ8", 0x300, 7 },1.48 - { "IRQ9", 0x320, 6 }, { "IRQ10",0x340, 5 }, { "IRQ11",0x360, 4 },1.49 - { "IRQ12",0x380, 3 }, { "IRQ13",0x3A0, 2 }, { "IRQ14",0x3C0, 1 },1.50 - { "NMI", 0x1C0, 16 }, { "H-UDI",0x600, 0 }, { "GPIOI",0x620, 0 },1.51 - { "DMTE0",0x640, 0 }, { "DMTE1",0x660, 0 }, { "DMTE2",0x680, 0 },1.52 - { "DMTE3",0x6A0, 0 }, { "DMTAE",0x6C0, 0 }, { "TUNI0",0x400, 0 },1.53 - { "TUNI1",0x420, 0 }, { "TUNI2",0x440, 0 }, { "TICPI2",0x460, 0 },1.54 - { "RTC_ATI",0x480, 0 },{ "RTC_PRI",0x4A0, 0 },{ "RTC_CUI",0x4C0, 0 },1.55 - { "SCI_ERI",0x4E0, 0 },{ "SCI_RXI",0x500, 0 },{ "SCI_TXI",0x520, 0 },1.56 - { "SCI_TEI",0x540, 0 },1.57 - { "SCIF_ERI",0x700, 0 },{ "SCIF_RXI",0x720, 0 },{ "SCIF_BRI",0x740, 0 },1.58 - { "SCIF_TXI",0x760, 0 },1.59 - { "WDT_ITI",0x560, 0 },{ "RCMI",0x580, 0 }, { "ROVI",0x5A0, 0 } };1.60 -1.61 -int intc_pending[INT_NUM_SOURCES];1.62 -int intc_num_pending = 0;1.63 +static struct intc_state {1.64 + int num_pending;1.65 + int pending[INT_NUM_SOURCES];1.66 + int priority[INT_NUM_SOURCES];1.67 +} intc_state;1.69 void mmio_region_INTC_write( uint32_t reg, uint32_t val )1.70 {1.71 @@ -98,7 +98,30 @@1.72 {1.73 return MMIO_READ( INTC, reg );1.74 }1.75 -1.76 +1.77 +void INTC_reset()1.78 +{1.79 + int i;1.80 +1.81 + intc_state.num_pending = 0;1.82 + for( i=0; i<INT_NUM_SOURCES; i++ )1.83 + intc_state.priority[i] = intc_default_priority[i];1.84 + sh4r.int_pending = 0;1.85 +}1.86 +1.87 +1.88 +void INTC_save_state( FILE *f )1.89 +{1.90 + fwrite( &intc_state, sizeof(intc_state), 1, f );1.91 +}1.92 +1.93 +int INTC_load_state( FILE *f )1.94 +{1.95 + if( fread(&intc_state, sizeof(intc_state), 1, f) != 1 )1.96 + return -1;1.97 + return 0;1.98 +}1.99 +1.100 /* We basically maintain a priority queue here, raise_interrupt adds an entry,1.101 * accept_interrupt takes it off. At the moment this is does as a simple1.102 * ordered array, on the basis that in practice there's unlikely to be more1.103 @@ -113,34 +136,34 @@1.104 pri = PRIORITY(which);1.105 if( pri == 0 ) return; /* masked off */1.107 - for( i=0; i<intc_num_pending; i++ ) {1.108 - if( intc_pending[i] == which ) return; /* Don't queue more than once */1.109 - if( PRIORITY(intc_pending[i]) > pri ||1.110 - (PRIORITY(intc_pending[i]) == pri &&1.111 - intc_pending[i] < which))1.112 + for( i=0; i<intc_state.num_pending; i++ ) {1.113 + if( intc_state.pending[i] == which ) return; /* Don't queue more than once */1.114 + if( PRIORITY(intc_state.pending[i]) > pri ||1.115 + (PRIORITY(intc_state.pending[i]) == pri &&1.116 + intc_state.pending[i] < which))1.117 break;1.118 }1.119 /* i == insertion point */1.120 - for( j=intc_num_pending; j > i; j-- )1.121 - intc_pending[j] = intc_pending[j-1];1.122 - intc_pending[i] = which;1.123 + for( j=intc_state.num_pending; j > i; j-- )1.124 + intc_state.pending[j] = intc_state.pending[j-1];1.125 + intc_state.pending[i] = which;1.127 - if( i == intc_num_pending && (sh4r.sr&SR_BL)==0 && SH4_INTMASK() < pri )1.128 + if( i == intc_state.num_pending && (sh4r.sr&SR_BL)==0 && SH4_INTMASK() < pri )1.129 sh4r.int_pending = 1;1.131 - intc_num_pending++;1.132 + intc_state.num_pending++;1.133 }1.135 void intc_clear_interrupt( int which )1.136 {1.137 int i;1.138 - for( i=intc_num_pending-1; i>=0; i-- ) {1.139 - if( intc_pending[i] == which ) {1.140 + for( i=intc_state.num_pending-1; i>=0; i-- ) {1.141 + if( intc_state.pending[i] == which ) {1.142 /* Shift array contents down */1.143 - while( i < intc_num_pending-1 ) {1.144 - intc_pending[i] = intc_pending[++i];1.145 + while( i < intc_state.num_pending-1 ) {1.146 + intc_state.pending[i] = intc_state.pending[++i];1.147 }1.148 - intc_num_pending--;1.149 + intc_state.num_pending--;1.150 intc_mask_changed();1.151 break;1.152 }1.153 @@ -150,14 +173,14 @@1.155 uint32_t intc_accept_interrupt( void )1.156 {1.157 - assert(intc_num_pending > 0);1.158 - return INTCODE(intc_pending[intc_num_pending-1]);1.159 + assert(intc_state.num_pending > 0);1.160 + return INTCODE(intc_state.pending[intc_state.num_pending-1]);1.161 }1.163 void intc_mask_changed( void )1.164 {1.165 - if( intc_num_pending > 0 && (sh4r.sr&SR_BL)==0 &&1.166 - SH4_INTMASK() < PRIORITY(intc_pending[intc_num_pending-1]) )1.167 + if( intc_state.num_pending > 0 && (sh4r.sr&SR_BL)==0 &&1.168 + SH4_INTMASK() < PRIORITY(intc_state.pending[intc_state.num_pending-1]) )1.169 sh4r.int_pending = 1;1.170 else sh4r.int_pending = 0;1.171 }1.172 @@ -167,9 +190,3 @@1.173 {1.174 return intc_sources[code].name;1.175 }1.176 -1.177 -void intc_reset( void )1.178 -{1.179 - intc_num_pending = 0;1.180 - sh4r.int_pending = 0;1.181 -}
.