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 "monitor/monitor.h"
24 #include "hw/sysbus.h"
26 #include "hw/lm32/lm32_pic.h"
27 #include "hw/intc/intc.h"
29 #define TYPE_LM32_PIC "lm32-pic"
30 #define LM32_PIC(obj) OBJECT_CHECK(LM32PicState, (obj), TYPE_LM32_PIC)
33 SysBusDevice parent_obj
;
36 uint32_t im
; /* interrupt mask */
37 uint32_t ip
; /* interrupt pending */
41 uint64_t stats_irq_count
[32];
43 typedef struct LM32PicState LM32PicState
;
45 static void update_irq(LM32PicState
*s
)
47 s
->ip
|= s
->irq_state
;
50 trace_lm32_pic_raise_irq();
51 qemu_irq_raise(s
->parent_irq
);
53 trace_lm32_pic_lower_irq();
54 qemu_irq_lower(s
->parent_irq
);
58 static void irq_handler(void *opaque
, int irq
, int level
)
60 LM32PicState
*s
= opaque
;
63 trace_lm32_pic_interrupt(irq
, level
);
66 s
->irq_state
|= (1 << irq
);
67 s
->stats_irq_count
[irq
]++;
69 s
->irq_state
&= ~(1 << irq
);
75 void lm32_pic_set_im(DeviceState
*d
, uint32_t im
)
77 LM32PicState
*s
= LM32_PIC(d
);
79 trace_lm32_pic_set_im(im
);
85 void lm32_pic_set_ip(DeviceState
*d
, uint32_t ip
)
87 LM32PicState
*s
= LM32_PIC(d
);
89 trace_lm32_pic_set_ip(ip
);
97 uint32_t lm32_pic_get_im(DeviceState
*d
)
99 LM32PicState
*s
= LM32_PIC(d
);
101 trace_lm32_pic_get_im(s
->im
);
105 uint32_t lm32_pic_get_ip(DeviceState
*d
)
107 LM32PicState
*s
= LM32_PIC(d
);
109 trace_lm32_pic_get_ip(s
->ip
);
113 static void pic_reset(DeviceState
*d
)
115 LM32PicState
*s
= LM32_PIC(d
);
121 for (i
= 0; i
< 32; i
++) {
122 s
->stats_irq_count
[i
] = 0;
126 static bool lm32_get_statistics(InterruptStatsProvider
*obj
,
127 uint64_t **irq_counts
, unsigned int *nb_irqs
)
129 LM32PicState
*s
= LM32_PIC(obj
);
130 *irq_counts
= s
->stats_irq_count
;
131 *nb_irqs
= ARRAY_SIZE(s
->stats_irq_count
);
135 static void lm32_print_info(InterruptStatsProvider
*obj
, Monitor
*mon
)
137 LM32PicState
*s
= LM32_PIC(obj
);
138 monitor_printf(mon
, "lm32-pic: im=%08x ip=%08x irq_state=%08x\n",
139 s
->im
, s
->ip
, s
->irq_state
);
142 static void lm32_pic_init(Object
*obj
)
144 DeviceState
*dev
= DEVICE(obj
);
145 LM32PicState
*s
= LM32_PIC(obj
);
146 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
148 qdev_init_gpio_in(dev
, irq_handler
, 32);
149 sysbus_init_irq(sbd
, &s
->parent_irq
);
152 static const VMStateDescription vmstate_lm32_pic
= {
155 .minimum_version_id
= 2,
156 .fields
= (VMStateField
[]) {
157 VMSTATE_UINT32(im
, LM32PicState
),
158 VMSTATE_UINT32(ip
, LM32PicState
),
159 VMSTATE_UINT32(irq_state
, LM32PicState
),
160 VMSTATE_UINT64_ARRAY(stats_irq_count
, LM32PicState
, 32),
161 VMSTATE_END_OF_LIST()
165 static void lm32_pic_class_init(ObjectClass
*klass
, void *data
)
167 DeviceClass
*dc
= DEVICE_CLASS(klass
);
168 InterruptStatsProviderClass
*ic
= INTERRUPT_STATS_PROVIDER_CLASS(klass
);
170 dc
->reset
= pic_reset
;
171 dc
->vmsd
= &vmstate_lm32_pic
;
172 ic
->get_statistics
= lm32_get_statistics
;
173 ic
->print_info
= lm32_print_info
;
176 static const TypeInfo lm32_pic_info
= {
177 .name
= TYPE_LM32_PIC
,
178 .parent
= TYPE_SYS_BUS_DEVICE
,
179 .instance_size
= sizeof(LM32PicState
),
180 .instance_init
= lm32_pic_init
,
181 .class_init
= lm32_pic_class_init
,
182 .interfaces
= (InterfaceInfo
[]) {
183 { TYPE_INTERRUPT_STATS_PROVIDER
},
188 static void lm32_pic_register_types(void)
190 type_register_static(&lm32_pic_info
);
193 type_init(lm32_pic_register_types
)