xlnx-versal-xramc.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * QEMU model of the Xilinx XRAM Controller.
  3. *
  4. * Copyright (c) 2021 Xilinx Inc.
  5. * SPDX-License-Identifier: GPL-2.0-or-later
  6. * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
  7. */
  8. #include "qemu/osdep.h"
  9. #include "qemu/units.h"
  10. #include "qapi/error.h"
  11. #include "migration/vmstate.h"
  12. #include "hw/sysbus.h"
  13. #include "hw/register.h"
  14. #include "hw/qdev-properties.h"
  15. #include "hw/irq.h"
  16. #include "hw/misc/xlnx-versal-xramc.h"
  17. #ifndef XLNX_XRAM_CTRL_ERR_DEBUG
  18. #define XLNX_XRAM_CTRL_ERR_DEBUG 0
  19. #endif
  20. static void xram_update_irq(XlnxXramCtrl *s)
  21. {
  22. bool pending = s->regs[R_XRAM_ISR] & ~s->regs[R_XRAM_IMR];
  23. qemu_set_irq(s->irq, pending);
  24. }
  25. static void xram_isr_postw(RegisterInfo *reg, uint64_t val64)
  26. {
  27. XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
  28. xram_update_irq(s);
  29. }
  30. static uint64_t xram_ien_prew(RegisterInfo *reg, uint64_t val64)
  31. {
  32. XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
  33. uint32_t val = val64;
  34. s->regs[R_XRAM_IMR] &= ~val;
  35. xram_update_irq(s);
  36. return 0;
  37. }
  38. static uint64_t xram_ids_prew(RegisterInfo *reg, uint64_t val64)
  39. {
  40. XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
  41. uint32_t val = val64;
  42. s->regs[R_XRAM_IMR] |= val;
  43. xram_update_irq(s);
  44. return 0;
  45. }
  46. static const RegisterAccessInfo xram_ctrl_regs_info[] = {
  47. { .name = "XRAM_ERR_CTRL", .addr = A_XRAM_ERR_CTRL,
  48. .reset = 0xf,
  49. .rsvd = 0xfffffff0,
  50. },{ .name = "XRAM_ISR", .addr = A_XRAM_ISR,
  51. .rsvd = 0xfffff800,
  52. .w1c = 0x7ff,
  53. .post_write = xram_isr_postw,
  54. },{ .name = "XRAM_IMR", .addr = A_XRAM_IMR,
  55. .reset = 0x7ff,
  56. .rsvd = 0xfffff800,
  57. .ro = 0x7ff,
  58. },{ .name = "XRAM_IEN", .addr = A_XRAM_IEN,
  59. .rsvd = 0xfffff800,
  60. .pre_write = xram_ien_prew,
  61. },{ .name = "XRAM_IDS", .addr = A_XRAM_IDS,
  62. .rsvd = 0xfffff800,
  63. .pre_write = xram_ids_prew,
  64. },{ .name = "XRAM_ECC_CNTL", .addr = A_XRAM_ECC_CNTL,
  65. .rsvd = 0xfffffff8,
  66. },{ .name = "XRAM_CLR_EXE", .addr = A_XRAM_CLR_EXE,
  67. .rsvd = 0xffffff00,
  68. },{ .name = "XRAM_CE_FFA", .addr = A_XRAM_CE_FFA,
  69. .rsvd = 0xfff00000,
  70. .ro = 0xfffff,
  71. },{ .name = "XRAM_CE_FFD0", .addr = A_XRAM_CE_FFD0,
  72. .ro = 0xffffffff,
  73. },{ .name = "XRAM_CE_FFD1", .addr = A_XRAM_CE_FFD1,
  74. .ro = 0xffffffff,
  75. },{ .name = "XRAM_CE_FFD2", .addr = A_XRAM_CE_FFD2,
  76. .ro = 0xffffffff,
  77. },{ .name = "XRAM_CE_FFD3", .addr = A_XRAM_CE_FFD3,
  78. .ro = 0xffffffff,
  79. },{ .name = "XRAM_CE_FFE", .addr = A_XRAM_CE_FFE,
  80. .rsvd = 0xffff0000,
  81. .ro = 0xffff,
  82. },{ .name = "XRAM_UE_FFA", .addr = A_XRAM_UE_FFA,
  83. .rsvd = 0xfff00000,
  84. .ro = 0xfffff,
  85. },{ .name = "XRAM_UE_FFD0", .addr = A_XRAM_UE_FFD0,
  86. .ro = 0xffffffff,
  87. },{ .name = "XRAM_UE_FFD1", .addr = A_XRAM_UE_FFD1,
  88. .ro = 0xffffffff,
  89. },{ .name = "XRAM_UE_FFD2", .addr = A_XRAM_UE_FFD2,
  90. .ro = 0xffffffff,
  91. },{ .name = "XRAM_UE_FFD3", .addr = A_XRAM_UE_FFD3,
  92. .ro = 0xffffffff,
  93. },{ .name = "XRAM_UE_FFE", .addr = A_XRAM_UE_FFE,
  94. .rsvd = 0xffff0000,
  95. .ro = 0xffff,
  96. },{ .name = "XRAM_FI_D0", .addr = A_XRAM_FI_D0,
  97. },{ .name = "XRAM_FI_D1", .addr = A_XRAM_FI_D1,
  98. },{ .name = "XRAM_FI_D2", .addr = A_XRAM_FI_D2,
  99. },{ .name = "XRAM_FI_D3", .addr = A_XRAM_FI_D3,
  100. },{ .name = "XRAM_FI_SY", .addr = A_XRAM_FI_SY,
  101. .rsvd = 0xffff0000,
  102. },{ .name = "XRAM_RMW_UE_FFA", .addr = A_XRAM_RMW_UE_FFA,
  103. .rsvd = 0xfff00000,
  104. .ro = 0xfffff,
  105. },{ .name = "XRAM_FI_CNTR", .addr = A_XRAM_FI_CNTR,
  106. .rsvd = 0xff000000,
  107. },{ .name = "XRAM_IMP", .addr = A_XRAM_IMP,
  108. .reset = 0x4,
  109. .rsvd = 0xfffffff0,
  110. .ro = 0xf,
  111. },{ .name = "XRAM_PRDY_DBG", .addr = A_XRAM_PRDY_DBG,
  112. .reset = 0xffff,
  113. .rsvd = 0xffff0000,
  114. .ro = 0xffff,
  115. },{ .name = "XRAM_SAFETY_CHK", .addr = A_XRAM_SAFETY_CHK,
  116. }
  117. };
  118. static void xram_ctrl_reset_enter(Object *obj, ResetType type)
  119. {
  120. XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
  121. unsigned int i;
  122. for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
  123. register_reset(&s->regs_info[i]);
  124. }
  125. ARRAY_FIELD_DP32(s->regs, XRAM_IMP, SIZE, s->cfg.encoded_size);
  126. }
  127. static void xram_ctrl_reset_hold(Object *obj, ResetType type)
  128. {
  129. XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
  130. xram_update_irq(s);
  131. }
  132. static const MemoryRegionOps xram_ctrl_ops = {
  133. .read = register_read_memory,
  134. .write = register_write_memory,
  135. .endianness = DEVICE_LITTLE_ENDIAN,
  136. .valid = {
  137. .min_access_size = 4,
  138. .max_access_size = 4,
  139. },
  140. };
  141. static void xram_ctrl_realize(DeviceState *dev, Error **errp)
  142. {
  143. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  144. XlnxXramCtrl *s = XLNX_XRAM_CTRL(dev);
  145. switch (s->cfg.size) {
  146. case 64 * KiB:
  147. s->cfg.encoded_size = 0;
  148. break;
  149. case 128 * KiB:
  150. s->cfg.encoded_size = 1;
  151. break;
  152. case 256 * KiB:
  153. s->cfg.encoded_size = 2;
  154. break;
  155. case 512 * KiB:
  156. s->cfg.encoded_size = 3;
  157. break;
  158. case 1 * MiB:
  159. s->cfg.encoded_size = 4;
  160. break;
  161. default:
  162. error_setg(errp, "Unsupported XRAM size %" PRId64, s->cfg.size);
  163. return;
  164. }
  165. memory_region_init_ram(&s->ram, OBJECT(s),
  166. object_get_canonical_path_component(OBJECT(s)),
  167. s->cfg.size, &error_fatal);
  168. sysbus_init_mmio(sbd, &s->ram);
  169. }
  170. static void xram_ctrl_init(Object *obj)
  171. {
  172. XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
  173. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  174. s->reg_array =
  175. register_init_block32(DEVICE(obj), xram_ctrl_regs_info,
  176. ARRAY_SIZE(xram_ctrl_regs_info),
  177. s->regs_info, s->regs,
  178. &xram_ctrl_ops,
  179. XLNX_XRAM_CTRL_ERR_DEBUG,
  180. XRAM_CTRL_R_MAX * 4);
  181. sysbus_init_mmio(sbd, &s->reg_array->mem);
  182. sysbus_init_irq(sbd, &s->irq);
  183. }
  184. static void xram_ctrl_finalize(Object *obj)
  185. {
  186. XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
  187. register_finalize_block(s->reg_array);
  188. }
  189. static const VMStateDescription vmstate_xram_ctrl = {
  190. .name = TYPE_XLNX_XRAM_CTRL,
  191. .version_id = 1,
  192. .minimum_version_id = 1,
  193. .fields = (const VMStateField[]) {
  194. VMSTATE_UINT32_ARRAY(regs, XlnxXramCtrl, XRAM_CTRL_R_MAX),
  195. VMSTATE_END_OF_LIST(),
  196. }
  197. };
  198. static const Property xram_ctrl_properties[] = {
  199. DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB),
  200. };
  201. static void xram_ctrl_class_init(ObjectClass *klass, void *data)
  202. {
  203. ResettableClass *rc = RESETTABLE_CLASS(klass);
  204. DeviceClass *dc = DEVICE_CLASS(klass);
  205. dc->realize = xram_ctrl_realize;
  206. dc->vmsd = &vmstate_xram_ctrl;
  207. device_class_set_props(dc, xram_ctrl_properties);
  208. rc->phases.enter = xram_ctrl_reset_enter;
  209. rc->phases.hold = xram_ctrl_reset_hold;
  210. }
  211. static const TypeInfo xram_ctrl_info = {
  212. .name = TYPE_XLNX_XRAM_CTRL,
  213. .parent = TYPE_SYS_BUS_DEVICE,
  214. .instance_size = sizeof(XlnxXramCtrl),
  215. .class_init = xram_ctrl_class_init,
  216. .instance_init = xram_ctrl_init,
  217. .instance_finalize = xram_ctrl_finalize,
  218. };
  219. static void xram_ctrl_register_types(void)
  220. {
  221. type_register_static(&xram_ctrl_info);
  222. }
  223. type_init(xram_ctrl_register_types)