]> git.proxmox.com Git - mirror_qemu.git/blame - hw/char/ibex_uart.c
Merge tag 'pull-riscv-to-apply-20230224' of github.com:palmer-dabbelt/qemu into staging
[mirror_qemu.git] / hw / char / ibex_uart.c
CommitLineData
a7d2d98c
AF
1/*
2 * QEMU lowRISC Ibex UART device
3 *
4 * Copyright (c) 2020 Western Digital
5 *
6 * For details check the documentation here:
7 * https://docs.opentitan.org/hw/ip/uart/doc/
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28#include "qemu/osdep.h"
29#include "hw/char/ibex_uart.h"
30#include "hw/irq.h"
940aabb9 31#include "hw/qdev-clock.h"
a7d2d98c 32#include "hw/qdev-properties.h"
ce35e229 33#include "hw/qdev-properties-system.h"
8c6631e6 34#include "hw/registerfields.h"
a7d2d98c
AF
35#include "migration/vmstate.h"
36#include "qemu/log.h"
37#include "qemu/module.h"
38
bdc36ce6
AF
39REG32(INTR_STATE, 0x00)
40 FIELD(INTR_STATE, TX_WATERMARK, 0, 1)
41 FIELD(INTR_STATE, RX_WATERMARK, 1, 1)
42 FIELD(INTR_STATE, TX_EMPTY, 2, 1)
43 FIELD(INTR_STATE, RX_OVERFLOW, 3, 1)
44REG32(INTR_ENABLE, 0x04)
45REG32(INTR_TEST, 0x08)
24bfb98d
AF
46REG32(ALERT_TEST, 0x0C)
47REG32(CTRL, 0x10)
bdc36ce6
AF
48 FIELD(CTRL, TX_ENABLE, 0, 1)
49 FIELD(CTRL, RX_ENABLE, 1, 1)
50 FIELD(CTRL, NF, 2, 1)
51 FIELD(CTRL, SLPBK, 4, 1)
52 FIELD(CTRL, LLPBK, 5, 1)
53 FIELD(CTRL, PARITY_EN, 6, 1)
54 FIELD(CTRL, PARITY_ODD, 7, 1)
55 FIELD(CTRL, RXBLVL, 8, 2)
56 FIELD(CTRL, NCO, 16, 16)
24bfb98d 57REG32(STATUS, 0x14)
bdc36ce6
AF
58 FIELD(STATUS, TXFULL, 0, 1)
59 FIELD(STATUS, RXFULL, 1, 1)
60 FIELD(STATUS, TXEMPTY, 2, 1)
61 FIELD(STATUS, RXIDLE, 4, 1)
62 FIELD(STATUS, RXEMPTY, 5, 1)
24bfb98d
AF
63REG32(RDATA, 0x18)
64REG32(WDATA, 0x1C)
65REG32(FIFO_CTRL, 0x20)
bdc36ce6
AF
66 FIELD(FIFO_CTRL, RXRST, 0, 1)
67 FIELD(FIFO_CTRL, TXRST, 1, 1)
68 FIELD(FIFO_CTRL, RXILVL, 2, 3)
69 FIELD(FIFO_CTRL, TXILVL, 5, 2)
24bfb98d 70REG32(FIFO_STATUS, 0x24)
bdc36ce6
AF
71 FIELD(FIFO_STATUS, TXLVL, 0, 5)
72 FIELD(FIFO_STATUS, RXLVL, 16, 5)
24bfb98d
AF
73REG32(OVRD, 0x28)
74REG32(VAL, 0x2C)
75REG32(TIMEOUT_CTRL, 0x30)
bdc36ce6 76
a7d2d98c
AF
77static void ibex_uart_update_irqs(IbexUartState *s)
78{
59093cc4 79 if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_WATERMARK_MASK) {
a7d2d98c
AF
80 qemu_set_irq(s->tx_watermark, 1);
81 } else {
82 qemu_set_irq(s->tx_watermark, 0);
83 }
84
59093cc4 85 if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_RX_WATERMARK_MASK) {
a7d2d98c
AF
86 qemu_set_irq(s->rx_watermark, 1);
87 } else {
88 qemu_set_irq(s->rx_watermark, 0);
89 }
90
59093cc4 91 if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_EMPTY_MASK) {
a7d2d98c
AF
92 qemu_set_irq(s->tx_empty, 1);
93 } else {
94 qemu_set_irq(s->tx_empty, 0);
95 }
96
59093cc4 97 if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_RX_OVERFLOW_MASK) {
a7d2d98c
AF
98 qemu_set_irq(s->rx_overflow, 1);
99 } else {
100 qemu_set_irq(s->rx_overflow, 0);
101 }
102}
103
104static int ibex_uart_can_receive(void *opaque)
105{
106 IbexUartState *s = opaque;
107
82a4ed8e
AW
108 if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
109 && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
a7d2d98c
AF
110 return 1;
111 }
112
113 return 0;
114}
115
116static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
117{
118 IbexUartState *s = opaque;
59093cc4
AF
119 uint8_t rx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_RXILVL_MASK)
120 >> R_FIFO_CTRL_RXILVL_SHIFT;
a7d2d98c
AF
121
122 s->uart_rdata = *buf;
123
59093cc4
AF
124 s->uart_status &= ~R_STATUS_RXIDLE_MASK;
125 s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
82a4ed8e
AW
126 /* The RXFULL is set after receiving a single byte
127 * as the FIFO buffers are not yet implemented.
128 */
129 s->uart_status |= R_STATUS_RXFULL_MASK;
130 s->rx_level += 1;
a7d2d98c
AF
131
132 if (size > rx_fifo_level) {
59093cc4 133 s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
a7d2d98c
AF
134 }
135
136 ibex_uart_update_irqs(s);
137}
138
bf7b1eab 139static gboolean ibex_uart_xmit(void *do_not_use, GIOCondition cond,
a7d2d98c
AF
140 void *opaque)
141{
142 IbexUartState *s = opaque;
59093cc4
AF
143 uint8_t tx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_TXILVL_MASK)
144 >> R_FIFO_CTRL_TXILVL_SHIFT;
a7d2d98c
AF
145 int ret;
146
147 /* instant drain the fifo when there's no back-end */
148 if (!qemu_chr_fe_backend_connected(&s->chr)) {
149 s->tx_level = 0;
150 return FALSE;
151 }
152
153 if (!s->tx_level) {
59093cc4
AF
154 s->uart_status &= ~R_STATUS_TXFULL_MASK;
155 s->uart_status |= R_STATUS_TXEMPTY_MASK;
156 s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK;
157 s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK;
a7d2d98c
AF
158 ibex_uart_update_irqs(s);
159 return FALSE;
160 }
161
162 ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
163
164 if (ret >= 0) {
165 s->tx_level -= ret;
166 memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_level);
167 }
168
169 if (s->tx_level) {
170 guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
171 ibex_uart_xmit, s);
172 if (!r) {
173 s->tx_level = 0;
174 return FALSE;
175 }
176 }
177
178 /* Clear the TX Full bit */
179 if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) {
59093cc4 180 s->uart_status &= ~R_STATUS_TXFULL_MASK;
a7d2d98c
AF
181 }
182
183 /* Disable the TX_WATERMARK IRQ */
184 if (s->tx_level < tx_fifo_level) {
59093cc4 185 s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK;
a7d2d98c
AF
186 }
187
188 /* Set TX empty */
189 if (s->tx_level == 0) {
59093cc4
AF
190 s->uart_status |= R_STATUS_TXEMPTY_MASK;
191 s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK;
a7d2d98c
AF
192 }
193
194 ibex_uart_update_irqs(s);
195 return FALSE;
196}
197
198static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
199 int size)
200{
201 uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
59093cc4
AF
202 uint8_t tx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_TXILVL_MASK)
203 >> R_FIFO_CTRL_TXILVL_SHIFT;
a7d2d98c
AF
204
205 if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) {
206 size = IBEX_UART_TX_FIFO_SIZE - s->tx_level;
207 qemu_log_mask(LOG_GUEST_ERROR, "ibex_uart: TX FIFO overflow");
208 }
209
210 memcpy(s->tx_fifo + s->tx_level, buf, size);
211 s->tx_level += size;
212
213 if (s->tx_level > 0) {
59093cc4 214 s->uart_status &= ~R_STATUS_TXEMPTY_MASK;
a7d2d98c
AF
215 }
216
217 if (s->tx_level >= tx_fifo_level) {
59093cc4 218 s->uart_intr_state |= R_INTR_STATE_TX_WATERMARK_MASK;
a7d2d98c
AF
219 ibex_uart_update_irqs(s);
220 }
221
222 if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) {
59093cc4 223 s->uart_status |= R_STATUS_TXFULL_MASK;
a7d2d98c
AF
224 }
225
226 timer_mod(s->fifo_trigger_handle, current_time +
227 (s->char_tx_time * 4));
228}
229
230static void ibex_uart_reset(DeviceState *dev)
231{
232 IbexUartState *s = IBEX_UART(dev);
233
234 s->uart_intr_state = 0x00000000;
235 s->uart_intr_state = 0x00000000;
236 s->uart_intr_enable = 0x00000000;
237 s->uart_ctrl = 0x00000000;
238 s->uart_status = 0x0000003c;
239 s->uart_rdata = 0x00000000;
240 s->uart_fifo_ctrl = 0x00000000;
241 s->uart_fifo_status = 0x00000000;
242 s->uart_ovrd = 0x00000000;
243 s->uart_val = 0x00000000;
244 s->uart_timeout_ctrl = 0x00000000;
245
246 s->tx_level = 0;
82a4ed8e 247 s->rx_level = 0;
a7d2d98c
AF
248
249 s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
250
251 ibex_uart_update_irqs(s);
252}
253
940aabb9
AF
254static uint64_t ibex_uart_get_baud(IbexUartState *s)
255{
256 uint64_t baud;
257
59093cc4 258 baud = ((s->uart_ctrl & R_CTRL_NCO_MASK) >> 16);
940aabb9
AF
259 baud *= clock_get_hz(s->f_clk);
260 baud >>= 20;
261
262 return baud;
263}
264
a7d2d98c
AF
265static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
266 unsigned int size)
267{
268 IbexUartState *s = opaque;
269 uint64_t retvalue = 0;
270
59093cc4
AF
271 switch (addr >> 2) {
272 case R_INTR_STATE:
a7d2d98c
AF
273 retvalue = s->uart_intr_state;
274 break;
59093cc4 275 case R_INTR_ENABLE:
a7d2d98c
AF
276 retvalue = s->uart_intr_enable;
277 break;
59093cc4 278 case R_INTR_TEST:
a7d2d98c
AF
279 qemu_log_mask(LOG_GUEST_ERROR,
280 "%s: wdata is write only\n", __func__);
281 break;
282
59093cc4 283 case R_CTRL:
a7d2d98c
AF
284 retvalue = s->uart_ctrl;
285 break;
59093cc4 286 case R_STATUS:
a7d2d98c
AF
287 retvalue = s->uart_status;
288 break;
289
59093cc4 290 case R_RDATA:
a7d2d98c 291 retvalue = s->uart_rdata;
82a4ed8e 292 if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
a7d2d98c
AF
293 qemu_chr_fe_accept_input(&s->chr);
294
82a4ed8e
AW
295 s->rx_level -= 1;
296 s->uart_status &= ~R_STATUS_RXFULL_MASK;
297 if (s->rx_level == 0) {
298 s->uart_status |= R_STATUS_RXIDLE_MASK;
299 s->uart_status |= R_STATUS_RXEMPTY_MASK;
300 }
a7d2d98c
AF
301 }
302 break;
59093cc4 303 case R_WDATA:
a7d2d98c
AF
304 qemu_log_mask(LOG_GUEST_ERROR,
305 "%s: wdata is write only\n", __func__);
306 break;
307
59093cc4 308 case R_FIFO_CTRL:
a7d2d98c
AF
309 retvalue = s->uart_fifo_ctrl;
310 break;
59093cc4 311 case R_FIFO_STATUS:
a7d2d98c
AF
312 retvalue = s->uart_fifo_status;
313
82a4ed8e
AW
314 retvalue |= (s->rx_level & 0x1F) << R_FIFO_STATUS_RXLVL_SHIFT;
315 retvalue |= (s->tx_level & 0x1F) << R_FIFO_STATUS_TXLVL_SHIFT;
a7d2d98c
AF
316
317 qemu_log_mask(LOG_UNIMP,
318 "%s: RX fifos are not supported\n", __func__);
319 break;
320
59093cc4 321 case R_OVRD:
a7d2d98c
AF
322 retvalue = s->uart_ovrd;
323 qemu_log_mask(LOG_UNIMP,
324 "%s: ovrd is not supported\n", __func__);
325 break;
59093cc4 326 case R_VAL:
a7d2d98c
AF
327 retvalue = s->uart_val;
328 qemu_log_mask(LOG_UNIMP,
329 "%s: val is not supported\n", __func__);
330 break;
59093cc4 331 case R_TIMEOUT_CTRL:
a7d2d98c
AF
332 retvalue = s->uart_timeout_ctrl;
333 qemu_log_mask(LOG_UNIMP,
334 "%s: timeout_ctrl is not supported\n", __func__);
335 break;
336 default:
337 qemu_log_mask(LOG_GUEST_ERROR,
338 "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
339 return 0;
340 }
341
342 return retvalue;
343}
344
345static void ibex_uart_write(void *opaque, hwaddr addr,
346 uint64_t val64, unsigned int size)
347{
348 IbexUartState *s = opaque;
349 uint32_t value = val64;
350
59093cc4
AF
351 switch (addr >> 2) {
352 case R_INTR_STATE:
a7d2d98c
AF
353 /* Write 1 clear */
354 s->uart_intr_state &= ~value;
355 ibex_uart_update_irqs(s);
356 break;
59093cc4 357 case R_INTR_ENABLE:
a7d2d98c
AF
358 s->uart_intr_enable = value;
359 ibex_uart_update_irqs(s);
360 break;
59093cc4 361 case R_INTR_TEST:
a7d2d98c
AF
362 s->uart_intr_state |= value;
363 ibex_uart_update_irqs(s);
364 break;
365
59093cc4 366 case R_CTRL:
a7d2d98c
AF
367 s->uart_ctrl = value;
368
59093cc4 369 if (value & R_CTRL_NF_MASK) {
a7d2d98c
AF
370 qemu_log_mask(LOG_UNIMP,
371 "%s: UART_CTRL_NF is not supported\n", __func__);
372 }
59093cc4 373 if (value & R_CTRL_SLPBK_MASK) {
a7d2d98c
AF
374 qemu_log_mask(LOG_UNIMP,
375 "%s: UART_CTRL_SLPBK is not supported\n", __func__);
376 }
59093cc4 377 if (value & R_CTRL_LLPBK_MASK) {
a7d2d98c
AF
378 qemu_log_mask(LOG_UNIMP,
379 "%s: UART_CTRL_LLPBK is not supported\n", __func__);
380 }
59093cc4 381 if (value & R_CTRL_PARITY_EN_MASK) {
a7d2d98c
AF
382 qemu_log_mask(LOG_UNIMP,
383 "%s: UART_CTRL_PARITY_EN is not supported\n",
384 __func__);
385 }
59093cc4 386 if (value & R_CTRL_PARITY_ODD_MASK) {
a7d2d98c
AF
387 qemu_log_mask(LOG_UNIMP,
388 "%s: UART_CTRL_PARITY_ODD is not supported\n",
389 __func__);
390 }
59093cc4 391 if (value & R_CTRL_RXBLVL_MASK) {
a7d2d98c
AF
392 qemu_log_mask(LOG_UNIMP,
393 "%s: UART_CTRL_RXBLVL is not supported\n", __func__);
394 }
59093cc4 395 if (value & R_CTRL_NCO_MASK) {
940aabb9 396 uint64_t baud = ibex_uart_get_baud(s);
a7d2d98c
AF
397
398 s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
399 }
400 break;
59093cc4 401 case R_STATUS:
a7d2d98c
AF
402 qemu_log_mask(LOG_GUEST_ERROR,
403 "%s: status is read only\n", __func__);
404 break;
405
59093cc4 406 case R_RDATA:
a7d2d98c
AF
407 qemu_log_mask(LOG_GUEST_ERROR,
408 "%s: rdata is read only\n", __func__);
409 break;
59093cc4 410 case R_WDATA:
a7d2d98c
AF
411 uart_write_tx_fifo(s, (uint8_t *) &value, 1);
412 break;
413
59093cc4 414 case R_FIFO_CTRL:
a7d2d98c
AF
415 s->uart_fifo_ctrl = value;
416
59093cc4 417 if (value & R_FIFO_CTRL_RXRST_MASK) {
82a4ed8e 418 s->rx_level = 0;
a7d2d98c
AF
419 qemu_log_mask(LOG_UNIMP,
420 "%s: RX fifos are not supported\n", __func__);
421 }
59093cc4 422 if (value & R_FIFO_CTRL_TXRST_MASK) {
a7d2d98c
AF
423 s->tx_level = 0;
424 }
425 break;
59093cc4 426 case R_FIFO_STATUS:
a7d2d98c
AF
427 qemu_log_mask(LOG_GUEST_ERROR,
428 "%s: fifo_status is read only\n", __func__);
429 break;
430
59093cc4 431 case R_OVRD:
a7d2d98c
AF
432 s->uart_ovrd = value;
433 qemu_log_mask(LOG_UNIMP,
434 "%s: ovrd is not supported\n", __func__);
435 break;
59093cc4 436 case R_VAL:
a7d2d98c
AF
437 qemu_log_mask(LOG_GUEST_ERROR,
438 "%s: val is read only\n", __func__);
439 break;
59093cc4 440 case R_TIMEOUT_CTRL:
a7d2d98c
AF
441 s->uart_timeout_ctrl = value;
442 qemu_log_mask(LOG_UNIMP,
443 "%s: timeout_ctrl is not supported\n", __func__);
444 break;
445 default:
446 qemu_log_mask(LOG_GUEST_ERROR,
447 "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
448 }
449}
450
5ee0abed 451static void ibex_uart_clk_update(void *opaque, ClockEvent event)
940aabb9
AF
452{
453 IbexUartState *s = opaque;
454
455 /* recompute uart's speed on clock change */
456 uint64_t baud = ibex_uart_get_baud(s);
457
458 s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
459}
460
a7d2d98c
AF
461static void fifo_trigger_update(void *opaque)
462{
463 IbexUartState *s = opaque;
464
59093cc4 465 if (s->uart_ctrl & R_CTRL_TX_ENABLE_MASK) {
a7d2d98c
AF
466 ibex_uart_xmit(NULL, G_IO_OUT, s);
467 }
468}
469
470static const MemoryRegionOps ibex_uart_ops = {
471 .read = ibex_uart_read,
472 .write = ibex_uart_write,
473 .endianness = DEVICE_NATIVE_ENDIAN,
474 .impl.min_access_size = 4,
475 .impl.max_access_size = 4,
476};
477
478static int ibex_uart_post_load(void *opaque, int version_id)
479{
480 IbexUartState *s = opaque;
481
482 ibex_uart_update_irqs(s);
483 return 0;
484}
485
486static const VMStateDescription vmstate_ibex_uart = {
487 .name = TYPE_IBEX_UART,
488 .version_id = 1,
489 .minimum_version_id = 1,
490 .post_load = ibex_uart_post_load,
491 .fields = (VMStateField[]) {
492 VMSTATE_UINT8_ARRAY(tx_fifo, IbexUartState,
493 IBEX_UART_TX_FIFO_SIZE),
494 VMSTATE_UINT32(tx_level, IbexUartState),
495 VMSTATE_UINT64(char_tx_time, IbexUartState),
496 VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexUartState),
497 VMSTATE_UINT32(uart_intr_state, IbexUartState),
498 VMSTATE_UINT32(uart_intr_enable, IbexUartState),
499 VMSTATE_UINT32(uart_ctrl, IbexUartState),
500 VMSTATE_UINT32(uart_status, IbexUartState),
501 VMSTATE_UINT32(uart_rdata, IbexUartState),
502 VMSTATE_UINT32(uart_fifo_ctrl, IbexUartState),
503 VMSTATE_UINT32(uart_fifo_status, IbexUartState),
504 VMSTATE_UINT32(uart_ovrd, IbexUartState),
505 VMSTATE_UINT32(uart_val, IbexUartState),
506 VMSTATE_UINT32(uart_timeout_ctrl, IbexUartState),
507 VMSTATE_END_OF_LIST()
508 }
509};
510
511static Property ibex_uart_properties[] = {
512 DEFINE_PROP_CHR("chardev", IbexUartState, chr),
513 DEFINE_PROP_END_OF_LIST(),
514};
515
516static void ibex_uart_init(Object *obj)
517{
518 IbexUartState *s = IBEX_UART(obj);
519
940aabb9 520 s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
5ee0abed 521 ibex_uart_clk_update, s, ClockUpdate);
940aabb9
AF
522 clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
523
a7d2d98c
AF
524 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
525 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark);
526 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty);
527 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_overflow);
528
529 memory_region_init_io(&s->mmio, obj, &ibex_uart_ops, s,
530 TYPE_IBEX_UART, 0x400);
531 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
532}
533
534static void ibex_uart_realize(DeviceState *dev, Error **errp)
535{
536 IbexUartState *s = IBEX_UART(dev);
537
538 s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
539 fifo_trigger_update, s);
540
541 qemu_chr_fe_set_handlers(&s->chr, ibex_uart_can_receive,
542 ibex_uart_receive, NULL, NULL,
543 s, NULL, true);
544}
545
546static void ibex_uart_class_init(ObjectClass *klass, void *data)
547{
548 DeviceClass *dc = DEVICE_CLASS(klass);
549
550 dc->reset = ibex_uart_reset;
551 dc->realize = ibex_uart_realize;
552 dc->vmsd = &vmstate_ibex_uart;
553 device_class_set_props(dc, ibex_uart_properties);
34229c46 554 set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
a7d2d98c
AF
555}
556
557static const TypeInfo ibex_uart_info = {
558 .name = TYPE_IBEX_UART,
559 .parent = TYPE_SYS_BUS_DEVICE,
560 .instance_size = sizeof(IbexUartState),
561 .instance_init = ibex_uart_init,
562 .class_init = ibex_uart_class_init,
563};
564
565static void ibex_uart_register_types(void)
566{
567 type_register_static(&ibex_uart_info);
568}
569
570type_init(ibex_uart_register_types)