2 * LatticeMico32 CPU interrupt controller logic.
4 * Copyright (c) 2010 Michael Walle <michael@walle.cc>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 uint32_t im
; /* interrupt mask */
33 uint32_t ip
; /* interrupt pending */
37 uint32_t stats_irq_count
[32];
39 typedef struct LM32PicState LM32PicState
;
41 static LM32PicState
*pic
;
42 void pic_info(Monitor
*mon
)
48 monitor_printf(mon
, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
49 pic
->im
, pic
->ip
, pic
->irq_state
);
52 void irq_info(Monitor
*mon
)
61 monitor_printf(mon
, "IRQ statistics:\n");
62 for (i
= 0; i
< 32; i
++) {
63 count
= pic
->stats_irq_count
[i
];
65 monitor_printf(mon
, "%2d: %u\n", i
, count
);
70 static void update_irq(LM32PicState
*s
)
72 s
->ip
|= s
->irq_state
;
75 trace_lm32_pic_raise_irq();
76 qemu_irq_raise(s
->parent_irq
);
78 trace_lm32_pic_lower_irq();
79 qemu_irq_lower(s
->parent_irq
);
83 static void irq_handler(void *opaque
, int irq
, int level
)
85 LM32PicState
*s
= opaque
;
88 trace_lm32_pic_interrupt(irq
, level
);
91 s
->irq_state
|= (1 << irq
);
92 s
->stats_irq_count
[irq
]++;
94 s
->irq_state
&= ~(1 << irq
);
100 void lm32_pic_set_im(DeviceState
*d
, uint32_t im
)
102 LM32PicState
*s
= container_of(d
, LM32PicState
, busdev
.qdev
);
104 trace_lm32_pic_set_im(im
);
110 void lm32_pic_set_ip(DeviceState
*d
, uint32_t ip
)
112 LM32PicState
*s
= container_of(d
, LM32PicState
, busdev
.qdev
);
114 trace_lm32_pic_set_ip(ip
);
122 uint32_t lm32_pic_get_im(DeviceState
*d
)
124 LM32PicState
*s
= container_of(d
, LM32PicState
, busdev
.qdev
);
126 trace_lm32_pic_get_im(s
->im
);
130 uint32_t lm32_pic_get_ip(DeviceState
*d
)
132 LM32PicState
*s
= container_of(d
, LM32PicState
, busdev
.qdev
);
134 trace_lm32_pic_get_ip(s
->ip
);
138 static void pic_reset(DeviceState
*d
)
140 LM32PicState
*s
= container_of(d
, LM32PicState
, busdev
.qdev
);
146 for (i
= 0; i
< 32; i
++) {
147 s
->stats_irq_count
[i
] = 0;
151 static int lm32_pic_init(SysBusDevice
*dev
)
153 LM32PicState
*s
= FROM_SYSBUS(typeof(*s
), dev
);
155 qdev_init_gpio_in(&dev
->qdev
, irq_handler
, 32);
156 sysbus_init_irq(dev
, &s
->parent_irq
);
163 static const VMStateDescription vmstate_lm32_pic
= {
166 .minimum_version_id
= 1,
167 .minimum_version_id_old
= 1,
168 .fields
= (VMStateField
[]) {
169 VMSTATE_UINT32(im
, LM32PicState
),
170 VMSTATE_UINT32(ip
, LM32PicState
),
171 VMSTATE_UINT32(irq_state
, LM32PicState
),
172 VMSTATE_UINT32_ARRAY(stats_irq_count
, LM32PicState
, 32),
173 VMSTATE_END_OF_LIST()
177 static SysBusDeviceInfo lm32_pic_info
= {
178 .init
= lm32_pic_init
,
179 .qdev
.name
= "lm32-pic",
180 .qdev
.size
= sizeof(LM32PicState
),
181 .qdev
.vmsd
= &vmstate_lm32_pic
,
182 .qdev
.reset
= pic_reset
,
185 static void lm32_pic_register(void)
187 sysbus_register_withprop(&lm32_pic_info
);
190 device_init(lm32_pic_register
)