qemu/hw/dma/puv3_dma.c
<<
>>
Prefs
   1/*
   2 * DMA device simulation in PKUnity SoC
   3 *
   4 * Copyright (C) 2010-2012 Guan Xuetao
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation, or any later version.
   9 * See the COPYING file in the top-level directory.
  10 */
  11
  12#include "qemu/osdep.h"
  13#include "hw/sysbus.h"
  14#include "qom/object.h"
  15
  16#undef DEBUG_PUV3
  17#include "hw/unicore32/puv3.h"
  18#include "qemu/module.h"
  19#include "qemu/log.h"
  20
  21#define PUV3_DMA_CH_NR          (6)
  22#define PUV3_DMA_CH_MASK        (0xff)
  23#define PUV3_DMA_CH(offset)     ((offset) >> 8)
  24
  25#define TYPE_PUV3_DMA "puv3_dma"
  26OBJECT_DECLARE_SIMPLE_TYPE(PUV3DMAState, PUV3_DMA)
  27
  28struct PUV3DMAState {
  29    SysBusDevice parent_obj;
  30
  31    MemoryRegion iomem;
  32    uint32_t reg_CFG[PUV3_DMA_CH_NR];
  33};
  34
  35static uint64_t puv3_dma_read(void *opaque, hwaddr offset,
  36        unsigned size)
  37{
  38    PUV3DMAState *s = opaque;
  39    uint32_t ret = 0;
  40
  41    assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
  42
  43    switch (offset & PUV3_DMA_CH_MASK) {
  44    case 0x10:
  45        ret = s->reg_CFG[PUV3_DMA_CH(offset)];
  46        break;
  47    default:
  48        qemu_log_mask(LOG_GUEST_ERROR,
  49                      "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
  50                      __func__, offset);
  51    }
  52    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
  53
  54    return ret;
  55}
  56
  57static void puv3_dma_write(void *opaque, hwaddr offset,
  58        uint64_t value, unsigned size)
  59{
  60    PUV3DMAState *s = opaque;
  61
  62    assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
  63
  64    switch (offset & PUV3_DMA_CH_MASK) {
  65    case 0x10:
  66        s->reg_CFG[PUV3_DMA_CH(offset)] = value;
  67        break;
  68    default:
  69        qemu_log_mask(LOG_GUEST_ERROR,
  70                      "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
  71                      __func__, offset);
  72    }
  73    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
  74}
  75
  76static const MemoryRegionOps puv3_dma_ops = {
  77    .read = puv3_dma_read,
  78    .write = puv3_dma_write,
  79    .impl = {
  80        .min_access_size = 4,
  81        .max_access_size = 4,
  82    },
  83    .endianness = DEVICE_NATIVE_ENDIAN,
  84};
  85
  86static void puv3_dma_realize(DeviceState *dev, Error **errp)
  87{
  88    PUV3DMAState *s = PUV3_DMA(dev);
  89    int i;
  90
  91    for (i = 0; i < PUV3_DMA_CH_NR; i++) {
  92        s->reg_CFG[i] = 0x0;
  93    }
  94
  95    memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma",
  96            PUV3_REGS_OFFSET);
  97    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
  98}
  99
 100static void puv3_dma_class_init(ObjectClass *klass, void *data)
 101{
 102    DeviceClass *dc = DEVICE_CLASS(klass);
 103
 104    dc->realize = puv3_dma_realize;
 105}
 106
 107static const TypeInfo puv3_dma_info = {
 108    .name = TYPE_PUV3_DMA,
 109    .parent = TYPE_SYS_BUS_DEVICE,
 110    .instance_size = sizeof(PUV3DMAState),
 111    .class_init = puv3_dma_class_init,
 112};
 113
 114static void puv3_dma_register_type(void)
 115{
 116    type_register_static(&puv3_dma_info);
 117}
 118
 119type_init(puv3_dma_register_type)
 120