Revision 43d91709 hw/mst_fpga.c
b/hw/mst_fpga.c | ||
---|---|---|
46 | 46 |
}mst_irq_state; |
47 | 47 |
|
48 | 48 |
static void |
49 |
mst_fpga_update_gpio(mst_irq_state *s) |
|
50 |
{ |
|
51 |
uint32_t level, diff; |
|
52 |
int bit; |
|
53 |
level = s->prev_level ^ s->intsetclr; |
|
54 |
|
|
55 |
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { |
|
56 |
bit = ffs(diff) - 1; |
|
57 |
qemu_set_irq(s->pins[bit], (level >> bit) & 1 ); |
|
58 |
} |
|
59 |
s->prev_level = level; |
|
60 |
} |
|
61 |
|
|
62 |
static void |
|
63 | 49 |
mst_fpga_set_irq(void *opaque, int irq, int level) |
64 | 50 |
{ |
65 | 51 |
mst_irq_state *s = (mst_irq_state *)opaque; |
52 |
uint32_t oldint = s->intsetclr; |
|
66 | 53 |
|
67 | 54 |
if (level) |
68 | 55 |
s->prev_level |= 1u << irq; |
69 | 56 |
else |
70 | 57 |
s->prev_level &= ~(1u << irq); |
71 | 58 |
|
72 |
if(s->intmskena & (1u << irq)) { |
|
73 |
s->intsetclr = 1u << irq; |
|
74 |
qemu_set_irq(s->parent, level); |
|
75 |
} |
|
59 |
if ((s->intmskena & (1u << irq)) && level) |
|
60 |
s->intsetclr |= 1u << irq; |
|
61 |
|
|
62 |
if (oldint != (s->intsetclr & s->intmskena)) |
|
63 |
qemu_set_irq(s->parent, s->intsetclr & s->intmskena); |
|
76 | 64 |
} |
77 | 65 |
|
78 | 66 |
|
... | ... | |
146 | 134 |
break; |
147 | 135 |
case MST_INTMSKENA: /* Mask interupt */ |
148 | 136 |
s->intmskena = (value & 0xFEEFF); |
149 |
mst_fpga_update_gpio(s);
|
|
137 |
qemu_set_irq(s->parent, s->intsetclr & s->intmskena);
|
|
150 | 138 |
break; |
151 | 139 |
case MST_INTSETCLR: /* clear or set interrupt */ |
152 | 140 |
s->intsetclr = (value & 0xFEEFF); |
141 |
qemu_set_irq(s->parent, s->intsetclr); |
|
153 | 142 |
break; |
154 | 143 |
case MST_PCMCIA0: |
155 | 144 |
s->pcmcia0 = value; |
... | ... | |
212 | 201 |
qemu_get_be32s(f, &s->intsetclr); |
213 | 202 |
qemu_get_be32s(f, &s->pcmcia0); |
214 | 203 |
qemu_get_be32s(f, &s->pcmcia1); |
204 |
|
|
205 |
qemu_set_irq(s->parent, s->intsetclr & s->intmskena); |
|
215 | 206 |
return 0; |
216 | 207 |
} |
217 | 208 |
|
Also available in: Unified diff