1#include "qemu/osdep.h"
2#include "hw/fdt_generic_util.h"
3#include "hw/fdt_generic_devices.h"
4#include "qom/object.h"
5#include "sysemu/blockdev.h"
6#include "sysemu/sysemu.h"
7#include "exec/memory.h"
8#include "exec/address-spaces.h"
9#include "qemu/log.h"
10#include "qapi/error.h"
11#include "chardev/char.h"
12#include "qemu/coroutine.h"
13
14#include "hw/char/serial.h"
15#include "hw/qdev-core.h"
16
17
18
19
20
21#ifndef FDT_GENERIC_UTIL_ERR_DEBUG
22#define FDT_GENERIC_UTIL_ERR_DEBUG 0
23#endif
24#define DB_PRINT(lvl, ...) do { \
25 if (FDT_GENERIC_UTIL_ERR_DEBUG > (lvl)) { \
26 qemu_log_mask(lvl, ": %s: ", __func__); \
27 qemu_log_mask(lvl, ## __VA_ARGS__); \
28 } \
29} while (0);
30
31#define DB_PRINT_NP(lvl, ...) do { \
32 if (FDT_GENERIC_UTIL_ERR_DEBUG > (lvl)) { \
33 qemu_log_mask(lvl, "%s", node_path); \
34 DB_PRINT((lvl), ## __VA_ARGS__); \
35 } \
36} while (0);
37
38static int uart16550_fdt_init(char *node_path, FDTMachineInfo *fdti,
39 void *priv)
40{
41
42 MemoryRegion *address_space_mem = get_system_memory();
43 hwaddr base;
44 uint32_t baudrate;
45 qemu_irq irqline;
46 bool map_mode;
47 char irq_info[1024];
48 Error *err = NULL;
49
50
51 base = qemu_fdt_getprop_cell(fdti->fdt, node_path, "reg", 0,
52 false, &error_abort);
53 base += qemu_fdt_getprop_cell(fdti->fdt, node_path, "reg-offset", 0,
54 false, &error_abort);
55 base &= ~3ULL;
56
57 baudrate = qemu_fdt_getprop_cell(fdti->fdt, node_path, "current-speed",
58 0, false, &err);
59 if (err) {
60 baudrate = 115200;
61 }
62
63 irqline = *fdt_get_irq_info(fdti, node_path, 0, irq_info, &map_mode);
64 assert(!map_mode);
65 DB_PRINT_NP(0, "UART16550a: baseaddr: 0x" TARGET_FMT_plx
66 ", irq: %s, baud %d\n", base, irq_info, baudrate);
67
68
69 serial_mm_init(address_space_mem, base, 2, irqline, baudrate,
70 serial_hd(fdt_serial_ports), DEVICE_LITTLE_ENDIAN);
71 return 0;
72}
73
74fdt_register_compatibility_n(uart16550_fdt_init, "compatible:ns16550", 0);
75fdt_register_compatibility_n(uart16550_fdt_init, "compatible:ns16550a", 1);
76