2
0

gpio.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * PowerMac NewWorld MacIO GPIO emulation
  3. *
  4. * Copyright (c) 2016 Benjamin Herrenschmidt
  5. * Copyright (c) 2018 Mark Cave-Ayland
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include "qemu/osdep.h"
  26. #include "hw/qdev-properties.h"
  27. #include "migration/vmstate.h"
  28. #include "hw/misc/macio/macio.h"
  29. #include "hw/misc/macio/gpio.h"
  30. #include "hw/irq.h"
  31. #include "hw/nmi.h"
  32. #include "qemu/log.h"
  33. #include "qemu/module.h"
  34. #include "trace.h"
  35. enum MacioGPIORegisterBits {
  36. OUT_DATA = 1,
  37. IN_DATA = 2,
  38. OUT_ENABLE = 4,
  39. };
  40. void macio_set_gpio(MacIOGPIOState *s, uint32_t gpio, bool state)
  41. {
  42. uint8_t new_reg;
  43. trace_macio_set_gpio(gpio, state);
  44. if (s->gpio_regs[gpio] & OUT_ENABLE) {
  45. qemu_log_mask(LOG_GUEST_ERROR,
  46. "GPIO: Setting GPIO %d while it's an output\n", gpio);
  47. }
  48. new_reg = s->gpio_regs[gpio] & ~IN_DATA;
  49. if (state) {
  50. new_reg |= IN_DATA;
  51. }
  52. if (new_reg == s->gpio_regs[gpio]) {
  53. return;
  54. }
  55. s->gpio_regs[gpio] = new_reg;
  56. /*
  57. * Note that we probably need to get access to the MPIC config to
  58. * decode polarity since qemu always use "raise" regardless.
  59. *
  60. * For now, we hard wire known GPIOs
  61. */
  62. switch (gpio) {
  63. case 1:
  64. /* Level low */
  65. if (!state) {
  66. trace_macio_gpio_irq_assert(gpio);
  67. qemu_irq_raise(s->gpio_extirqs[gpio]);
  68. } else {
  69. trace_macio_gpio_irq_deassert(gpio);
  70. qemu_irq_lower(s->gpio_extirqs[gpio]);
  71. }
  72. break;
  73. case 9:
  74. /* Edge, triggered by NMI below */
  75. if (state) {
  76. trace_macio_gpio_irq_assert(gpio);
  77. qemu_irq_raise(s->gpio_extirqs[gpio]);
  78. } else {
  79. trace_macio_gpio_irq_deassert(gpio);
  80. qemu_irq_lower(s->gpio_extirqs[gpio]);
  81. }
  82. break;
  83. default:
  84. qemu_log_mask(LOG_UNIMP, "GPIO: setting unimplemented GPIO %d", gpio);
  85. }
  86. }
  87. static void macio_gpio_write(void *opaque, hwaddr addr, uint64_t value,
  88. unsigned size)
  89. {
  90. MacIOGPIOState *s = opaque;
  91. uint8_t ibit;
  92. trace_macio_gpio_write(addr, value);
  93. /* Levels regs are read-only */
  94. if (addr < 8) {
  95. return;
  96. }
  97. addr -= 8;
  98. if (addr < 36) {
  99. value &= ~IN_DATA;
  100. if (value & OUT_ENABLE) {
  101. ibit = (value & OUT_DATA) << 1;
  102. } else {
  103. ibit = s->gpio_regs[addr] & IN_DATA;
  104. }
  105. s->gpio_regs[addr] = value | ibit;
  106. }
  107. }
  108. static uint64_t macio_gpio_read(void *opaque, hwaddr addr, unsigned size)
  109. {
  110. MacIOGPIOState *s = opaque;
  111. uint64_t val = 0;
  112. /* Levels regs */
  113. if (addr < 8) {
  114. val = s->gpio_levels[addr];
  115. } else {
  116. addr -= 8;
  117. if (addr < 36) {
  118. val = s->gpio_regs[addr];
  119. }
  120. }
  121. trace_macio_gpio_read(addr, val);
  122. return val;
  123. }
  124. static const MemoryRegionOps macio_gpio_ops = {
  125. .read = macio_gpio_read,
  126. .write = macio_gpio_write,
  127. .endianness = DEVICE_LITTLE_ENDIAN,
  128. .impl = {
  129. .min_access_size = 1,
  130. .max_access_size = 1,
  131. },
  132. };
  133. static void macio_gpio_init(Object *obj)
  134. {
  135. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  136. MacIOGPIOState *s = MACIO_GPIO(obj);
  137. int i;
  138. for (i = 0; i < 10; i++) {
  139. sysbus_init_irq(sbd, &s->gpio_extirqs[i]);
  140. }
  141. memory_region_init_io(&s->gpiomem, OBJECT(s), &macio_gpio_ops, obj,
  142. "gpio", 0x30);
  143. sysbus_init_mmio(sbd, &s->gpiomem);
  144. }
  145. static const VMStateDescription vmstate_macio_gpio = {
  146. .name = "macio_gpio",
  147. .version_id = 0,
  148. .minimum_version_id = 0,
  149. .fields = (const VMStateField[]) {
  150. VMSTATE_UINT8_ARRAY(gpio_levels, MacIOGPIOState, 8),
  151. VMSTATE_UINT8_ARRAY(gpio_regs, MacIOGPIOState, 36),
  152. VMSTATE_END_OF_LIST()
  153. }
  154. };
  155. static void macio_gpio_reset(DeviceState *dev)
  156. {
  157. MacIOGPIOState *s = MACIO_GPIO(dev);
  158. /* GPIO 1 is up by default */
  159. macio_set_gpio(s, 1, true);
  160. }
  161. static void macio_gpio_nmi(NMIState *n, int cpu_index, Error **errp)
  162. {
  163. macio_set_gpio(MACIO_GPIO(n), 9, true);
  164. macio_set_gpio(MACIO_GPIO(n), 9, false);
  165. }
  166. static void macio_gpio_class_init(ObjectClass *oc, void *data)
  167. {
  168. DeviceClass *dc = DEVICE_CLASS(oc);
  169. NMIClass *nc = NMI_CLASS(oc);
  170. device_class_set_legacy_reset(dc, macio_gpio_reset);
  171. dc->vmsd = &vmstate_macio_gpio;
  172. nc->nmi_monitor_handler = macio_gpio_nmi;
  173. }
  174. static const TypeInfo macio_gpio_init_info = {
  175. .name = TYPE_MACIO_GPIO,
  176. .parent = TYPE_SYS_BUS_DEVICE,
  177. .instance_size = sizeof(MacIOGPIOState),
  178. .instance_init = macio_gpio_init,
  179. .class_init = macio_gpio_class_init,
  180. .interfaces = (InterfaceInfo[]) {
  181. { TYPE_NMI },
  182. { }
  183. },
  184. };
  185. static void macio_gpio_register_types(void)
  186. {
  187. type_register_static(&macio_gpio_init_info);
  188. }
  189. type_init(macio_gpio_register_types)