Revision fd6dc90b hw/etraxfs_pic.c
b/hw/etraxfs_pic.c | ||
---|---|---|
22 | 22 |
* THE SOFTWARE. |
23 | 23 |
*/ |
24 | 24 |
|
25 |
#include <stdio.h>
|
|
25 |
#include "sysbus.h"
|
|
26 | 26 |
#include "hw.h" |
27 | 27 |
#include "pc.h" |
28 | 28 |
#include "etraxfs.h" |
... | ... | |
36 | 36 |
#define R_R_GURU 4 |
37 | 37 |
#define R_MAX 5 |
38 | 38 |
|
39 |
struct fs_pic_state
|
|
39 |
struct etrax_pic
|
|
40 | 40 |
{ |
41 |
CPUState *env; |
|
41 |
SysBusDevice busdev; |
|
42 |
uint32_t *interrupt_vector; |
|
43 |
qemu_irq parent_irq; |
|
44 |
qemu_irq parent_nmi; |
|
42 | 45 |
uint32_t regs[R_MAX]; |
43 | 46 |
}; |
44 | 47 |
|
45 |
static void pic_update(struct fs_pic_state *fs)
|
|
48 |
static void pic_update(struct etrax_pic *fs)
|
|
46 | 49 |
{ |
47 |
CPUState *env = fs->env; |
|
48 | 50 |
uint32_t vector = 0; |
49 | 51 |
int i; |
50 | 52 |
|
... | ... | |
66 | 68 |
} |
67 | 69 |
mv >>= 1; |
68 | 70 |
} |
69 |
if (vector) { |
|
70 |
env->interrupt_vector = vector; |
|
71 |
D(printf("%s vector=%x\n", __func__, vector)); |
|
72 |
cpu_interrupt(env, CPU_INTERRUPT_HARD); |
|
73 |
} |
|
74 |
} else { |
|
75 |
env->interrupt_vector = 0; |
|
76 |
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); |
|
77 |
D(printf("%s reset irqs\n", __func__)); |
|
78 | 71 |
} |
72 |
|
|
73 |
if (fs->interrupt_vector) { |
|
74 |
*fs->interrupt_vector = vector; |
|
75 |
} |
|
76 |
qemu_set_irq(fs->parent_irq, !!vector); |
|
79 | 77 |
} |
80 | 78 |
|
81 | 79 |
static uint32_t pic_readl (void *opaque, target_phys_addr_t addr) |
82 | 80 |
{ |
83 |
struct fs_pic_state *fs = opaque;
|
|
81 |
struct etrax_pic *fs = opaque;
|
|
84 | 82 |
uint32_t rval; |
85 | 83 |
|
86 | 84 |
rval = fs->regs[addr >> 2]; |
... | ... | |
91 | 89 |
static void |
92 | 90 |
pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value) |
93 | 91 |
{ |
94 |
struct fs_pic_state *fs = opaque;
|
|
92 |
struct etrax_pic *fs = opaque;
|
|
95 | 93 |
D(printf("%s addr=%x val=%x\n", __func__, addr, value)); |
96 | 94 |
|
97 | 95 |
if (addr == R_RW_MASK) { |
... | ... | |
110 | 108 |
&pic_writel, |
111 | 109 |
}; |
112 | 110 |
|
113 |
void pic_info(Monitor *mon) |
|
114 |
{ |
|
115 |
} |
|
116 |
|
|
117 |
void irq_info(Monitor *mon) |
|
118 |
{ |
|
119 |
} |
|
120 |
|
|
121 | 111 |
static void nmi_handler(void *opaque, int irq, int level) |
122 | 112 |
{ |
123 |
struct fs_pic_state *fs = (void *)opaque; |
|
124 |
CPUState *env = fs->env; |
|
113 |
struct etrax_pic *fs = (void *)opaque; |
|
125 | 114 |
uint32_t mask; |
126 | 115 |
|
127 | 116 |
mask = 1 << irq; |
... | ... | |
130 | 119 |
else |
131 | 120 |
fs->regs[R_R_NMI] &= ~mask; |
132 | 121 |
|
133 |
if (fs->regs[R_R_NMI]) |
|
134 |
cpu_interrupt(env, CPU_INTERRUPT_NMI); |
|
135 |
else |
|
136 |
cpu_reset_interrupt(env, CPU_INTERRUPT_NMI); |
|
122 |
qemu_set_irq(fs->parent_nmi, !!fs->regs[R_R_NMI]); |
|
137 | 123 |
} |
138 | 124 |
|
139 | 125 |
static void irq_handler(void *opaque, int irq, int level) |
140 | 126 |
{ |
141 |
struct fs_pic_state *fs = (void *)opaque;
|
|
127 |
struct etrax_pic *fs = (void *)opaque;
|
|
142 | 128 |
|
143 | 129 |
if (irq >= 30) |
144 | 130 |
return nmi_handler(opaque, irq, level); |
... | ... | |
149 | 135 |
pic_update(fs); |
150 | 136 |
} |
151 | 137 |
|
152 |
qemu_irq *etraxfs_pic_init(CPUState *env, target_phys_addr_t base)
|
|
138 |
static void etraxfs_pic_init(SysBusDevice *dev)
|
|
153 | 139 |
{ |
154 |
struct fs_pic_state *fs = NULL; |
|
155 |
qemu_irq *irq; |
|
140 |
struct etrax_pic *s = FROM_SYSBUS(typeof (*s), dev); |
|
156 | 141 |
int intr_vect_regs; |
157 | 142 |
|
158 |
fs = qemu_mallocz(sizeof *fs); |
|
159 |
fs->env = env; |
|
160 |
irq = qemu_allocate_irqs(irq_handler, fs, 32); |
|
143 |
s->interrupt_vector = qdev_get_prop_ptr(&dev->qdev, "interrupt_vector"); |
|
144 |
qdev_init_irq_sink(&dev->qdev, irq_handler, 32); |
|
145 |
sysbus_init_irq(dev, &s->parent_irq); |
|
146 |
sysbus_init_irq(dev, &s->parent_nmi); |
|
161 | 147 |
|
162 |
intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, fs); |
|
163 |
cpu_register_physical_memory(base, R_MAX * 4, intr_vect_regs); |
|
164 |
return irq; |
|
148 |
intr_vect_regs = cpu_register_io_memory(0, pic_read, pic_write, s); |
|
149 |
sysbus_init_mmio(dev, R_MAX * 4, intr_vect_regs); |
|
165 | 150 |
} |
151 |
|
|
152 |
static void etraxfs_pic_register(void) |
|
153 |
{ |
|
154 |
sysbus_register_dev("etraxfs,pic", sizeof (struct etrax_pic), |
|
155 |
etraxfs_pic_init); |
|
156 |
} |
|
157 |
|
|
158 |
device_init(etraxfs_pic_register) |
Also available in: Unified diff