2
0

djmemc.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * djMEMC, macintosh memory and interrupt controller
  3. * (Quadra 610/650/800 & Centris 610/650)
  4. *
  5. * https://mac68k.info/wiki/display/mac68k/djMEMC+Information
  6. *
  7. * SPDX-License-Identifier: GPL-2.0-or-later
  8. */
  9. #include "qemu/osdep.h"
  10. #include "qemu/log.h"
  11. #include "migration/vmstate.h"
  12. #include "hw/misc/djmemc.h"
  13. #include "hw/qdev-properties.h"
  14. #include "trace.h"
  15. #define DJMEMC_INTERLEAVECONF 0x0
  16. #define DJMEMC_BANK0CONF 0x4
  17. #define DJMEMC_BANK1CONF 0x8
  18. #define DJMEMC_BANK2CONF 0xc
  19. #define DJMEMC_BANK3CONF 0x10
  20. #define DJMEMC_BANK4CONF 0x14
  21. #define DJMEMC_BANK5CONF 0x18
  22. #define DJMEMC_BANK6CONF 0x1c
  23. #define DJMEMC_BANK7CONF 0x20
  24. #define DJMEMC_BANK8CONF 0x24
  25. #define DJMEMC_BANK9CONF 0x28
  26. #define DJMEMC_MEMTOP 0x2c
  27. #define DJMEMC_CONFIG 0x30
  28. #define DJMEMC_REFRESH 0x34
  29. static uint64_t djmemc_read(void *opaque, hwaddr addr, unsigned size)
  30. {
  31. DJMEMCState *s = opaque;
  32. uint64_t val = 0;
  33. switch (addr) {
  34. case DJMEMC_INTERLEAVECONF:
  35. case DJMEMC_BANK0CONF ... DJMEMC_BANK9CONF:
  36. case DJMEMC_MEMTOP:
  37. case DJMEMC_CONFIG:
  38. case DJMEMC_REFRESH:
  39. val = s->regs[addr >> 2];
  40. break;
  41. default:
  42. qemu_log_mask(LOG_UNIMP, "djMEMC: unimplemented read addr=0x%"PRIx64
  43. " val=0x%"PRIx64 " size=%d\n",
  44. addr, val, size);
  45. }
  46. trace_djmemc_read(addr, val, size);
  47. return val;
  48. }
  49. static void djmemc_write(void *opaque, hwaddr addr, uint64_t val,
  50. unsigned size)
  51. {
  52. DJMEMCState *s = opaque;
  53. trace_djmemc_write(addr, val, size);
  54. switch (addr) {
  55. case DJMEMC_INTERLEAVECONF:
  56. case DJMEMC_BANK0CONF ... DJMEMC_BANK9CONF:
  57. case DJMEMC_MEMTOP:
  58. case DJMEMC_CONFIG:
  59. case DJMEMC_REFRESH:
  60. s->regs[addr >> 2] = val;
  61. break;
  62. default:
  63. qemu_log_mask(LOG_UNIMP, "djMEMC: unimplemented write addr=0x%"PRIx64
  64. " val=0x%"PRIx64 " size=%d\n",
  65. addr, val, size);
  66. }
  67. }
  68. static const MemoryRegionOps djmemc_mmio_ops = {
  69. .read = djmemc_read,
  70. .write = djmemc_write,
  71. .impl = {
  72. .min_access_size = 4,
  73. .max_access_size = 4,
  74. },
  75. .endianness = DEVICE_BIG_ENDIAN,
  76. };
  77. static void djmemc_init(Object *obj)
  78. {
  79. DJMEMCState *s = DJMEMC(obj);
  80. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  81. memory_region_init_io(&s->mem_regs, obj, &djmemc_mmio_ops, s, "djMEMC",
  82. DJMEMC_SIZE);
  83. sysbus_init_mmio(sbd, &s->mem_regs);
  84. }
  85. static void djmemc_reset_hold(Object *obj, ResetType type)
  86. {
  87. DJMEMCState *s = DJMEMC(obj);
  88. memset(s->regs, 0, sizeof(s->regs));
  89. }
  90. static const VMStateDescription vmstate_djmemc = {
  91. .name = "djMEMC",
  92. .version_id = 1,
  93. .minimum_version_id = 1,
  94. .fields = (const VMStateField[]) {
  95. VMSTATE_UINT32_ARRAY(regs, DJMEMCState, DJMEMC_NUM_REGS),
  96. VMSTATE_END_OF_LIST()
  97. }
  98. };
  99. static void djmemc_class_init(ObjectClass *oc, void *data)
  100. {
  101. DeviceClass *dc = DEVICE_CLASS(oc);
  102. ResettableClass *rc = RESETTABLE_CLASS(oc);
  103. dc->vmsd = &vmstate_djmemc;
  104. rc->phases.hold = djmemc_reset_hold;
  105. }
  106. static const TypeInfo djmemc_info_types[] = {
  107. {
  108. .name = TYPE_DJMEMC,
  109. .parent = TYPE_SYS_BUS_DEVICE,
  110. .instance_size = sizeof(DJMEMCState),
  111. .instance_init = djmemc_init,
  112. .class_init = djmemc_class_init,
  113. },
  114. };
  115. DEFINE_TYPES(djmemc_info_types)