74 lines
1.6 KiB
C
74 lines
1.6 KiB
C
|
/*
|
||
|
* 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;
|
||
|
}
|