root / hw / arm_pic.c @ beb811bd
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 | } |