Commit 106627d0a036f9ebe523c648686b087eb8888355

Authored by balrog
1 parent 577390ff

Rework OMAP1 interrupt handling to allow multiple interrupt banks, by Lauro Ramos Venancio.

Add irq pulse shortcut, by Lauro Ramos Venancio.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3774 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 167 additions and 134 deletions
hw/irq.h
@@ -19,6 +19,12 @@ static inline void qemu_irq_lower(qemu_irq irq) @@ -19,6 +19,12 @@ static inline void qemu_irq_lower(qemu_irq irq)
19 qemu_set_irq(irq, 0); 19 qemu_set_irq(irq, 0);
20 } 20 }
21 21
  22 +static inline void qemu_irq_pulse(qemu_irq irq)
  23 +{
  24 + qemu_set_irq(irq, 1);
  25 + qemu_set_irq(irq, 0);
  26 +}
  27 +
22 /* Returns an array of N IRQs. */ 28 /* Returns an array of N IRQs. */
23 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n); 29 qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
24 30
hw/omap.c
@@ -80,71 +80,68 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr, @@ -80,71 +80,68 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
80 } 80 }
81 81
82 /* Interrupt Handlers */ 82 /* Interrupt Handlers */
83 -struct omap_intr_handler_s {  
84 - qemu_irq *pins;  
85 - qemu_irq *parent_pic;  
86 - target_phys_addr_t base;  
87 -  
88 - /* state */ 83 +struct omap_intr_handler_bank_s {
89 uint32_t irqs; 84 uint32_t irqs;
  85 + uint32_t inputs;
90 uint32_t mask; 86 uint32_t mask;
91 - uint32_t sens_edge;  
92 uint32_t fiq; 87 uint32_t fiq;
93 - int priority[32];  
94 - uint32_t new_irq_agr;  
95 - uint32_t new_fiq_agr;  
96 - int sir_irq;  
97 - int sir_fiq;  
98 - int stats[32]; 88 + uint32_t sens_edge;
  89 + unsigned char priority[32];
99 }; 90 };
100 91
101 -static void omap_inth_update(struct omap_intr_handler_s *s)  
102 -{  
103 - uint32_t irq = s->irqs & ~s->mask & ~s->fiq;  
104 - uint32_t fiq = s->irqs & ~s->mask & s->fiq; 92 +struct omap_intr_handler_s {
  93 + qemu_irq *pins;
  94 + qemu_irq parent_intr[2];
  95 + target_phys_addr_t base;
  96 + unsigned char nbanks;
105 97
106 - if (s->new_irq_agr || !irq) {  
107 - qemu_set_irq(s->parent_pic[ARM_PIC_CPU_IRQ], irq);  
108 - if (irq)  
109 - s->new_irq_agr = 0;  
110 - } 98 + /* state */
  99 + uint32_t new_agr[2];
  100 + int sir_intr[2];
  101 + struct omap_intr_handler_bank_s banks[];
  102 +};
111 103
112 - if (s->new_fiq_agr || !irq) {  
113 - qemu_set_irq(s->parent_pic[ARM_PIC_CPU_FIQ], fiq);  
114 - if (fiq)  
115 - s->new_fiq_agr = 0; 104 +static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
  105 +{
  106 + int i, j, sir_intr, p_intr, p, f;
  107 + uint32_t level;
  108 + sir_intr = 0;
  109 + p_intr = 255;
  110 +
  111 + /* Find the interrupt line with the highest dynamic priority.
  112 + * Note: 0 denotes the hightest priority.
  113 + * If all interrupts have the same priority, the default order is IRQ_N,
  114 + * IRQ_N-1,...,IRQ_0. */
  115 + for (j = 0; j < s->nbanks; ++j) {
  116 + level = s->banks[j].irqs & ~s->banks[j].mask &
  117 + (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq);
  118 + for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
  119 + level >>= f) {
  120 + p = s->banks[j].priority[i];
  121 + if (p <= p_intr) {
  122 + p_intr = p;
  123 + sir_intr = 32 * j + i;
  124 + }
  125 + f = ffs(level >> 1);
  126 + }
116 } 127 }
  128 + s->sir_intr[is_fiq] = sir_intr;
117 } 129 }
118 130
119 -static void omap_inth_sir_update(struct omap_intr_handler_s *s) 131 +static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
120 { 132 {
121 - int i, intr_irq, intr_fiq, p_irq, p_fiq, p, f;  
122 - uint32_t level = s->irqs & ~s->mask; 133 + int i;
  134 + uint32_t has_intr = 0;
123 135
124 - intr_irq = 0;  
125 - intr_fiq = 0;  
126 - p_irq = -1;  
127 - p_fiq = -1;  
128 - /* Find the interrupt line with the highest dynamic priority */  
129 - for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, level >>= f) {  
130 - p = s->priority[i];  
131 - if (s->fiq & (1 << i)) {  
132 - if (p > p_fiq) {  
133 - p_fiq = p;  
134 - intr_fiq = i;  
135 - }  
136 - } else {  
137 - if (p > p_irq) {  
138 - p_irq = p;  
139 - intr_irq = i;  
140 - }  
141 - } 136 + for (i = 0; i < s->nbanks; ++i)
  137 + has_intr |= s->banks[i].irqs & ~s->banks[i].mask &
  138 + (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);
142 139
143 - f = ffs(level >> 1); 140 + if (s->new_agr[is_fiq] && has_intr) {
  141 + s->new_agr[is_fiq] = 0;
  142 + omap_inth_sir_update(s, is_fiq);
  143 + qemu_set_irq(s->parent_intr[is_fiq], 1);
144 } 144 }
145 -  
146 - s->sir_irq = intr_irq;  
147 - s->sir_fiq = intr_fiq;  
148 } 145 }
149 146
150 #define INT_FALLING_EDGE 0 147 #define INT_FALLING_EDGE 0
@@ -155,19 +152,24 @@ static void omap_set_intr(void *opaque, int irq, int req) @@ -155,19 +152,24 @@ static void omap_set_intr(void *opaque, int irq, int req)
155 struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque; 152 struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
156 uint32_t rise; 153 uint32_t rise;
157 154
  155 + struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];
  156 + int n = irq & 31;
  157 +
158 if (req) { 158 if (req) {
159 - rise = ~ih->irqs & (1 << irq);  
160 - ih->irqs |= rise;  
161 - ih->stats[irq] += !!rise; 159 + rise = ~bank->irqs & (1 << n);
  160 + if (~bank->sens_edge & (1 << n))
  161 + rise &= ~bank->inputs & (1 << n);
  162 +
  163 + bank->inputs |= (1 << n);
  164 + if (rise) {
  165 + bank->irqs |= rise;
  166 + omap_inth_update(ih, 0);
  167 + omap_inth_update(ih, 1);
  168 + }
162 } else { 169 } else {
163 - rise = ih->sens_edge & ih->irqs & (1 << irq);  
164 - ih->irqs &= ~rise;  
165 - }  
166 -  
167 - if (rise & ~ih->mask) {  
168 - omap_inth_sir_update(ih);  
169 -  
170 - omap_inth_update(ih); 170 + rise = bank->sens_edge & bank->irqs & (1 << n);
  171 + bank->irqs &= ~rise;
  172 + bank->inputs &= ~(1 << n);
171 } 173 }
172 } 174 }
173 175
@@ -175,33 +177,32 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) @@ -175,33 +177,32 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
175 { 177 {
176 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; 178 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
177 int i, offset = addr - s->base; 179 int i, offset = addr - s->base;
  180 + int bank_no = offset >> 8;
  181 + int line_no;
  182 + struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
  183 + offset &= 0xff;
178 184
179 switch (offset) { 185 switch (offset) {
180 case 0x00: /* ITR */ 186 case 0x00: /* ITR */
181 - return s->irqs; 187 + return bank->irqs;
182 188
183 case 0x04: /* MIR */ 189 case 0x04: /* MIR */
184 - return s->mask; 190 + return bank->mask;
185 191
186 case 0x10: /* SIR_IRQ_CODE */ 192 case 0x10: /* SIR_IRQ_CODE */
187 - i = s->sir_irq;  
188 - if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {  
189 - s->irqs &= ~(1 << i);  
190 - omap_inth_sir_update(s);  
191 - omap_inth_update(s);  
192 - }  
193 - return i;  
194 -  
195 - case 0x14: /* SIR_FIQ_CODE */  
196 - i = s->sir_fiq;  
197 - if (((s->sens_edge >> i) & 1) == INT_FALLING_EDGE && i) {  
198 - s->irqs &= ~(1 << i);  
199 - omap_inth_sir_update(s);  
200 - omap_inth_update(s);  
201 - } 193 + case 0x14: /* SIR_FIQ_CODE */
  194 + if (bank_no != 0)
  195 + break;
  196 + line_no = s->sir_intr[(offset - 0x10) >> 2];
  197 + bank = &s->banks[line_no >> 5];
  198 + i = line_no & 31;
  199 + if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
  200 + bank->irqs &= ~(1 << i);
202 return i; 201 return i;
203 202
204 case 0x18: /* CONTROL_REG */ 203 case 0x18: /* CONTROL_REG */
  204 + if (bank_no != 0)
  205 + break;
205 return 0; 206 return 0;
206 207
207 case 0x1c: /* ILR0 */ 208 case 0x1c: /* ILR0 */
@@ -237,17 +238,15 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr) @@ -237,17 +238,15 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
237 case 0x94: /* ILR30 */ 238 case 0x94: /* ILR30 */
238 case 0x98: /* ILR31 */ 239 case 0x98: /* ILR31 */
239 i = (offset - 0x1c) >> 2; 240 i = (offset - 0x1c) >> 2;
240 - return (s->priority[i] << 2) |  
241 - (((s->sens_edge >> i) & 1) << 1) |  
242 - ((s->fiq >> i) & 1); 241 + return (bank->priority[i] << 2) |
  242 + (((bank->sens_edge >> i) & 1) << 1) |
  243 + ((bank->fiq >> i) & 1);
243 244
244 case 0x9c: /* ISR */ 245 case 0x9c: /* ISR */
245 return 0x00000000; 246 return 0x00000000;
246 247
247 - default:  
248 - OMAP_BAD_REG(addr);  
249 - break;  
250 } 248 }
  249 + OMAP_BAD_REG(addr);
251 return 0; 250 return 0;
252 } 251 }
253 252
@@ -256,18 +255,21 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, @@ -256,18 +255,21 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr,
256 { 255 {
257 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque; 256 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
258 int i, offset = addr - s->base; 257 int i, offset = addr - s->base;
  258 + int bank_no = offset >> 8;
  259 + struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
  260 + offset &= 0xff;
259 261
260 switch (offset) { 262 switch (offset) {
261 case 0x00: /* ITR */ 263 case 0x00: /* ITR */
262 - s->irqs &= value | 1;  
263 - omap_inth_sir_update(s);  
264 - omap_inth_update(s); 264 + /* Important: ignore the clearing if the IRQ is level-triggered and
  265 + the input bit is 1 */
  266 + bank->irqs &= value | (bank->inputs & bank->sens_edge);
265 return; 267 return;
266 268
267 case 0x04: /* MIR */ 269 case 0x04: /* MIR */
268 - s->mask = value;  
269 - omap_inth_sir_update(s);  
270 - omap_inth_update(s); 270 + bank->mask = value;
  271 + omap_inth_update(s, 0);
  272 + omap_inth_update(s, 1);
271 return; 273 return;
272 274
273 case 0x10: /* SIR_IRQ_CODE */ 275 case 0x10: /* SIR_IRQ_CODE */
@@ -276,11 +278,18 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, @@ -276,11 +278,18 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr,
276 break; 278 break;
277 279
278 case 0x18: /* CONTROL_REG */ 280 case 0x18: /* CONTROL_REG */
279 - if (value & 2)  
280 - s->new_fiq_agr = ~0;  
281 - if (value & 1)  
282 - s->new_irq_agr = ~0;  
283 - omap_inth_update(s); 281 + if (bank_no != 0)
  282 + break;
  283 + if (value & 2) {
  284 + qemu_set_irq(s->parent_intr[1], 0);
  285 + s->new_agr[1] = ~0;
  286 + omap_inth_update(s, 1);
  287 + }
  288 + if (value & 1) {
  289 + qemu_set_irq(s->parent_intr[0], 0);
  290 + s->new_agr[0] = ~0;
  291 + omap_inth_update(s, 0);
  292 + }
284 return; 293 return;
285 294
286 case 0x1c: /* ILR0 */ 295 case 0x1c: /* ILR0 */
@@ -316,24 +325,22 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr, @@ -316,24 +325,22 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr,
316 case 0x94: /* ILR30 */ 325 case 0x94: /* ILR30 */
317 case 0x98: /* ILR31 */ 326 case 0x98: /* ILR31 */
318 i = (offset - 0x1c) >> 2; 327 i = (offset - 0x1c) >> 2;
319 - s->priority[i] = (value >> 2) & 0x1f;  
320 - s->sens_edge &= ~(1 << i);  
321 - s->sens_edge |= ((value >> 1) & 1) << i;  
322 - s->fiq &= ~(1 << i);  
323 - s->fiq |= (value & 1) << i; 328 + bank->priority[i] = (value >> 2) & 0x1f;
  329 + bank->sens_edge &= ~(1 << i);
  330 + bank->sens_edge |= ((value >> 1) & 1) << i;
  331 + bank->fiq &= ~(1 << i);
  332 + bank->fiq |= (value & 1) << i;
324 return; 333 return;
325 334
326 case 0x9c: /* ISR */ 335 case 0x9c: /* ISR */
327 for (i = 0; i < 32; i ++) 336 for (i = 0; i < 32; i ++)
328 if (value & (1 << i)) { 337 if (value & (1 << i)) {
329 - omap_set_intr(s, i, 1); 338 + omap_set_intr(s, 32 * bank_no + i, 1);
330 return; 339 return;
331 } 340 }
332 return; 341 return;
333 -  
334 - default:  
335 - OMAP_BAD_REG(addr);  
336 } 342 }
  343 + OMAP_BAD_REG(addr);
337 } 344 }
338 345
339 static CPUReadMemoryFunc *omap_inth_readfn[] = { 346 static CPUReadMemoryFunc *omap_inth_readfn[] = {
@@ -348,31 +355,43 @@ static CPUWriteMemoryFunc *omap_inth_writefn[] = { @@ -348,31 +355,43 @@ static CPUWriteMemoryFunc *omap_inth_writefn[] = {
348 omap_inth_write, 355 omap_inth_write,
349 }; 356 };
350 357
351 -static void omap_inth_reset(struct omap_intr_handler_s *s) 358 +void omap_inth_reset(struct omap_intr_handler_s *s)
352 { 359 {
353 - s->irqs = 0x00000000;  
354 - s->mask = 0xffffffff;  
355 - s->sens_edge = 0x00000000;  
356 - s->fiq = 0x00000000;  
357 - memset(s->priority, 0, sizeof(s->priority));  
358 - s->new_irq_agr = ~0;  
359 - s->new_fiq_agr = ~0;  
360 - s->sir_irq = 0;  
361 - s->sir_fiq = 0; 360 + int i;
  361 +
  362 + for (i = 0; i < s->nbanks; ++i){
  363 + s->banks[i].irqs = 0x00000000;
  364 + s->banks[i].mask = 0xffffffff;
  365 + s->banks[i].sens_edge = 0x00000000;
  366 + s->banks[i].fiq = 0x00000000;
  367 + s->banks[i].inputs = 0x00000000;
  368 + memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));
  369 + }
362 370
363 - omap_inth_update(s); 371 + s->new_agr[0] = ~0;
  372 + s->new_agr[1] = ~0;
  373 + s->sir_intr[0] = 0;
  374 + s->sir_intr[1] = 0;
  375 +
  376 + qemu_set_irq(s->parent_intr[0], 0);
  377 + qemu_set_irq(s->parent_intr[1], 0);
364 } 378 }
365 379
366 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, 380 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
367 - unsigned long size, qemu_irq parent[2], omap_clk clk) 381 + unsigned long size, unsigned char nbanks,
  382 + qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
368 { 383 {
369 int iomemtype; 384 int iomemtype;
370 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) 385 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
371 - qemu_mallocz(sizeof(struct omap_intr_handler_s)); 386 + qemu_mallocz(sizeof(struct omap_intr_handler_s) +
  387 + sizeof(struct omap_intr_handler_bank_s) * nbanks);
372 388
373 - s->parent_pic = parent; 389 + s->parent_intr[0] = parent_irq;
  390 + s->parent_intr[1] = parent_fiq;
374 s->base = base; 391 s->base = base;
375 - s->pins = qemu_allocate_irqs(omap_set_intr, s, 32); 392 + s->nbanks = nbanks;
  393 + s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
  394 +
376 omap_inth_reset(s); 395 omap_inth_reset(s);
377 396
378 iomemtype = cpu_register_io_memory(0, omap_inth_readfn, 397 iomemtype = cpu_register_io_memory(0, omap_inth_readfn,
@@ -1144,7 +1163,8 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) @@ -1144,7 +1163,8 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
1144 timer->val = 0; 1163 timer->val = 0;
1145 timer->st = 0; 1164 timer->st = 0;
1146 if (timer->it_ena) 1165 if (timer->it_ena)
1147 - qemu_irq_raise(timer->irq); 1166 + /* Edge-triggered irq */
  1167 + qemu_irq_pulse(timer->irq);
1148 } 1168 }
1149 } else 1169 } else
1150 qemu_del_timer(timer->timer); 1170 qemu_del_timer(timer->timer);
@@ -1161,7 +1181,8 @@ static void omap_timer_tick(void *opaque) @@ -1161,7 +1181,8 @@ static void omap_timer_tick(void *opaque)
1161 } 1181 }
1162 1182
1163 if (timer->it_ena) 1183 if (timer->it_ena)
1164 - qemu_irq_raise(timer->irq); 1184 + /* Edge-triggered irq */
  1185 + qemu_irq_pulse(timer->irq);
1165 omap_timer_update(timer); 1186 omap_timer_update(timer);
1166 } 1187 }
1167 1188
@@ -3678,6 +3699,7 @@ struct omap_rtc_s { @@ -3678,6 +3699,7 @@ struct omap_rtc_s {
3678 3699
3679 static void omap_rtc_interrupts_update(struct omap_rtc_s *s) 3700 static void omap_rtc_interrupts_update(struct omap_rtc_s *s)
3680 { 3701 {
  3702 + /* s->alarm is level-triggered */
3681 qemu_set_irq(s->alarm, (s->status >> 6) & 1); 3703 qemu_set_irq(s->alarm, (s->status >> 6) & 1);
3682 } 3704 }
3683 3705
@@ -4000,26 +4022,26 @@ static void omap_rtc_tick(void *opaque) @@ -4000,26 +4022,26 @@ static void omap_rtc_tick(void *opaque)
4000 switch (s->interrupts & 3) { 4022 switch (s->interrupts & 3) {
4001 case 0: 4023 case 0:
4002 s->status |= 0x04; 4024 s->status |= 0x04;
4003 - qemu_irq_raise(s->irq); 4025 + qemu_irq_pulse(s->irq);
4004 break; 4026 break;
4005 case 1: 4027 case 1:
4006 if (s->current_tm.tm_sec) 4028 if (s->current_tm.tm_sec)
4007 break; 4029 break;
4008 s->status |= 0x08; 4030 s->status |= 0x08;
4009 - qemu_irq_raise(s->irq); 4031 + qemu_irq_pulse(s->irq);
4010 break; 4032 break;
4011 case 2: 4033 case 2:
4012 if (s->current_tm.tm_sec || s->current_tm.tm_min) 4034 if (s->current_tm.tm_sec || s->current_tm.tm_min)
4013 break; 4035 break;
4014 s->status |= 0x10; 4036 s->status |= 0x10;
4015 - qemu_irq_raise(s->irq); 4037 + qemu_irq_pulse(s->irq);
4016 break; 4038 break;
4017 case 3: 4039 case 3:
4018 if (s->current_tm.tm_sec || 4040 if (s->current_tm.tm_sec ||
4019 s->current_tm.tm_min || s->current_tm.tm_hour) 4041 s->current_tm.tm_min || s->current_tm.tm_hour)
4020 break; 4042 break;
4021 s->status |= 0x20; 4043 s->status |= 0x20;
4022 - qemu_irq_raise(s->irq); 4044 + qemu_irq_pulse(s->irq);
4023 break; 4045 break;
4024 } 4046 }
4025 4047
@@ -4121,7 +4143,8 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) @@ -4121,7 +4143,8 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4121 break; 4143 break;
4122 } 4144 }
4123 4145
4124 - qemu_set_irq(s->rxirq, irq); 4146 + if (irq)
  4147 + qemu_irq_pulse(s->rxirq);
4125 4148
4126 switch ((s->spcr[1] >> 4) & 3) { /* XINTM */ 4149 switch ((s->spcr[1] >> 4) & 3) { /* XINTM */
4127 case 0: 4150 case 0:
@@ -4135,7 +4158,8 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) @@ -4135,7 +4158,8 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s)
4135 break; 4158 break;
4136 } 4159 }
4137 4160
4138 - qemu_set_irq(s->txirq, irq); 4161 + if (irq)
  4162 + qemu_irq_pulse(s->txirq);
4139 } 4163 }
4140 4164
4141 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s) 4165 static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
@@ -4901,8 +4925,9 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, @@ -4901,8 +4925,9 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4901 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) 4925 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4902 qemu_mallocz(sizeof(struct omap_mpu_state_s)); 4926 qemu_mallocz(sizeof(struct omap_mpu_state_s));
4903 ram_addr_t imif_base, emiff_base; 4927 ram_addr_t imif_base, emiff_base;
  4928 + qemu_irq *cpu_irq;
4904 int sdindex; 4929 int sdindex;
4905 - 4930 +
4906 if (!core) 4931 if (!core)
4907 core = "ti925t"; 4932 core = "ti925t";
4908 4933
@@ -4929,11 +4954,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, @@ -4929,11 +4954,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4929 4954
4930 omap_clkm_init(0xfffece00, 0xe1008000, s); 4955 omap_clkm_init(0xfffece00, 0xe1008000, s);
4931 4956
4932 - s->ih[0] = omap_inth_init(0xfffecb00, 0x100,  
4933 - arm_pic_init_cpu(s->env), 4957 + cpu_irq = arm_pic_init_cpu(s->env);
  4958 + s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1,
  4959 + cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4934 omap_findclk(s, "arminth_ck")); 4960 omap_findclk(s, "arminth_ck"));
4935 - s->ih[1] = omap_inth_init(0xfffe0000, 0x800,  
4936 - &s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], 4961 + s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1,
  4962 + s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4937 omap_findclk(s, "arminth_ck")); 4963 omap_findclk(s, "arminth_ck"));
4938 s->irq[0] = s->ih[0]->pins; 4964 s->irq[0] = s->ih[0]->pins;
4939 s->irq[1] = s->ih[1]->pins; 4965 s->irq[1] = s->ih[1]->pins;
hw/omap.h
@@ -57,7 +57,8 @@ void omap_clk_reparent(omap_clk clk, omap_clk parent); @@ -57,7 +57,8 @@ void omap_clk_reparent(omap_clk clk, omap_clk parent);
57 /* omap.c */ 57 /* omap.c */
58 struct omap_intr_handler_s; 58 struct omap_intr_handler_s;
59 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, 59 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
60 - unsigned long size, qemu_irq parent[2], omap_clk clk); 60 + unsigned long size, unsigned char nbanks,
  61 + qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk);
61 62
62 /* 63 /*
63 * Common IRQ numbers for level 1 interrupt handler 64 * Common IRQ numbers for level 1 interrupt handler