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/>.
20 #include "qemu/osdep.h"
22 #include "migration/vmstate.h"
23 #include "monitor/monitor.h"
24 #include "qemu/module.h"
25 #include "hw/sysbus.h"
27 #include "hw/lm32/lm32_pic.h"
28 #include "hw/intc/intc.h"
30 #include "qom/object.h"
32 #define TYPE_LM32_PIC "lm32-pic"
33 typedef struct LM32PicState LM32PicState
;
34 #define LM32_PIC(obj) OBJECT_CHECK(LM32PicState, (obj), TYPE_LM32_PIC)
37 SysBusDevice parent_obj
;
40 uint32_t im
; /* interrupt mask */
41 uint32_t ip
; /* interrupt pending */
45 uint64_t stats_irq_count
[32];
48 static void update_irq(LM32PicState
*s
)
50 s
->ip
|= s
->irq_state
;
53 trace_lm32_pic_raise_irq();
54 qemu_irq_raise(s
->parent_irq
);
56 trace_lm32_pic_lower_irq();
57 qemu_irq_lower(s
->parent_irq
);
61 static void irq_handler(void *opaque
, int irq
, int level
)
63 LM32PicState
*s
= opaque
;
66 trace_lm32_pic_interrupt(irq
, level
);
69 s
->irq_state
|= (1 << irq
);
70 s
->stats_irq_count
[irq
]++;
72 s
->irq_state
&= ~(1 << irq
);
78 void lm32_pic_set_im(DeviceState
*d
, uint32_t im
)
80 LM32PicState
*s
= LM32_PIC(d
);
82 trace_lm32_pic_set_im(im
);
88 void lm32_pic_set_ip(DeviceState
*d
, uint32_t ip
)
90 LM32PicState
*s
= LM32_PIC(d
);
92 trace_lm32_pic_set_ip(ip
);
100 uint32_t lm32_pic_get_im(DeviceState
*d
)
102 LM32PicState
*s
= LM32_PIC(d
);
104 trace_lm32_pic_get_im(s
->im
);
108 uint32_t lm32_pic_get_ip(DeviceState
*d
)
110 LM32PicState
*s
= LM32_PIC(d
);
112 trace_lm32_pic_get_ip(s
->ip
);
116 static void pic_reset(DeviceState
*d
)
118 LM32PicState
*s
= LM32_PIC(d
);
124 for (i
= 0; i
< 32; i
++) {
125 s
->stats_irq_count
[i
] = 0;
129 static bool lm32_get_statistics(InterruptStatsProvider
*obj
,
130 uint64_t **irq_counts
, unsigned int *nb_irqs
)
132 LM32PicState
*s
= LM32_PIC(obj
);
133 *irq_counts
= s
->stats_irq_count
;
134 *nb_irqs
= ARRAY_SIZE(s
->stats_irq_count
);
138 static void lm32_print_info(InterruptStatsProvider
*obj
, Monitor
*mon
)
140 LM32PicState
*s
= LM32_PIC(obj
);
141 monitor_printf(mon
, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
142 s
->im
, s
->ip
, s
->irq_state
);
145 static void lm32_pic_init(Object
*obj
)
147 DeviceState
*dev
= DEVICE(obj
);
148 LM32PicState
*s
= LM32_PIC(obj
);
149 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
151 qdev_init_gpio_in(dev
, irq_handler
, 32);
152 sysbus_init_irq(sbd
, &s
->parent_irq
);
155 static const VMStateDescription vmstate_lm32_pic
= {
158 .minimum_version_id
= 2,
159 .fields
= (VMStateField
[]) {
160 VMSTATE_UINT32(im
, LM32PicState
),
161 VMSTATE_UINT32(ip
, LM32PicState
),
162 VMSTATE_UINT32(irq_state
, LM32PicState
),
163 VMSTATE_UINT64_ARRAY(stats_irq_count
, LM32PicState
, 32),
164 VMSTATE_END_OF_LIST()
168 static void lm32_pic_class_init(ObjectClass
*klass
, void *data
)
170 DeviceClass
*dc
= DEVICE_CLASS(klass
);
171 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(klass
);
173 dc
->reset
= pic_reset
;
174 dc
->vmsd
= &vmstate_lm32_pic
;
175 ic
->get_statistics
= lm32_get_statistics
;
176 ic
->print_info
= lm32_print_info
;
179 static const TypeInfo lm32_pic_info
= {
180 .name
= TYPE_LM32_PIC
,
181 .parent
= TYPE_SYS_BUS_DEVICE
,
182 .instance_size
= sizeof(LM32PicState
),
183 .instance_init
= lm32_pic_init
,
184 .class_init
= lm32_pic_class_init
,
185 .interfaces
= (InterfaceInfo
[]) {
186 { TYPE_INTERRUPT_STATS_PROVIDER
},
191 static void lm32_pic_register_types(void)
193 type_register_static(&lm32_pic_info
);
196 type_init(lm32_pic_register_types
)