4 * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 #include "qemu/osdep.h"
29 #include "migration/vmstate.h"
30 #include "hw/misc/stm32f4xx_exti.h"
32 static void stm32f4xx_exti_reset(DeviceState
*dev
)
34 STM32F4xxExtiState
*s
= STM32F4XX_EXTI(dev
);
36 s
->exti_imr
= 0x00000000;
37 s
->exti_emr
= 0x00000000;
38 s
->exti_rtsr
= 0x00000000;
39 s
->exti_ftsr
= 0x00000000;
40 s
->exti_swier
= 0x00000000;
41 s
->exti_pr
= 0x00000000;
44 static void stm32f4xx_exti_set_irq(void *opaque
, int irq
, int level
)
46 STM32F4xxExtiState
*s
= opaque
;
48 trace_stm32f4xx_exti_set_irq(irq
, level
);
50 if (((1 << irq
) & s
->exti_rtsr
) && level
) {
52 s
->exti_pr
|= 1 << irq
;
55 if (((1 << irq
) & s
->exti_ftsr
) && !level
) {
57 s
->exti_pr
|= 1 << irq
;
60 if (!((1 << irq
) & s
->exti_imr
)) {
61 /* Interrupt is masked */
64 qemu_irq_pulse(s
->irq
[irq
]);
67 static uint64_t stm32f4xx_exti_read(void *opaque
, hwaddr addr
,
70 STM32F4xxExtiState
*s
= opaque
;
72 trace_stm32f4xx_exti_read(addr
);
88 qemu_log_mask(LOG_GUEST_ERROR
,
89 "STM32F4XX_exti_read: Bad offset %x\n", (int)addr
);
95 static void stm32f4xx_exti_write(void *opaque
, hwaddr addr
,
96 uint64_t val64
, unsigned int size
)
98 STM32F4xxExtiState
*s
= opaque
;
99 uint32_t value
= (uint32_t) val64
;
101 trace_stm32f4xx_exti_write(addr
, value
);
111 s
->exti_rtsr
= value
;
114 s
->exti_ftsr
= value
;
117 s
->exti_swier
= value
;
120 /* This bit is cleared by writing a 1 to it */
121 s
->exti_pr
&= ~value
;
124 qemu_log_mask(LOG_GUEST_ERROR
,
125 "STM32F4XX_exti_write: Bad offset %x\n", (int)addr
);
129 static const MemoryRegionOps stm32f4xx_exti_ops
= {
130 .read
= stm32f4xx_exti_read
,
131 .write
= stm32f4xx_exti_write
,
132 .endianness
= DEVICE_NATIVE_ENDIAN
,
135 static void stm32f4xx_exti_init(Object
*obj
)
137 STM32F4xxExtiState
*s
= STM32F4XX_EXTI(obj
);
140 for (i
= 0; i
< NUM_INTERRUPT_OUT_LINES
; i
++) {
141 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->irq
[i
]);
144 memory_region_init_io(&s
->mmio
, obj
, &stm32f4xx_exti_ops
, s
,
145 TYPE_STM32F4XX_EXTI
, 0x400);
146 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &s
->mmio
);
148 qdev_init_gpio_in(DEVICE(obj
), stm32f4xx_exti_set_irq
,
149 NUM_GPIO_EVENT_IN_LINES
);
152 static const VMStateDescription vmstate_stm32f4xx_exti
= {
153 .name
= TYPE_STM32F4XX_EXTI
,
155 .minimum_version_id
= 1,
156 .fields
= (const VMStateField
[]) {
157 VMSTATE_UINT32(exti_imr
, STM32F4xxExtiState
),
158 VMSTATE_UINT32(exti_emr
, STM32F4xxExtiState
),
159 VMSTATE_UINT32(exti_rtsr
, STM32F4xxExtiState
),
160 VMSTATE_UINT32(exti_ftsr
, STM32F4xxExtiState
),
161 VMSTATE_UINT32(exti_swier
, STM32F4xxExtiState
),
162 VMSTATE_UINT32(exti_pr
, STM32F4xxExtiState
),
163 VMSTATE_END_OF_LIST()
167 static void stm32f4xx_exti_class_init(ObjectClass
*klass
, void *data
)
169 DeviceClass
*dc
= DEVICE_CLASS(klass
);
171 dc
->reset
= stm32f4xx_exti_reset
;
172 dc
->vmsd
= &vmstate_stm32f4xx_exti
;
175 static const TypeInfo stm32f4xx_exti_info
= {
176 .name
= TYPE_STM32F4XX_EXTI
,
177 .parent
= TYPE_SYS_BUS_DEVICE
,
178 .instance_size
= sizeof(STM32F4xxExtiState
),
179 .instance_init
= stm32f4xx_exti_init
,
180 .class_init
= stm32f4xx_exti_class_init
,
183 static void stm32f4xx_exti_register_types(void)
185 type_register_static(&stm32f4xx_exti_info
);
188 type_init(stm32f4xx_exti_register_types
)