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"
23 #include "hw/i386/pc.h"
24 #include "monitor/monitor.h"
25 #include "hw/sysbus.h"
27 #include "hw/lm32/lm32_pic.h"
28 #include "hw/intc/intc.h"
30 #define TYPE_LM32_PIC "lm32-pic"
31 #define LM32_PIC(obj) OBJECT_CHECK(LM32PicState, (obj), TYPE_LM32_PIC)
34 SysBusDevice parent_obj
;
37 uint32_t im
; /* interrupt mask */
38 uint32_t ip
; /* interrupt pending */
42 uint64_t stats_irq_count
[32];
44 typedef struct LM32PicState LM32PicState
;
46 static void update_irq(LM32PicState
*s
)
48 s
->ip
|= s
->irq_state
;
51 trace_lm32_pic_raise_irq();
52 qemu_irq_raise(s
->parent_irq
);
54 trace_lm32_pic_lower_irq();
55 qemu_irq_lower(s
->parent_irq
);
59 static void irq_handler(void *opaque
, int irq
, int level
)
61 LM32PicState
*s
= opaque
;
64 trace_lm32_pic_interrupt(irq
, level
);
67 s
->irq_state
|= (1 << irq
);
68 s
->stats_irq_count
[irq
]++;
70 s
->irq_state
&= ~(1 << irq
);
76 void lm32_pic_set_im(DeviceState
*d
, uint32_t im
)
78 LM32PicState
*s
= LM32_PIC(d
);
80 trace_lm32_pic_set_im(im
);
86 void lm32_pic_set_ip(DeviceState
*d
, uint32_t ip
)
88 LM32PicState
*s
= LM32_PIC(d
);
90 trace_lm32_pic_set_ip(ip
);
98 uint32_t lm32_pic_get_im(DeviceState
*d
)
100 LM32PicState
*s
= LM32_PIC(d
);
102 trace_lm32_pic_get_im(s
->im
);
106 uint32_t lm32_pic_get_ip(DeviceState
*d
)
108 LM32PicState
*s
= LM32_PIC(d
);
110 trace_lm32_pic_get_ip(s
->ip
);
114 static void pic_reset(DeviceState
*d
)
116 LM32PicState
*s
= LM32_PIC(d
);
122 for (i
= 0; i
< 32; i
++) {
123 s
->stats_irq_count
[i
] = 0;
127 static bool lm32_get_statistics(InterruptStatsProvider
*obj
,
128 uint64_t **irq_counts
, unsigned int *nb_irqs
)
130 LM32PicState
*s
= LM32_PIC(obj
);
131 *irq_counts
= s
->stats_irq_count
;
132 *nb_irqs
= ARRAY_SIZE(s
->stats_irq_count
);
136 static void lm32_print_info(InterruptStatsProvider
*obj
, Monitor
*mon
)
138 LM32PicState
*s
= LM32_PIC(obj
);
139 monitor_printf(mon
, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
140 s
->im
, s
->ip
, s
->irq_state
);
143 static void lm32_pic_init(Object
*obj
)
145 DeviceState
*dev
= DEVICE(obj
);
146 LM32PicState
*s
= LM32_PIC(obj
);
147 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
149 qdev_init_gpio_in(dev
, irq_handler
, 32);
150 sysbus_init_irq(sbd
, &s
->parent_irq
);
153 static const VMStateDescription vmstate_lm32_pic
= {
156 .minimum_version_id
= 2,
157 .fields
= (VMStateField
[]) {
158 VMSTATE_UINT32(im
, LM32PicState
),
159 VMSTATE_UINT32(ip
, LM32PicState
),
160 VMSTATE_UINT32(irq_state
, LM32PicState
),
161 VMSTATE_UINT64_ARRAY(stats_irq_count
, LM32PicState
, 32),
162 VMSTATE_END_OF_LIST()
166 static void lm32_pic_class_init(ObjectClass
*klass
, void *data
)
168 DeviceClass
*dc
= DEVICE_CLASS(klass
);
169 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(klass
);
171 dc
->reset
= pic_reset
;
172 dc
->vmsd
= &vmstate_lm32_pic
;
173 ic
->get_statistics
= lm32_get_statistics
;
174 ic
->print_info
= lm32_print_info
;
177 static const TypeInfo lm32_pic_info
= {
178 .name
= TYPE_LM32_PIC
,
179 .parent
= TYPE_SYS_BUS_DEVICE
,
180 .instance_size
= sizeof(LM32PicState
),
181 .instance_init
= lm32_pic_init
,
182 .class_init
= lm32_pic_class_init
,
183 .interfaces
= (InterfaceInfo
[]) {
184 { TYPE_INTERRUPT_STATS_PROVIDER
},
189 static void lm32_pic_register_types(void)
191 type_register_static(&lm32_pic_info
);
194 type_init(lm32_pic_register_types
)