2
0

iotkit-sysinfo.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * ARM IoTKit system information block
  3. *
  4. * Copyright (c) 2018 Linaro Limited
  5. * Written by Peter Maydell
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 or
  9. * (at your option) any later version.
  10. */
  11. /*
  12. * This is a model of the "system information block" which is part of the
  13. * Arm IoTKit and documented in
  14. * https://developer.arm.com/documentation/ecm0601256/latest
  15. * It consists of 2 read-only version/config registers, plus the
  16. * usual ID registers.
  17. */
  18. #include "qemu/osdep.h"
  19. #include "qemu/log.h"
  20. #include "qemu/module.h"
  21. #include "trace.h"
  22. #include "qapi/error.h"
  23. #include "hw/sysbus.h"
  24. #include "hw/registerfields.h"
  25. #include "hw/misc/iotkit-sysinfo.h"
  26. #include "hw/qdev-properties.h"
  27. #include "hw/arm/armsse-version.h"
  28. REG32(SYS_VERSION, 0x0)
  29. REG32(SYS_CONFIG, 0x4)
  30. REG32(SYS_CONFIG1, 0x8)
  31. REG32(IIDR, 0xfc8)
  32. REG32(PID4, 0xfd0)
  33. REG32(PID5, 0xfd4)
  34. REG32(PID6, 0xfd8)
  35. REG32(PID7, 0xfdc)
  36. REG32(PID0, 0xfe0)
  37. REG32(PID1, 0xfe4)
  38. REG32(PID2, 0xfe8)
  39. REG32(PID3, 0xfec)
  40. REG32(CID0, 0xff0)
  41. REG32(CID1, 0xff4)
  42. REG32(CID2, 0xff8)
  43. REG32(CID3, 0xffc)
  44. /* PID/CID values */
  45. static const int sysinfo_id[] = {
  46. 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
  47. 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
  48. 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
  49. };
  50. static const int sysinfo_sse300_id[] = {
  51. 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
  52. 0x58, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
  53. 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
  54. };
  55. static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
  56. unsigned size)
  57. {
  58. IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque);
  59. uint64_t r;
  60. switch (offset) {
  61. case A_SYS_VERSION:
  62. r = s->sys_version;
  63. break;
  64. case A_SYS_CONFIG:
  65. r = s->sys_config;
  66. break;
  67. case A_SYS_CONFIG1:
  68. switch (s->sse_version) {
  69. case ARMSSE_SSE300:
  70. return 0;
  71. break;
  72. default:
  73. goto bad_read;
  74. }
  75. break;
  76. case A_IIDR:
  77. switch (s->sse_version) {
  78. case ARMSSE_SSE300:
  79. return s->iidr;
  80. break;
  81. default:
  82. goto bad_read;
  83. }
  84. break;
  85. case A_PID4 ... A_CID3:
  86. switch (s->sse_version) {
  87. case ARMSSE_SSE300:
  88. r = sysinfo_sse300_id[(offset - A_PID4) / 4];
  89. break;
  90. default:
  91. r = sysinfo_id[(offset - A_PID4) / 4];
  92. break;
  93. }
  94. break;
  95. default:
  96. bad_read:
  97. qemu_log_mask(LOG_GUEST_ERROR,
  98. "IoTKit SysInfo read: bad offset %x\n", (int)offset);
  99. r = 0;
  100. break;
  101. }
  102. trace_iotkit_sysinfo_read(offset, r, size);
  103. return r;
  104. }
  105. static void iotkit_sysinfo_write(void *opaque, hwaddr offset,
  106. uint64_t value, unsigned size)
  107. {
  108. trace_iotkit_sysinfo_write(offset, value, size);
  109. qemu_log_mask(LOG_GUEST_ERROR,
  110. "IoTKit SysInfo: write to RO offset 0x%x\n", (int)offset);
  111. }
  112. static const MemoryRegionOps iotkit_sysinfo_ops = {
  113. .read = iotkit_sysinfo_read,
  114. .write = iotkit_sysinfo_write,
  115. .endianness = DEVICE_LITTLE_ENDIAN,
  116. /* byte/halfword accesses are just zero-padded on reads and writes */
  117. .impl.min_access_size = 4,
  118. .impl.max_access_size = 4,
  119. .valid.min_access_size = 1,
  120. .valid.max_access_size = 4,
  121. };
  122. static const Property iotkit_sysinfo_props[] = {
  123. DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
  124. DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
  125. DEFINE_PROP_UINT32("sse-version", IoTKitSysInfo, sse_version, 0),
  126. DEFINE_PROP_UINT32("IIDR", IoTKitSysInfo, iidr, 0),
  127. };
  128. static void iotkit_sysinfo_init(Object *obj)
  129. {
  130. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  131. IoTKitSysInfo *s = IOTKIT_SYSINFO(obj);
  132. memory_region_init_io(&s->iomem, obj, &iotkit_sysinfo_ops,
  133. s, "iotkit-sysinfo", 0x1000);
  134. sysbus_init_mmio(sbd, &s->iomem);
  135. }
  136. static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp)
  137. {
  138. IoTKitSysInfo *s = IOTKIT_SYSINFO(dev);
  139. if (!armsse_version_valid(s->sse_version)) {
  140. error_setg(errp, "invalid sse-version value %d", s->sse_version);
  141. return;
  142. }
  143. }
  144. static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
  145. {
  146. DeviceClass *dc = DEVICE_CLASS(klass);
  147. /*
  148. * This device has no guest-modifiable state and so it
  149. * does not need a reset function or VMState.
  150. */
  151. dc->realize = iotkit_sysinfo_realize;
  152. device_class_set_props(dc, iotkit_sysinfo_props);
  153. }
  154. static const TypeInfo iotkit_sysinfo_info = {
  155. .name = TYPE_IOTKIT_SYSINFO,
  156. .parent = TYPE_SYS_BUS_DEVICE,
  157. .instance_size = sizeof(IoTKitSysInfo),
  158. .instance_init = iotkit_sysinfo_init,
  159. .class_init = iotkit_sysinfo_class_init,
  160. };
  161. static void iotkit_sysinfo_register_types(void)
  162. {
  163. type_register_static(&iotkit_sysinfo_info);
  164. }
  165. type_init(iotkit_sysinfo_register_types);