lasi.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * HP-PARISC Lasi chipset emulation.
  3. *
  4. * (C) 2019 by Helge Deller <deller@gmx.de>
  5. *
  6. * This work is licensed under the GNU GPL license version 2 or later.
  7. *
  8. * Documentation available at:
  9. * https://parisc.wiki.kernel.org/images-parisc/7/79/Lasi_ers.pdf
  10. */
  11. #include "qemu/osdep.h"
  12. #include "qemu/units.h"
  13. #include "qemu/log.h"
  14. #include "qapi/error.h"
  15. #include "trace.h"
  16. #include "hw/irq.h"
  17. #include "system/system.h"
  18. #include "system/runstate.h"
  19. #include "migration/vmstate.h"
  20. #include "qom/object.h"
  21. #include "hw/misc/lasi.h"
  22. static bool lasi_chip_mem_valid(void *opaque, hwaddr addr,
  23. unsigned size, bool is_write,
  24. MemTxAttrs attrs)
  25. {
  26. bool ret = false;
  27. switch (addr) {
  28. case LASI_IRR:
  29. case LASI_IMR:
  30. case LASI_IPR:
  31. case LASI_ICR:
  32. case LASI_IAR:
  33. case LASI_LPT:
  34. case LASI_AUDIO:
  35. case LASI_AUDIO + 4:
  36. case LASI_UART:
  37. case LASI_LAN:
  38. case LASI_LAN + 12: /* LASI LAN MAC */
  39. case LASI_RTC:
  40. case LASI_FDC:
  41. case LASI_PCR ... LASI_AMR:
  42. ret = true;
  43. }
  44. trace_lasi_chip_mem_valid(addr, ret);
  45. return ret;
  46. }
  47. static MemTxResult lasi_chip_read_with_attrs(void *opaque, hwaddr addr,
  48. uint64_t *data, unsigned size,
  49. MemTxAttrs attrs)
  50. {
  51. LasiState *s = opaque;
  52. MemTxResult ret = MEMTX_OK;
  53. uint32_t val;
  54. switch (addr) {
  55. case LASI_IRR:
  56. val = s->irr;
  57. break;
  58. case LASI_IMR:
  59. val = s->imr;
  60. break;
  61. case LASI_IPR:
  62. val = s->ipr;
  63. /* Any read to IPR clears the register. */
  64. s->ipr = 0;
  65. break;
  66. case LASI_ICR:
  67. val = s->icr & ICR_BUS_ERROR_BIT; /* bus_error */
  68. break;
  69. case LASI_IAR:
  70. val = s->iar;
  71. break;
  72. case LASI_LPT:
  73. case LASI_UART:
  74. case LASI_LAN:
  75. case LASI_LAN + 12:
  76. case LASI_FDC:
  77. val = 0;
  78. break;
  79. case LASI_RTC:
  80. val = time(NULL);
  81. val += s->rtc_ref;
  82. break;
  83. case LASI_PCR:
  84. case LASI_VER: /* only version 0 existed. */
  85. case LASI_IORESET:
  86. val = 0;
  87. break;
  88. case LASI_ERRLOG:
  89. val = s->errlog;
  90. break;
  91. case LASI_AMR:
  92. val = s->amr;
  93. break;
  94. default:
  95. /* Controlled by lasi_chip_mem_valid above. */
  96. g_assert_not_reached();
  97. }
  98. trace_lasi_chip_read(addr, val);
  99. *data = val;
  100. return ret;
  101. }
  102. static MemTxResult lasi_chip_write_with_attrs(void *opaque, hwaddr addr,
  103. uint64_t val, unsigned size,
  104. MemTxAttrs attrs)
  105. {
  106. LasiState *s = opaque;
  107. trace_lasi_chip_write(addr, val);
  108. switch (addr) {
  109. case LASI_IRR:
  110. /* read-only. */
  111. break;
  112. case LASI_IMR:
  113. s->imr = val;
  114. if (((val & LASI_IRQ_BITS) != val) && (val != 0xffffffff)) {
  115. qemu_log_mask(LOG_GUEST_ERROR,
  116. "LASI: tried to set invalid %lx IMR value.\n",
  117. (unsigned long) val);
  118. }
  119. break;
  120. case LASI_IPR:
  121. /* Any write to IPR clears the register. */
  122. s->ipr = 0;
  123. break;
  124. case LASI_ICR:
  125. s->icr = val;
  126. /* if (val & ICR_TOC_BIT) issue_toc(); */
  127. break;
  128. case LASI_IAR:
  129. s->iar = val;
  130. break;
  131. case LASI_LPT:
  132. /* XXX: reset parallel port */
  133. break;
  134. case LASI_AUDIO:
  135. case LASI_AUDIO + 4:
  136. /* XXX: reset audio port */
  137. break;
  138. case LASI_UART:
  139. /* XXX: reset serial port */
  140. break;
  141. case LASI_LAN:
  142. /* XXX: reset LAN card */
  143. break;
  144. case LASI_FDC:
  145. /* XXX: reset Floppy controller */
  146. break;
  147. case LASI_RTC:
  148. s->rtc_ref = val - time(NULL);
  149. break;
  150. case LASI_PCR:
  151. if (val == 0x02) { /* immediately power off */
  152. qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
  153. }
  154. break;
  155. case LASI_ERRLOG:
  156. s->errlog = val;
  157. break;
  158. case LASI_VER:
  159. /* read-only. */
  160. break;
  161. case LASI_IORESET:
  162. break; /* XXX: TODO: Reset various devices. */
  163. case LASI_AMR:
  164. s->amr = val;
  165. break;
  166. default:
  167. /* Controlled by lasi_chip_mem_valid above. */
  168. g_assert_not_reached();
  169. }
  170. return MEMTX_OK;
  171. }
  172. static const MemoryRegionOps lasi_chip_ops = {
  173. .read_with_attrs = lasi_chip_read_with_attrs,
  174. .write_with_attrs = lasi_chip_write_with_attrs,
  175. .endianness = DEVICE_BIG_ENDIAN,
  176. .valid = {
  177. .min_access_size = 1,
  178. .max_access_size = 4,
  179. .accepts = lasi_chip_mem_valid,
  180. },
  181. .impl = {
  182. .min_access_size = 1,
  183. .max_access_size = 4,
  184. },
  185. };
  186. static const VMStateDescription vmstate_lasi = {
  187. .name = "Lasi",
  188. .version_id = 2,
  189. .minimum_version_id = 1,
  190. .fields = (const VMStateField[]) {
  191. VMSTATE_UINT32(irr, LasiState),
  192. VMSTATE_UINT32(imr, LasiState),
  193. VMSTATE_UINT32(ipr, LasiState),
  194. VMSTATE_UINT32(icr, LasiState),
  195. VMSTATE_UINT32(iar, LasiState),
  196. VMSTATE_UINT32(errlog, LasiState),
  197. VMSTATE_UINT32(amr, LasiState),
  198. VMSTATE_UINT32_V(rtc_ref, LasiState, 2),
  199. VMSTATE_END_OF_LIST()
  200. }
  201. };
  202. static void lasi_set_irq(void *opaque, int irq, int level)
  203. {
  204. LasiState *s = opaque;
  205. uint32_t bit = 1u << irq;
  206. if (level) {
  207. s->ipr |= bit;
  208. if (bit & s->imr) {
  209. uint32_t iar = s->iar;
  210. s->irr |= bit;
  211. if ((s->icr & ICR_BUS_ERROR_BIT) == 0) {
  212. stl_be_phys(&address_space_memory, iar & -32, iar & 31);
  213. }
  214. }
  215. }
  216. }
  217. static void lasi_reset(DeviceState *dev)
  218. {
  219. LasiState *s = LASI_CHIP(dev);
  220. s->iar = 0xFFFB0000 + 3; /* CPU_HPA + 3 */
  221. /* Real time clock (RTC), it's only one 32-bit counter @9000 */
  222. s->rtc_ref = 0;
  223. }
  224. static void lasi_init(Object *obj)
  225. {
  226. LasiState *s = LASI_CHIP(obj);
  227. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  228. memory_region_init_io(&s->this_mem, OBJECT(s), &lasi_chip_ops,
  229. s, "lasi", 0x100000);
  230. sysbus_init_mmio(sbd, &s->this_mem);
  231. qdev_init_gpio_in(DEVICE(obj), lasi_set_irq, LASI_IRQS);
  232. }
  233. static void lasi_class_init(ObjectClass *klass, void *data)
  234. {
  235. DeviceClass *dc = DEVICE_CLASS(klass);
  236. device_class_set_legacy_reset(dc, lasi_reset);
  237. dc->vmsd = &vmstate_lasi;
  238. }
  239. static const TypeInfo lasi_pcihost_info = {
  240. .name = TYPE_LASI_CHIP,
  241. .parent = TYPE_SYS_BUS_DEVICE,
  242. .instance_init = lasi_init,
  243. .instance_size = sizeof(LasiState),
  244. .class_init = lasi_class_init,
  245. };
  246. static void lasi_register_types(void)
  247. {
  248. type_register_static(&lasi_pcihost_info);
  249. }
  250. type_init(lasi_register_types)