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_syscfg.h"
32 static void stm32f4xx_syscfg_reset(DeviceState
*dev
)
34 STM32F4xxSyscfgState
*s
= STM32F4XX_SYSCFG(dev
);
36 s
->syscfg_memrmp
= 0x00000000;
37 s
->syscfg_pmc
= 0x00000000;
38 s
->syscfg_exticr
[0] = 0x00000000;
39 s
->syscfg_exticr
[1] = 0x00000000;
40 s
->syscfg_exticr
[2] = 0x00000000;
41 s
->syscfg_exticr
[3] = 0x00000000;
42 s
->syscfg_cmpcr
= 0x00000000;
45 static void stm32f4xx_syscfg_set_irq(void *opaque
, int irq
, int level
)
47 STM32F4xxSyscfgState
*s
= opaque
;
49 int startbit
= (irq
& 3) * 4;
50 uint8_t config
= config
= irq
/ 16;
52 trace_stm32f4xx_syscfg_set_irq(irq
/ 16, irq
% 16, level
);
54 g_assert(icrreg
< SYSCFG_NUM_EXTICR
);
56 if (extract32(s
->syscfg_exticr
[icrreg
], startbit
, 4) == config
) {
57 qemu_set_irq(s
->gpio_out
[irq
], level
);
58 trace_stm32f4xx_pulse_exti(irq
);
62 static uint64_t stm32f4xx_syscfg_read(void *opaque
, hwaddr addr
,
65 STM32F4xxSyscfgState
*s
= opaque
;
67 trace_stm32f4xx_syscfg_read(addr
);
71 return s
->syscfg_memrmp
;
74 case SYSCFG_EXTICR1
...SYSCFG_EXTICR4
:
75 return s
->syscfg_exticr
[addr
/ 4 - SYSCFG_EXTICR1
/ 4];
77 return s
->syscfg_cmpcr
;
79 qemu_log_mask(LOG_GUEST_ERROR
,
80 "%s: Bad offset 0x%"HWADDR_PRIx
"\n", __func__
, addr
);
85 static void stm32f4xx_syscfg_write(void *opaque
, hwaddr addr
,
86 uint64_t val64
, unsigned int size
)
88 STM32F4xxSyscfgState
*s
= opaque
;
89 uint32_t value
= val64
;
91 trace_stm32f4xx_syscfg_write(value
, addr
);
95 qemu_log_mask(LOG_UNIMP
,
96 "%s: Changing the memory mapping isn't supported " \
97 "in QEMU\n", __func__
);
100 qemu_log_mask(LOG_UNIMP
,
101 "%s: Changing the memory mapping isn't supported " \
102 "in QEMU\n", __func__
);
104 case SYSCFG_EXTICR1
...SYSCFG_EXTICR4
:
105 s
->syscfg_exticr
[addr
/ 4 - SYSCFG_EXTICR1
/ 4] = (value
& 0xFFFF);
108 s
->syscfg_cmpcr
= value
;
111 qemu_log_mask(LOG_GUEST_ERROR
,
112 "%s: Bad offset 0x%"HWADDR_PRIx
"\n", __func__
, addr
);
116 static const MemoryRegionOps stm32f4xx_syscfg_ops
= {
117 .read
= stm32f4xx_syscfg_read
,
118 .write
= stm32f4xx_syscfg_write
,
119 .endianness
= DEVICE_NATIVE_ENDIAN
,
122 static void stm32f4xx_syscfg_init(Object
*obj
)
124 STM32F4xxSyscfgState
*s
= STM32F4XX_SYSCFG(obj
);
126 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->irq
);
128 memory_region_init_io(&s
->mmio
, obj
, &stm32f4xx_syscfg_ops
, s
,
129 TYPE_STM32F4XX_SYSCFG
, 0x400);
130 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &s
->mmio
);
132 qdev_init_gpio_in(DEVICE(obj
), stm32f4xx_syscfg_set_irq
, 16 * 9);
133 qdev_init_gpio_out(DEVICE(obj
), s
->gpio_out
, 16);
136 static const VMStateDescription vmstate_stm32f4xx_syscfg
= {
137 .name
= TYPE_STM32F4XX_SYSCFG
,
139 .minimum_version_id
= 1,
140 .fields
= (VMStateField
[]) {
141 VMSTATE_UINT32(syscfg_memrmp
, STM32F4xxSyscfgState
),
142 VMSTATE_UINT32(syscfg_pmc
, STM32F4xxSyscfgState
),
143 VMSTATE_UINT32_ARRAY(syscfg_exticr
, STM32F4xxSyscfgState
,
145 VMSTATE_UINT32(syscfg_cmpcr
, STM32F4xxSyscfgState
),
146 VMSTATE_END_OF_LIST()
150 static void stm32f4xx_syscfg_class_init(ObjectClass
*klass
, void *data
)
152 DeviceClass
*dc
= DEVICE_CLASS(klass
);
154 dc
->reset
= stm32f4xx_syscfg_reset
;
155 dc
->vmsd
= &vmstate_stm32f4xx_syscfg
;
158 static const TypeInfo stm32f4xx_syscfg_info
= {
159 .name
= TYPE_STM32F4XX_SYSCFG
,
160 .parent
= TYPE_SYS_BUS_DEVICE
,
161 .instance_size
= sizeof(STM32F4xxSyscfgState
),
162 .instance_init
= stm32f4xx_syscfg_init
,
163 .class_init
= stm32f4xx_syscfg_class_init
,
166 static void stm32f4xx_syscfg_register_types(void)
168 type_register_static(&stm32f4xx_syscfg_info
);
171 type_init(stm32f4xx_syscfg_register_types
)