Revision d0dfae6e hw/ppc.c

b/hw/ppc.c
161 161
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc6xx_set_irq, env, 6);
162 162
}
163 163

  
164
/* PowerPC 970 internal IRQ controller */
165
static void ppc970_set_irq (void *opaque, int pin, int level)
166
{
167
    CPUState *env = opaque;
168
    int cur_level;
169

  
170
#if defined(PPC_DEBUG_IRQ)
171
    if (loglevel & CPU_LOG_INT) {
172
        fprintf(logfile, "%s: env %p pin %d level %d\n", __func__,
173
                env, pin, level);
174
    }
175
#endif
176
    cur_level = (env->irq_input_state >> pin) & 1;
177
    /* Don't generate spurious events */
178
    if ((cur_level == 1 && level == 0) || (cur_level == 0 && level != 0)) {
179
        switch (pin) {
180
        case PPC970_INPUT_INT:
181
            /* Level sensitive - active high */
182
#if defined(PPC_DEBUG_IRQ)
183
            if (loglevel & CPU_LOG_INT) {
184
                fprintf(logfile, "%s: set the external IRQ state to %d\n",
185
                        __func__, level);
186
            }
187
#endif
188
            ppc_set_irq(env, PPC_INTERRUPT_EXT, level);
189
            break;
190
        case PPC970_INPUT_THINT:
191
            /* Level sensitive - active high */
192
#if defined(PPC_DEBUG_IRQ)
193
            if (loglevel & CPU_LOG_INT) {
194
                fprintf(logfile, "%s: set the SMI IRQ state to %d\n", __func__,
195
                        level);
196
            }
197
#endif
198
            ppc_set_irq(env, PPC_INTERRUPT_THERM, level);
199
            break;
200
        case PPC970_INPUT_MCP:
201
            /* Negative edge sensitive */
202
            /* XXX: TODO: actual reaction may depends on HID0 status
203
             *            603/604/740/750: check HID0[EMCP]
204
             */
205
            if (cur_level == 1 && level == 0) {
206
#if defined(PPC_DEBUG_IRQ)
207
                if (loglevel & CPU_LOG_INT) {
208
                    fprintf(logfile, "%s: raise machine check state\n",
209
                            __func__);
210
                }
211
#endif
212
                ppc_set_irq(env, PPC_INTERRUPT_MCK, 1);
213
            }
214
            break;
215
        case PPC970_INPUT_CKSTP:
216
            /* Level sensitive - active low */
217
            /* XXX: TODO: relay the signal to CKSTP_OUT pin */
218
            if (level) {
219
#if defined(PPC_DEBUG_IRQ)
220
                if (loglevel & CPU_LOG_INT) {
221
                    fprintf(logfile, "%s: stop the CPU\n", __func__);
222
                }
223
#endif
224
                env->halted = 1;
225
            } else {
226
#if defined(PPC_DEBUG_IRQ)
227
                if (loglevel & CPU_LOG_INT) {
228
                    fprintf(logfile, "%s: restart the CPU\n", __func__);
229
                }
230
#endif
231
                env->halted = 0;
232
            }
233
            break;
234
        case PPC970_INPUT_HRESET:
235
            /* Level sensitive - active low */
236
            if (level) {
237
#if 0 // XXX: TOFIX
238
#if defined(PPC_DEBUG_IRQ)
239
                if (loglevel & CPU_LOG_INT) {
240
                    fprintf(logfile, "%s: reset the CPU\n", __func__);
241
                }
242
#endif
243
                cpu_reset(env);
244
#endif
245
            }
246
            break;
247
        case PPC970_INPUT_SRESET:
248
#if defined(PPC_DEBUG_IRQ)
249
            if (loglevel & CPU_LOG_INT) {
250
                fprintf(logfile, "%s: set the RESET IRQ state to %d\n",
251
                        __func__, level);
252
            }
253
#endif
254
            ppc_set_irq(env, PPC_INTERRUPT_RESET, level);
255
            break;
256
        case PPC970_INPUT_TBEN:
257
#if defined(PPC_DEBUG_IRQ)
258
            if (loglevel & CPU_LOG_INT) {
259
                fprintf(logfile, "%s: set the TBEN state to %d\n", __func__,
260
                        level);
261
            }
262
#endif
263
            /* XXX: TODO */
264
            break;
265
        default:
266
            /* Unknown pin - do nothing */
267
#if defined(PPC_DEBUG_IRQ)
268
            if (loglevel & CPU_LOG_INT) {
269
                fprintf(logfile, "%s: unknown IRQ pin %d\n", __func__, pin);
270
            }
271
#endif
272
            return;
273
        }
274
        if (level)
275
            env->irq_input_state |= 1 << pin;
276
        else
277
            env->irq_input_state &= ~(1 << pin);
278
    }
279
}
280

  
281
void ppc970_irq_init (CPUState *env)
282
{
283
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppc970_set_irq, env, 7);
284
}
285

  
164 286
/* PowerPC 405 internal IRQ controller */
165 287
static void ppc405_set_irq (void *opaque, int pin, int level)
166 288
{

Also available in: Unified diff