1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
/*
* Generic ARM Programmable Interrupt Controller support.
*
* Copyright (c) 2006 CodeSourcery.
* Written by Paul Brook
*
* This code is licenced under the LGPL
*/
#include "vl.h"
#include "arm_pic.h"
/* Stub functions for hardware that doesn't exist. */
void pic_set_irq(int irq, int level)
{
cpu_abort(cpu_single_env, "pic_set_irq");
}
void pic_info(void)
{
}
void irq_info(void)
{
}
void pic_set_irq_new(void *opaque, int irq, int level)
{
arm_pic_handler *p = (arm_pic_handler *)opaque;
/* Call the real handler. */
(*p)(opaque, irq, level);
}
/* Model the IRQ/FIQ CPU interrupt lines as a two input interrupt controller.
Input 0 is IRQ and input 1 is FIQ. */
typedef struct
{
arm_pic_handler handler;
CPUState *cpu_env;
} arm_pic_cpu_state;
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
{
arm_pic_cpu_state *s = (arm_pic_cpu_state *)opaque;
switch (irq) {
case ARM_PIC_CPU_IRQ:
if (level)
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
else
cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
break;
case ARM_PIC_CPU_FIQ:
if (level)
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
else
cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
break;
default:
cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n",
irq);
}
}
void *arm_pic_init_cpu(CPUState *env)
{
arm_pic_cpu_state *s;
s = (arm_pic_cpu_state *)malloc(sizeof(arm_pic_cpu_state));
s->handler = arm_pic_cpu_handler;
s->cpu_env = env;
return s;
}
|