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"
31 #define TYPE_LM32_PIC "lm32-pic"
32 #define LM32_PIC(obj) OBJECT_CHECK(LM32PicState, (obj), TYPE_LM32_PIC)
35 SysBusDevice parent_obj
;
38 uint32_t im
; /* interrupt mask */
39 uint32_t ip
; /* interrupt pending */
43 uint64_t stats_irq_count
[32];
45 typedef struct LM32PicState LM32PicState
;
47 static void update_irq(LM32PicState
*s
)
49 s
->ip
|= s
->irq_state
;
52 trace_lm32_pic_raise_irq();
53 qemu_irq_raise(s
->parent_irq
);
55 trace_lm32_pic_lower_irq();
56 qemu_irq_lower(s
->parent_irq
);
60 static void irq_handler(void *opaque
, int irq
, int level
)
62 LM32PicState
*s
= opaque
;
65 trace_lm32_pic_interrupt(irq
, level
);
68 s
->irq_state
|= (1 << irq
);
69 s
->stats_irq_count
[irq
]++;
71 s
->irq_state
&= ~(1 << irq
);
77 void lm32_pic_set_im(DeviceState
*d
, uint32_t im
)
79 LM32PicState
*s
= LM32_PIC(d
);
81 trace_lm32_pic_set_im(im
);
87 void lm32_pic_set_ip(DeviceState
*d
, uint32_t ip
)
89 LM32PicState
*s
= LM32_PIC(d
);
91 trace_lm32_pic_set_ip(ip
);
99 uint32_t lm32_pic_get_im(DeviceState
*d
)
101 LM32PicState
*s
= LM32_PIC(d
);
103 trace_lm32_pic_get_im(s
->im
);
107 uint32_t lm32_pic_get_ip(DeviceState
*d
)
109 LM32PicState
*s
= LM32_PIC(d
);
111 trace_lm32_pic_get_ip(s
->ip
);
115 static void pic_reset(DeviceState
*d
)
117 LM32PicState
*s
= LM32_PIC(d
);
123 for (i
= 0; i
< 32; i
++) {
124 s
->stats_irq_count
[i
] = 0;
128 static bool lm32_get_statistics(InterruptStatsProvider
*obj
,
129 uint64_t **irq_counts
, unsigned int *nb_irqs
)
131 LM32PicState
*s
= LM32_PIC(obj
);
132 *irq_counts
= s
->stats_irq_count
;
133 *nb_irqs
= ARRAY_SIZE(s
->stats_irq_count
);
137 static void lm32_print_info(InterruptStatsProvider
*obj
, Monitor
*mon
)
139 LM32PicState
*s
= LM32_PIC(obj
);
140 monitor_printf(mon
, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
141 s
->im
, s
->ip
, s
->irq_state
);
144 static void lm32_pic_init(Object
*obj
)
146 DeviceState
*dev
= DEVICE(obj
);
147 LM32PicState
*s
= LM32_PIC(obj
);
148 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
150 qdev_init_gpio_in(dev
, irq_handler
, 32);
151 sysbus_init_irq(sbd
, &s
->parent_irq
);
154 static const VMStateDescription vmstate_lm32_pic
= {
157 .minimum_version_id
= 2,
158 .fields
= (VMStateField
[]) {
159 VMSTATE_UINT32(im
, LM32PicState
),
160 VMSTATE_UINT32(ip
, LM32PicState
),
161 VMSTATE_UINT32(irq_state
, LM32PicState
),
162 VMSTATE_UINT64_ARRAY(stats_irq_count
, LM32PicState
, 32),
163 VMSTATE_END_OF_LIST()
167 static void lm32_pic_class_init(ObjectClass
*klass
, void *data
)
169 DeviceClass
*dc
= DEVICE_CLASS(klass
);
170 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(klass
);
172 dc
->reset
= pic_reset
;
173 dc
->vmsd
= &vmstate_lm32_pic
;
174 ic
->get_statistics
= lm32_get_statistics
;
175 ic
->print_info
= lm32_print_info
;
178 static const TypeInfo lm32_pic_info
= {
179 .name
= TYPE_LM32_PIC
,
180 .parent
= TYPE_SYS_BUS_DEVICE
,
181 .instance_size
= sizeof(LM32PicState
),
182 .instance_init
= lm32_pic_init
,
183 .class_init
= lm32_pic_class_init
,
184 .interfaces
= (InterfaceInfo
[]) {
185 { TYPE_INTERRUPT_STATS_PROVIDER
},
190 static void lm32_pic_register_types(void)
192 type_register_static(&lm32_pic_info
);
195 type_init(lm32_pic_register_types
)