1 | /* |
2 | * ARM CMSDK APB UART emulation |
3 | * |
4 | * Copyright (c) 2017 Linaro Limited |
5 | * Written by Peter Maydell |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 or |
9 | * (at your option) any later version. |
10 | */ |
11 | |
12 | #ifndef CMSDK_APB_UART_H |
13 | #define CMSDK_APB_UART_H |
14 | |
15 | #include "hw/qdev-properties.h" |
16 | #include "hw/sysbus.h" |
17 | #include "chardev/char-fe.h" |
18 | |
19 | #define TYPE_CMSDK_APB_UART "cmsdk-apb-uart" |
20 | #define CMSDK_APB_UART(obj) OBJECT_CHECK(CMSDKAPBUART, (obj), \ |
21 | TYPE_CMSDK_APB_UART) |
22 | |
23 | typedef struct { |
24 | /*< private >*/ |
25 | SysBusDevice parent_obj; |
26 | |
27 | /*< public >*/ |
28 | MemoryRegion iomem; |
29 | CharBackend chr; |
30 | qemu_irq txint; |
31 | qemu_irq rxint; |
32 | qemu_irq txovrint; |
33 | qemu_irq rxovrint; |
34 | qemu_irq uartint; |
35 | guint watch_tag; |
36 | uint32_t pclk_frq; |
37 | |
38 | uint32_t state; |
39 | uint32_t ctrl; |
40 | uint32_t intstatus; |
41 | uint32_t bauddiv; |
42 | /* This UART has no FIFO, only a 1-character buffer for each of Tx and Rx */ |
43 | uint8_t txbuf; |
44 | uint8_t rxbuf; |
45 | } CMSDKAPBUART; |
46 | |
47 | /** |
48 | * cmsdk_apb_uart_create - convenience function to create TYPE_CMSDK_APB_UART |
49 | * @addr: location in system memory to map registers |
50 | * @chr: Chardev backend to connect UART to, or NULL if no backend |
51 | * @pclk_frq: frequency in Hz of the PCLK clock (used for calculating baud rate) |
52 | */ |
53 | static inline DeviceState *cmsdk_apb_uart_create(hwaddr addr, |
54 | qemu_irq txint, |
55 | qemu_irq rxint, |
56 | qemu_irq txovrint, |
57 | qemu_irq rxovrint, |
58 | qemu_irq uartint, |
59 | Chardev *chr, |
60 | uint32_t pclk_frq) |
61 | { |
62 | DeviceState *dev; |
63 | SysBusDevice *s; |
64 | |
65 | dev = qdev_create(NULL, TYPE_CMSDK_APB_UART); |
66 | s = SYS_BUS_DEVICE(dev); |
67 | qdev_prop_set_chr(dev, "chardev" , chr); |
68 | qdev_prop_set_uint32(dev, "pclk-frq" , pclk_frq); |
69 | qdev_init_nofail(dev); |
70 | sysbus_mmio_map(s, 0, addr); |
71 | sysbus_connect_irq(s, 0, txint); |
72 | sysbus_connect_irq(s, 1, rxint); |
73 | sysbus_connect_irq(s, 2, txovrint); |
74 | sysbus_connect_irq(s, 3, rxovrint); |
75 | sysbus_connect_irq(s, 4, uartint); |
76 | return dev; |
77 | } |
78 | |
79 | #endif |
80 | |