2
0

armsse-cpu-pwrctrl.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Arm SSE CPU PWRCTRL register block
  3. *
  4. * Copyright (c) 2021 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 "CPU<N>_PWRCTRL block" which is part of the
  13. * Arm Corstone SSE-300 Example Subsystem and documented in
  14. * https://developer.arm.com/documentation/101773/0000
  15. */
  16. #include "qemu/osdep.h"
  17. #include "qemu/log.h"
  18. #include "qemu/module.h"
  19. #include "trace.h"
  20. #include "qapi/error.h"
  21. #include "migration/vmstate.h"
  22. #include "hw/sysbus.h"
  23. #include "hw/registerfields.h"
  24. #include "hw/misc/armsse-cpu-pwrctrl.h"
  25. REG32(CPUPWRCFG, 0x0)
  26. REG32(PID4, 0xfd0)
  27. REG32(PID5, 0xfd4)
  28. REG32(PID6, 0xfd8)
  29. REG32(PID7, 0xfdc)
  30. REG32(PID0, 0xfe0)
  31. REG32(PID1, 0xfe4)
  32. REG32(PID2, 0xfe8)
  33. REG32(PID3, 0xfec)
  34. REG32(CID0, 0xff0)
  35. REG32(CID1, 0xff4)
  36. REG32(CID2, 0xff8)
  37. REG32(CID3, 0xffc)
  38. /* PID/CID values */
  39. static const int cpu_pwrctrl_id[] = {
  40. 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
  41. 0x5a, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
  42. 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
  43. };
  44. static uint64_t pwrctrl_read(void *opaque, hwaddr offset, unsigned size)
  45. {
  46. ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
  47. uint64_t r;
  48. switch (offset) {
  49. case A_CPUPWRCFG:
  50. r = s->cpupwrcfg;
  51. break;
  52. case A_PID4 ... A_CID3:
  53. r = cpu_pwrctrl_id[(offset - A_PID4) / 4];
  54. break;
  55. default:
  56. qemu_log_mask(LOG_GUEST_ERROR,
  57. "SSE CPU_PWRCTRL read: bad offset %x\n", (int)offset);
  58. r = 0;
  59. break;
  60. }
  61. trace_armsse_cpu_pwrctrl_read(offset, r, size);
  62. return r;
  63. }
  64. static void pwrctrl_write(void *opaque, hwaddr offset,
  65. uint64_t value, unsigned size)
  66. {
  67. ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(opaque);
  68. trace_armsse_cpu_pwrctrl_write(offset, value, size);
  69. switch (offset) {
  70. case A_CPUPWRCFG:
  71. qemu_log_mask(LOG_UNIMP,
  72. "SSE CPU_PWRCTRL: CPUPWRCFG unimplemented\n");
  73. s->cpupwrcfg = value;
  74. break;
  75. default:
  76. qemu_log_mask(LOG_GUEST_ERROR,
  77. "SSE CPU_PWRCTRL write: bad offset 0x%x\n", (int)offset);
  78. break;
  79. }
  80. }
  81. static const MemoryRegionOps pwrctrl_ops = {
  82. .read = pwrctrl_read,
  83. .write = pwrctrl_write,
  84. .endianness = DEVICE_LITTLE_ENDIAN,
  85. .impl.min_access_size = 4,
  86. .impl.max_access_size = 4,
  87. .valid.min_access_size = 4,
  88. .valid.max_access_size = 4,
  89. };
  90. static void pwrctrl_reset(DeviceState *dev)
  91. {
  92. ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(dev);
  93. s->cpupwrcfg = 0;
  94. }
  95. static const VMStateDescription pwrctrl_vmstate = {
  96. .name = "armsse-cpu-pwrctrl",
  97. .version_id = 1,
  98. .minimum_version_id = 1,
  99. .fields = (VMStateField[]) {
  100. VMSTATE_UINT32(cpupwrcfg, ARMSSECPUPwrCtrl),
  101. VMSTATE_END_OF_LIST()
  102. },
  103. };
  104. static void pwrctrl_init(Object *obj)
  105. {
  106. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  107. ARMSSECPUPwrCtrl *s = ARMSSE_CPU_PWRCTRL(obj);
  108. memory_region_init_io(&s->iomem, obj, &pwrctrl_ops,
  109. s, "armsse-cpu-pwrctrl", 0x1000);
  110. sysbus_init_mmio(sbd, &s->iomem);
  111. }
  112. static void pwrctrl_class_init(ObjectClass *klass, void *data)
  113. {
  114. DeviceClass *dc = DEVICE_CLASS(klass);
  115. dc->reset = pwrctrl_reset;
  116. dc->vmsd = &pwrctrl_vmstate;
  117. }
  118. static const TypeInfo pwrctrl_info = {
  119. .name = TYPE_ARMSSE_CPU_PWRCTRL,
  120. .parent = TYPE_SYS_BUS_DEVICE,
  121. .instance_size = sizeof(ARMSSECPUPwrCtrl),
  122. .instance_init = pwrctrl_init,
  123. .class_init = pwrctrl_class_init,
  124. };
  125. static void pwrctrl_register_types(void)
  126. {
  127. type_register_static(&pwrctrl_info);
  128. }
  129. type_init(pwrctrl_register_types);