Statistics
| Branch: | Revision:

root / hw / arm_pic.c @ 0986ac3b

History | View | Annotate | Download (1.6 kB)

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