2
0

aspeed_sli.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * ASPEED SLI Controller
  3. *
  4. * Copyright (C) 2024 ASPEED Technology Inc.
  5. *
  6. * SPDX-License-Identifier: GPL-2.0-or-later
  7. */
  8. #include "qemu/osdep.h"
  9. #include "qemu/log.h"
  10. #include "qemu/error-report.h"
  11. #include "hw/qdev-properties.h"
  12. #include "hw/misc/aspeed_sli.h"
  13. #include "qapi/error.h"
  14. #include "migration/vmstate.h"
  15. #include "trace.h"
  16. #define SLI_REGION_SIZE 0x500
  17. #define TO_REG(addr) ((addr) >> 2)
  18. static uint64_t aspeed_sli_read(void *opaque, hwaddr addr, unsigned int size)
  19. {
  20. AspeedSLIState *s = ASPEED_SLI(opaque);
  21. int reg = TO_REG(addr);
  22. if (reg >= ARRAY_SIZE(s->regs)) {
  23. qemu_log_mask(LOG_GUEST_ERROR,
  24. "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
  25. __func__, addr);
  26. return 0;
  27. }
  28. trace_aspeed_sli_read(addr, size, s->regs[reg]);
  29. return s->regs[reg];
  30. }
  31. static void aspeed_sli_write(void *opaque, hwaddr addr, uint64_t data,
  32. unsigned int size)
  33. {
  34. AspeedSLIState *s = ASPEED_SLI(opaque);
  35. int reg = TO_REG(addr);
  36. if (reg >= ARRAY_SIZE(s->regs)) {
  37. qemu_log_mask(LOG_GUEST_ERROR,
  38. "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
  39. __func__, addr);
  40. return;
  41. }
  42. trace_aspeed_sli_write(addr, size, data);
  43. s->regs[reg] = data;
  44. }
  45. static uint64_t aspeed_sliio_read(void *opaque, hwaddr addr, unsigned int size)
  46. {
  47. AspeedSLIState *s = ASPEED_SLI(opaque);
  48. int reg = TO_REG(addr);
  49. if (reg >= ARRAY_SIZE(s->regs)) {
  50. qemu_log_mask(LOG_GUEST_ERROR,
  51. "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
  52. __func__, addr);
  53. return 0;
  54. }
  55. trace_aspeed_sliio_read(addr, size, s->regs[reg]);
  56. return s->regs[reg];
  57. }
  58. static void aspeed_sliio_write(void *opaque, hwaddr addr, uint64_t data,
  59. unsigned int size)
  60. {
  61. AspeedSLIState *s = ASPEED_SLI(opaque);
  62. int reg = TO_REG(addr);
  63. if (reg >= ARRAY_SIZE(s->regs)) {
  64. qemu_log_mask(LOG_GUEST_ERROR,
  65. "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
  66. __func__, addr);
  67. return;
  68. }
  69. trace_aspeed_sliio_write(addr, size, data);
  70. s->regs[reg] = data;
  71. }
  72. static const MemoryRegionOps aspeed_sli_ops = {
  73. .read = aspeed_sli_read,
  74. .write = aspeed_sli_write,
  75. .endianness = DEVICE_LITTLE_ENDIAN,
  76. .valid = {
  77. .min_access_size = 1,
  78. .max_access_size = 4,
  79. },
  80. };
  81. static const MemoryRegionOps aspeed_sliio_ops = {
  82. .read = aspeed_sliio_read,
  83. .write = aspeed_sliio_write,
  84. .endianness = DEVICE_LITTLE_ENDIAN,
  85. .valid = {
  86. .min_access_size = 1,
  87. .max_access_size = 4,
  88. },
  89. };
  90. static void aspeed_sli_realize(DeviceState *dev, Error **errp)
  91. {
  92. AspeedSLIState *s = ASPEED_SLI(dev);
  93. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  94. memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sli_ops, s,
  95. TYPE_ASPEED_SLI, SLI_REGION_SIZE);
  96. sysbus_init_mmio(sbd, &s->iomem);
  97. }
  98. static void aspeed_sliio_realize(DeviceState *dev, Error **errp)
  99. {
  100. AspeedSLIState *s = ASPEED_SLI(dev);
  101. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  102. memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sliio_ops, s,
  103. TYPE_ASPEED_SLI, SLI_REGION_SIZE);
  104. sysbus_init_mmio(sbd, &s->iomem);
  105. }
  106. static void aspeed_sli_class_init(ObjectClass *klass, void *data)
  107. {
  108. DeviceClass *dc = DEVICE_CLASS(klass);
  109. dc->desc = "Aspeed SLI Controller";
  110. dc->realize = aspeed_sli_realize;
  111. }
  112. static const TypeInfo aspeed_sli_info = {
  113. .name = TYPE_ASPEED_SLI,
  114. .parent = TYPE_SYS_BUS_DEVICE,
  115. .instance_size = sizeof(AspeedSLIState),
  116. .class_init = aspeed_sli_class_init,
  117. .abstract = true,
  118. };
  119. static void aspeed_2700_sli_class_init(ObjectClass *klass, void *data)
  120. {
  121. DeviceClass *dc = DEVICE_CLASS(klass);
  122. dc->desc = "AST2700 SLI Controller";
  123. }
  124. static void aspeed_2700_sliio_class_init(ObjectClass *klass, void *data)
  125. {
  126. DeviceClass *dc = DEVICE_CLASS(klass);
  127. dc->desc = "AST2700 I/O SLI Controller";
  128. dc->realize = aspeed_sliio_realize;
  129. }
  130. static const TypeInfo aspeed_2700_sli_info = {
  131. .name = TYPE_ASPEED_2700_SLI,
  132. .parent = TYPE_ASPEED_SLI,
  133. .class_init = aspeed_2700_sli_class_init,
  134. };
  135. static const TypeInfo aspeed_2700_sliio_info = {
  136. .name = TYPE_ASPEED_2700_SLIIO,
  137. .parent = TYPE_ASPEED_SLI,
  138. .class_init = aspeed_2700_sliio_class_init,
  139. };
  140. static void aspeed_sli_register_types(void)
  141. {
  142. type_register_static(&aspeed_sli_info);
  143. type_register_static(&aspeed_2700_sli_info);
  144. type_register_static(&aspeed_2700_sliio_info);
  145. }
  146. type_init(aspeed_sli_register_types);