1 | /* |
2 | * LatticeMico32 JTAG UART model. |
3 | * |
4 | * Copyright (c) 2010 Michael Walle <michael@walle.cc> |
5 | * |
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. |
10 | * |
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. |
15 | * |
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/>. |
18 | */ |
19 | |
20 | #include "qemu/osdep.h" |
21 | #include "hw/sysbus.h" |
22 | #include "migration/vmstate.h" |
23 | #include "qemu/module.h" |
24 | #include "trace.h" |
25 | #include "chardev/char-fe.h" |
26 | |
27 | #include "hw/char/lm32_juart.h" |
28 | #include "hw/qdev-properties.h" |
29 | |
30 | enum { |
31 | LM32_JUART_MIN_SAVE_VERSION = 0, |
32 | LM32_JUART_CURRENT_SAVE_VERSION = 0, |
33 | LM32_JUART_MAX_SAVE_VERSION = 0, |
34 | }; |
35 | |
36 | enum { |
37 | JTX_FULL = (1<<8), |
38 | }; |
39 | |
40 | enum { |
41 | JRX_FULL = (1<<8), |
42 | }; |
43 | |
44 | #define LM32_JUART(obj) OBJECT_CHECK(LM32JuartState, (obj), TYPE_LM32_JUART) |
45 | |
46 | struct LM32JuartState { |
47 | SysBusDevice parent_obj; |
48 | |
49 | CharBackend chr; |
50 | |
51 | uint32_t jtx; |
52 | uint32_t jrx; |
53 | }; |
54 | typedef struct LM32JuartState LM32JuartState; |
55 | |
56 | uint32_t lm32_juart_get_jtx(DeviceState *d) |
57 | { |
58 | LM32JuartState *s = LM32_JUART(d); |
59 | |
60 | trace_lm32_juart_get_jtx(s->jtx); |
61 | return s->jtx; |
62 | } |
63 | |
64 | uint32_t lm32_juart_get_jrx(DeviceState *d) |
65 | { |
66 | LM32JuartState *s = LM32_JUART(d); |
67 | |
68 | trace_lm32_juart_get_jrx(s->jrx); |
69 | return s->jrx; |
70 | } |
71 | |
72 | void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx) |
73 | { |
74 | LM32JuartState *s = LM32_JUART(d); |
75 | unsigned char ch = jtx & 0xff; |
76 | |
77 | trace_lm32_juart_set_jtx(s->jtx); |
78 | |
79 | s->jtx = jtx; |
80 | /* XXX this blocks entire thread. Rewrite to use |
81 | * qemu_chr_fe_write and background I/O callbacks */ |
82 | qemu_chr_fe_write_all(&s->chr, &ch, 1); |
83 | } |
84 | |
85 | void lm32_juart_set_jrx(DeviceState *d, uint32_t jtx) |
86 | { |
87 | LM32JuartState *s = LM32_JUART(d); |
88 | |
89 | trace_lm32_juart_set_jrx(s->jrx); |
90 | s->jrx &= ~JRX_FULL; |
91 | } |
92 | |
93 | static void juart_rx(void *opaque, const uint8_t *buf, int size) |
94 | { |
95 | LM32JuartState *s = opaque; |
96 | |
97 | s->jrx = *buf | JRX_FULL; |
98 | } |
99 | |
100 | static int juart_can_rx(void *opaque) |
101 | { |
102 | LM32JuartState *s = opaque; |
103 | |
104 | return !(s->jrx & JRX_FULL); |
105 | } |
106 | |
107 | static void juart_event(void *opaque, int event) |
108 | { |
109 | } |
110 | |
111 | static void juart_reset(DeviceState *d) |
112 | { |
113 | LM32JuartState *s = LM32_JUART(d); |
114 | |
115 | s->jtx = 0; |
116 | s->jrx = 0; |
117 | } |
118 | |
119 | static void lm32_juart_realize(DeviceState *dev, Error **errp) |
120 | { |
121 | LM32JuartState *s = LM32_JUART(dev); |
122 | |
123 | qemu_chr_fe_set_handlers(&s->chr, juart_can_rx, juart_rx, |
124 | juart_event, NULL, s, NULL, true); |
125 | } |
126 | |
127 | static const VMStateDescription vmstate_lm32_juart = { |
128 | .name = "lm32-juart" , |
129 | .version_id = 1, |
130 | .minimum_version_id = 1, |
131 | .fields = (VMStateField[]) { |
132 | VMSTATE_UINT32(jtx, LM32JuartState), |
133 | VMSTATE_UINT32(jrx, LM32JuartState), |
134 | VMSTATE_END_OF_LIST() |
135 | } |
136 | }; |
137 | |
138 | static Property lm32_juart_properties[] = { |
139 | DEFINE_PROP_CHR("chardev" , LM32JuartState, chr), |
140 | DEFINE_PROP_END_OF_LIST(), |
141 | }; |
142 | |
143 | static void lm32_juart_class_init(ObjectClass *klass, void *data) |
144 | { |
145 | DeviceClass *dc = DEVICE_CLASS(klass); |
146 | |
147 | dc->reset = juart_reset; |
148 | dc->vmsd = &vmstate_lm32_juart; |
149 | dc->props = lm32_juart_properties; |
150 | dc->realize = lm32_juart_realize; |
151 | } |
152 | |
153 | static const TypeInfo lm32_juart_info = { |
154 | .name = TYPE_LM32_JUART, |
155 | .parent = TYPE_SYS_BUS_DEVICE, |
156 | .instance_size = sizeof(LM32JuartState), |
157 | .class_init = lm32_juart_class_init, |
158 | }; |
159 | |
160 | static void lm32_juart_register_types(void) |
161 | { |
162 | type_register_static(&lm32_juart_info); |
163 | } |
164 | |
165 | type_init(lm32_juart_register_types) |
166 | |