qemu/hw/core/fdt_generic_devices_serial.c
<<
>>
Prefs
   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/* Piggy back fdt_generic_util.c ERR_DEBUG symbol as these two are really the
  18 * same feature
  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    /* FIXME: Pass in dynamically */
  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    /* FIXME: respect #address and size cells */
  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; /* qemu uart16550 model starts with 3* 8bit offset */
  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    /* it_shift = 2, reg-shift in DTS - for Xilnx IP is hardcoded */
  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