6 int priorities[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
8 struct intc_sources_t {
14 #define PRIORITY(which) intc_sources[which].priority
15 #define INTCODE(which) intc_sources[which].code
17 static struct intc_sources_t intc_sources[] = {
18 { "IRQ0", 0x200, 15 }, { "IRQ1", 0x220, 14 }, { "IRQ2", 0x240, 13 },
19 { "IRQ3", 0x260, 12 }, { "IRQ4", 0x280, 11 }, { "IRQ5", 0x2A0, 10 },
20 { "IRQ6", 0x2C0, 9 }, { "IRQ7", 0x2E0, 8 }, { "IRQ8", 0x300, 7 },
21 { "IRQ9", 0x320, 6 }, { "IRQ10",0x340, 5 }, { "IRQ11",0x360, 4 },
22 { "IRQ12",0x380, 3 }, { "IRQ13",0x3A0, 2 }, { "IRQ14",0x3C0, 1 },
23 { "NMI", 0x1C0, 16 }, { "H-UDI",0x600, 0 }, { "GPIOI",0x620, 0 },
24 { "DMTE0",0x640, 0 }, { "DMTE1",0x660, 0 }, { "DMTE2",0x680, 0 },
25 { "DMTE3",0x6A0, 0 }, { "DMTAE",0x6C0, 0 }, { "TUNI0",0x400, 0 },
26 { "TUNI1",0x420, 0 }, { "TUNI2",0x440, 0 }, { "TICPI2",0x460, 0 },
27 { "RTC_ATI",0x480, 0 },{ "RTC_PRI",0x4A0, 0 },{ "RTC_CUI",0x4C0, 0 },
28 { "SCI_ERI",0x4E0, 0 },{ "SCI_RXI",0x500, 0 },{ "SCI_TXI",0x520, 0 },
29 { "SCI_TEI",0x540, 0 },
30 { "SCIF_ERI",0x700, 0 },{ "SCIF_RXI",0x720, 0 },{ "SCIF_BRI",0x740, 0 },
31 { "SCIF_TXI",0x760, 0 },
32 { "WDT_ITI",0x560, 0 },{ "RCMI",0x580, 0 }, { "ROVI",0x5A0, 0 } };
34 int intc_pending[INT_NUM_SOURCES];
35 int intc_num_pending = 0;
37 void mmio_region_INTC_write( uint32_t reg, uint32_t val )
39 /* Well it saves having to use an intermediate table... */
41 case ICR: /* care about this later */
44 PRIORITY(INT_TMU_TUNI0) = (val>>12)&0x000F;
45 PRIORITY(INT_TMU_TUNI1) = (val>>8)&0x000F;
46 PRIORITY(INT_TMU_TUNI2) =
47 PRIORITY(INT_TMU_TICPI2) = (val>>4)&0x000F;
48 PRIORITY(INT_RTC_ATI) =
49 PRIORITY(INT_RTC_PRI) =
50 PRIORITY(INT_RTC_CUI) = val&0x000F;
53 PRIORITY(INT_WDT_ITI) = (val>>12)&0x000F;
54 PRIORITY(INT_REF_RCMI) =
55 PRIORITY(INT_REF_ROVI) = (val>>8)&0x000F;
56 PRIORITY(INT_SCI_ERI) =
57 PRIORITY(INT_SCI_RXI) =
58 PRIORITY(INT_SCI_TXI) =
59 PRIORITY(INT_SCI_TEI) = (val>>4)&0x000F;
60 /* Bits 0-3 reserved */
63 PRIORITY(INT_GPIO) = (val>>12)&0x000F;
64 PRIORITY(INT_DMA_DMTE0) =
65 PRIORITY(INT_DMA_DMTE1) =
66 PRIORITY(INT_DMA_DMTE2) =
67 PRIORITY(INT_DMA_DMTE3) =
68 PRIORITY(INT_DMA_DMAE) = (val>>8)&0x000F;
69 PRIORITY(INT_SCIF_ERI) =
70 PRIORITY(INT_SCIF_RXI) =
71 PRIORITY(INT_SCIF_BRI) =
72 PRIORITY(INT_SCIF_TXI) = (val>>4)&0x000F;
73 PRIORITY(INT_HUDI) = val&0x000F;
76 MMIO_WRITE( INTC, reg, val );
79 int32_t mmio_region_INTC_read( uint32_t reg )
81 return MMIO_READ( INTC, reg );
84 /* We basically maintain a priority queue here, raise_interrupt adds an entry,
85 * accept_interrupt takes it off. At the moment this is does as a simple
86 * ordered array, on the basis that in practice there's unlikely to be more
87 * than one at a time. There are lots of ways to optimize this if it turns out
88 * to be necessary, but I'd doubt it will be...
91 void intc_raise_interrupt( int which )
95 pri = PRIORITY(which);
96 if( pri == 0 ) return; /* masked off */
98 for( i=0; i<intc_num_pending; i++ ) {
99 if( intc_pending[i] == which ) return; /* Don't queue more than once */
100 if( PRIORITY(intc_pending[i]) > pri ||
101 (PRIORITY(intc_pending[i]) == pri &&
102 intc_pending[i] < which))
105 /* i == insertion point */
106 for( j=intc_num_pending; j > i; j-- )
107 intc_pending[j] = intc_pending[j-1];
108 intc_pending[i] = which;
110 if( i == intc_num_pending && (sh4r.sr&SR_BL)==0 && SH4_INTMASK() < pri )
111 sh4r.int_pending = 1;
116 void intc_clear_interrupt( int which )
119 for( i=intc_num_pending-1; i>=0; i-- ) {
120 if( intc_pending[i] == which ) {
121 /* Shift array contents down */
122 while( i < intc_num_pending-1 ) {
123 intc_pending[i] = intc_pending[++i];
126 if( intc_num_pending == 0 )
127 sh4r.int_pending = 0;
129 sh4r.int_pending = PRIORITY(intc_pending[intc_num_pending-1]);
136 uint32_t intc_accept_interrupt( void )
138 assert(intc_num_pending > 0);
139 return INTCODE(intc_pending[intc_num_pending-1]);
142 if( intc_num_pending > 0 )
143 sh4r.int_pending = PRIORITY(intc_pending[intc_num_pending-1]);
145 sh4r.int_pending = 0;
146 return INTCODE(intc_pending[intc_num_pending]);
150 void intc_mask_changed( void )
152 if( intc_num_pending > 0 && (sh4r.sr&SR_BL)==0 &&
153 SH4_INTMASK() < PRIORITY(intc_pending[intc_num_pending-1]) )
154 sh4r.int_pending = 1;
155 else sh4r.int_pending = 0;
159 char *intc_get_interrupt_name( int code )
161 return intc_sources[code].name;
164 void intc_reset( void )
166 intc_num_pending = 0;
167 sh4r.int_pending = 0;
.