4 * Copyright (c) 2018 University of Kent
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see
19 * <http://www.gnu.org/licenses/lgpl-2.1.html>
22 #include "qemu/osdep.h"
23 #include "hw/char/avr_usart.h"
26 #include "hw/qdev-properties.h"
27 #include "hw/qdev-properties-system.h"
29 static int avr_usart_can_receive(void *opaque
)
31 AVRUsartState
*usart
= opaque
;
33 if (usart
->data_valid
|| !(usart
->csrb
& USART_CSRB_RXEN
)) {
39 static void avr_usart_receive(void *opaque
, const uint8_t *buffer
, int size
)
41 AVRUsartState
*usart
= opaque
;
43 assert(!usart
->data_valid
);
44 usart
->data
= buffer
[0];
45 usart
->data_valid
= true;
46 usart
->csra
|= USART_CSRA_RXC
;
47 if (usart
->csrb
& USART_CSRB_RXCIE
) {
48 qemu_set_irq(usart
->rxc_irq
, 1);
52 static void update_char_mask(AVRUsartState
*usart
)
54 uint8_t mode
= ((usart
->csrc
& USART_CSRC_CSZ0
) ? 1 : 0) |
55 ((usart
->csrc
& USART_CSRC_CSZ1
) ? 2 : 0) |
56 ((usart
->csrb
& USART_CSRB_CSZ2
) ? 4 : 0);
59 usart
->char_mask
= 0b11111;
62 usart
->char_mask
= 0b111111;
65 usart
->char_mask
= 0b1111111;
68 usart
->char_mask
= 0b11111111;
77 "%s: Reserved character size 0x%x\n",
84 "%s: Nine bit character size not supported (forcing eight)\n",
86 usart
->char_mask
= 0b11111111;
89 g_assert_not_reached();
93 static void avr_usart_reset(DeviceState
*dev
)
95 AVRUsartState
*usart
= AVR_USART(dev
);
96 usart
->data_valid
= false;
97 usart
->csra
= 0b00100000;
98 usart
->csrb
= 0b00000000;
99 usart
->csrc
= 0b00000110;
102 update_char_mask(usart
);
103 qemu_set_irq(usart
->rxc_irq
, 0);
104 qemu_set_irq(usart
->txc_irq
, 0);
105 qemu_set_irq(usart
->dre_irq
, 0);
108 static uint64_t avr_usart_read(void *opaque
, hwaddr addr
, unsigned int size
)
110 AVRUsartState
*usart
= opaque
;
114 if (!usart
->enabled
) {
120 if (!(usart
->csrb
& USART_CSRB_RXEN
)) {
121 /* Receiver disabled, ignore. */
124 if (usart
->data_valid
) {
125 data
= usart
->data
& usart
->char_mask
;
126 usart
->data_valid
= false;
130 usart
->csra
&= 0xff ^ USART_CSRA_RXC
;
131 qemu_set_irq(usart
->rxc_irq
, 0);
132 qemu_chr_fe_accept_input(&usart
->chr
);
147 "%s: Bad offset 0x%"HWADDR_PRIx
"\n",
154 static void avr_usart_write(void *opaque
, hwaddr addr
, uint64_t value
,
157 AVRUsartState
*usart
= opaque
;
160 assert((value
& 0xff) == value
);
163 if (!usart
->enabled
) {
169 if (!(usart
->csrb
& USART_CSRB_TXEN
)) {
170 /* Transmitter disabled, ignore. */
173 usart
->csra
|= USART_CSRA_TXC
;
174 usart
->csra
|= USART_CSRA_DRE
;
175 if (usart
->csrb
& USART_CSRB_TXCIE
) {
176 qemu_set_irq(usart
->txc_irq
, 1);
177 usart
->csra
&= 0xff ^ USART_CSRA_TXC
;
179 if (usart
->csrb
& USART_CSRB_DREIE
) {
180 qemu_set_irq(usart
->dre_irq
, 1);
183 qemu_chr_fe_write_all(&usart
->chr
, &data
, 1);
187 /* Mask read-only bits. */
188 value
= (value
& mask
) | (usart
->csra
& (0xff ^ mask
));
190 if (value
& USART_CSRA_TXC
) {
191 usart
->csra
^= USART_CSRA_TXC
;
192 qemu_set_irq(usart
->txc_irq
, 0);
194 if (value
& USART_CSRA_MPCM
) {
197 "%s: MPCM not supported by USART\n",
203 /* Mask read-only bits. */
204 value
= (value
& mask
) | (usart
->csrb
& (0xff ^ mask
));
206 if (!(value
& USART_CSRB_RXEN
)) {
207 /* Receiver disabled, flush input buffer. */
208 usart
->data_valid
= false;
210 qemu_set_irq(usart
->rxc_irq
,
211 ((value
& USART_CSRB_RXCIE
) &&
212 (usart
->csra
& USART_CSRA_RXC
)) ? 1 : 0);
213 qemu_set_irq(usart
->txc_irq
,
214 ((value
& USART_CSRB_TXCIE
) &&
215 (usart
->csra
& USART_CSRA_TXC
)) ? 1 : 0);
216 qemu_set_irq(usart
->dre_irq
,
217 ((value
& USART_CSRB_DREIE
) &&
218 (usart
->csra
& USART_CSRA_DRE
)) ? 1 : 0);
219 update_char_mask(usart
);
223 if ((value
& USART_CSRC_MSEL1
) && (value
& USART_CSRC_MSEL0
)) {
226 "%s: SPI mode not supported by USART\n",
229 if ((value
& USART_CSRC_MSEL1
) && !(value
& USART_CSRC_MSEL0
)) {
230 qemu_log_mask(LOG_GUEST_ERROR
, "%s: Bad USART mode\n", __func__
);
232 if (!(value
& USART_CSRC_PM1
) && (value
& USART_CSRC_PM0
)) {
235 "%s: Bad USART parity mode\n",
238 update_char_mask(usart
);
244 usart
->brrh
= value
& 0b00001111;
249 "%s: Bad offset 0x%"HWADDR_PRIx
"\n",
255 static const MemoryRegionOps avr_usart_ops
= {
256 .read
= avr_usart_read
,
257 .write
= avr_usart_write
,
258 .endianness
= DEVICE_NATIVE_ENDIAN
,
259 .impl
= {.min_access_size
= 1, .max_access_size
= 1}
262 static Property avr_usart_properties
[] = {
263 DEFINE_PROP_CHR("chardev", AVRUsartState
, chr
),
264 DEFINE_PROP_END_OF_LIST(),
267 static void avr_usart_pr(void *opaque
, int irq
, int level
)
269 AVRUsartState
*s
= AVR_USART(opaque
);
274 avr_usart_reset(DEVICE(s
));
278 static void avr_usart_init(Object
*obj
)
280 AVRUsartState
*s
= AVR_USART(obj
);
281 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->rxc_irq
);
282 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->dre_irq
);
283 sysbus_init_irq(SYS_BUS_DEVICE(obj
), &s
->txc_irq
);
284 memory_region_init_io(&s
->mmio
, obj
, &avr_usart_ops
, s
, TYPE_AVR_USART
, 7);
285 sysbus_init_mmio(SYS_BUS_DEVICE(obj
), &s
->mmio
);
286 qdev_init_gpio_in(DEVICE(s
), avr_usart_pr
, 1);
290 static void avr_usart_realize(DeviceState
*dev
, Error
**errp
)
292 AVRUsartState
*s
= AVR_USART(dev
);
293 qemu_chr_fe_set_handlers(&s
->chr
, avr_usart_can_receive
,
294 avr_usart_receive
, NULL
, NULL
,
296 avr_usart_reset(dev
);
299 static void avr_usart_class_init(ObjectClass
*klass
, void *data
)
301 DeviceClass
*dc
= DEVICE_CLASS(klass
);
303 device_class_set_legacy_reset(dc
, avr_usart_reset
);
304 device_class_set_props(dc
, avr_usart_properties
);
305 dc
->realize
= avr_usart_realize
;
308 static const TypeInfo avr_usart_info
= {
309 .name
= TYPE_AVR_USART
,
310 .parent
= TYPE_SYS_BUS_DEVICE
,
311 .instance_size
= sizeof(AVRUsartState
),
312 .instance_init
= avr_usart_init
,
313 .class_init
= avr_usart_class_init
,
316 static void avr_usart_register_types(void)
318 type_register_static(&avr_usart_info
);
321 type_init(avr_usart_register_types
)