puv3_dma.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. #include "hw.h"
  12. #include "sysbus.h"
  13. #undef DEBUG_PUV3
  14. #include "puv3.h"
  15. #define PUV3_DMA_CH_NR (6)
  16. #define PUV3_DMA_CH_MASK (0xff)
  17. #define PUV3_DMA_CH(offset) ((offset) >> 8)
  18. typedef struct {
  19. SysBusDevice busdev;
  20. MemoryRegion iomem;
  21. uint32_t reg_CFG[PUV3_DMA_CH_NR];
  22. } PUV3DMAState;
  23. static uint64_t puv3_dma_read(void *opaque, hwaddr offset,
  24. unsigned size)
  25. {
  26. PUV3DMAState *s = opaque;
  27. uint32_t ret = 0;
  28. assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
  29. switch (offset & PUV3_DMA_CH_MASK) {
  30. case 0x10:
  31. ret = s->reg_CFG[PUV3_DMA_CH(offset)];
  32. break;
  33. default:
  34. DPRINTF("Bad offset 0x%x\n", offset);
  35. }
  36. DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
  37. return ret;
  38. }
  39. static void puv3_dma_write(void *opaque, hwaddr offset,
  40. uint64_t value, unsigned size)
  41. {
  42. PUV3DMAState *s = opaque;
  43. assert(PUV3_DMA_CH(offset) < PUV3_DMA_CH_NR);
  44. switch (offset & PUV3_DMA_CH_MASK) {
  45. case 0x10:
  46. s->reg_CFG[PUV3_DMA_CH(offset)] = value;
  47. break;
  48. default:
  49. DPRINTF("Bad offset 0x%x\n", offset);
  50. }
  51. DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
  52. }
  53. static const MemoryRegionOps puv3_dma_ops = {
  54. .read = puv3_dma_read,
  55. .write = puv3_dma_write,
  56. .impl = {
  57. .min_access_size = 4,
  58. .max_access_size = 4,
  59. },
  60. .endianness = DEVICE_NATIVE_ENDIAN,
  61. };
  62. static int puv3_dma_init(SysBusDevice *dev)
  63. {
  64. PUV3DMAState *s = FROM_SYSBUS(PUV3DMAState, dev);
  65. int i;
  66. for (i = 0; i < PUV3_DMA_CH_NR; i++) {
  67. s->reg_CFG[i] = 0x0;
  68. }
  69. memory_region_init_io(&s->iomem, &puv3_dma_ops, s, "puv3_dma",
  70. PUV3_REGS_OFFSET);
  71. sysbus_init_mmio(dev, &s->iomem);
  72. return 0;
  73. }
  74. static void puv3_dma_class_init(ObjectClass *klass, void *data)
  75. {
  76. SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
  77. sdc->init = puv3_dma_init;
  78. }
  79. static const TypeInfo puv3_dma_info = {
  80. .name = "puv3_dma",
  81. .parent = TYPE_SYS_BUS_DEVICE,
  82. .instance_size = sizeof(PUV3DMAState),
  83. .class_init = puv3_dma_class_init,
  84. };
  85. static void puv3_dma_register_type(void)
  86. {
  87. type_register_static(&puv3_dma_info);
  88. }
  89. type_init(puv3_dma_register_type)