2
0

lm32_sys.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * QEMU model of the LatticeMico32 system control block.
  3. *
  4. * Copyright (c) 2010 Michael Walle <michael@walle.cc>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /*
  20. * This model is mainly intended for testing purposes and doesn't fit to any
  21. * real hardware. On the one hand it provides a control register (R_CTRL) on
  22. * the other hand it supports the lm32 tests.
  23. *
  24. * A write to the control register causes a system shutdown.
  25. * Tests first write the pointer to a test name to the test name register
  26. * (R_TESTNAME) and then write a zero to the pass/fail register (R_PASSFAIL) if
  27. * the test is passed or any non-zero value to it if the test is failed.
  28. */
  29. #include "hw.h"
  30. #include "sysbus.h"
  31. #include "trace.h"
  32. #include "qemu/log.h"
  33. #include "qemu/error-report.h"
  34. #include "sysemu/sysemu.h"
  35. #include "qemu/log.h"
  36. enum {
  37. R_CTRL = 0,
  38. R_PASSFAIL,
  39. R_TESTNAME,
  40. R_MAX
  41. };
  42. #define MAX_TESTNAME_LEN 16
  43. struct LM32SysState {
  44. SysBusDevice busdev;
  45. MemoryRegion iomem;
  46. uint32_t base;
  47. uint32_t regs[R_MAX];
  48. uint8_t testname[MAX_TESTNAME_LEN];
  49. };
  50. typedef struct LM32SysState LM32SysState;
  51. static void copy_testname(LM32SysState *s)
  52. {
  53. cpu_physical_memory_read(s->regs[R_TESTNAME], s->testname,
  54. MAX_TESTNAME_LEN);
  55. s->testname[MAX_TESTNAME_LEN - 1] = '\0';
  56. }
  57. static void sys_write(void *opaque, hwaddr addr,
  58. uint64_t value, unsigned size)
  59. {
  60. LM32SysState *s = opaque;
  61. char *testname;
  62. trace_lm32_sys_memory_write(addr, value);
  63. addr >>= 2;
  64. switch (addr) {
  65. case R_CTRL:
  66. qemu_system_shutdown_request();
  67. break;
  68. case R_PASSFAIL:
  69. s->regs[addr] = value;
  70. testname = (char *)s->testname;
  71. qemu_log("TC %-16s %s\n", testname, (value) ? "FAILED" : "OK");
  72. break;
  73. case R_TESTNAME:
  74. s->regs[addr] = value;
  75. copy_testname(s);
  76. break;
  77. default:
  78. error_report("lm32_sys: write access to unknown register 0x"
  79. TARGET_FMT_plx, addr << 2);
  80. break;
  81. }
  82. }
  83. static bool sys_ops_accepts(void *opaque, hwaddr addr,
  84. unsigned size, bool is_write)
  85. {
  86. return is_write && size == 4;
  87. }
  88. static const MemoryRegionOps sys_ops = {
  89. .write = sys_write,
  90. .valid.accepts = sys_ops_accepts,
  91. .endianness = DEVICE_NATIVE_ENDIAN,
  92. };
  93. static void sys_reset(DeviceState *d)
  94. {
  95. LM32SysState *s = container_of(d, LM32SysState, busdev.qdev);
  96. int i;
  97. for (i = 0; i < R_MAX; i++) {
  98. s->regs[i] = 0;
  99. }
  100. memset(s->testname, 0, MAX_TESTNAME_LEN);
  101. }
  102. static int lm32_sys_init(SysBusDevice *dev)
  103. {
  104. LM32SysState *s = FROM_SYSBUS(typeof(*s), dev);
  105. memory_region_init_io(&s->iomem, &sys_ops , s, "sys", R_MAX * 4);
  106. sysbus_init_mmio(dev, &s->iomem);
  107. /* Note: This device is not created in the board initialization,
  108. * instead it has to be added with the -device parameter. Therefore,
  109. * the device maps itself. */
  110. sysbus_mmio_map(dev, 0, s->base);
  111. return 0;
  112. }
  113. static const VMStateDescription vmstate_lm32_sys = {
  114. .name = "lm32-sys",
  115. .version_id = 1,
  116. .minimum_version_id = 1,
  117. .minimum_version_id_old = 1,
  118. .fields = (VMStateField[]) {
  119. VMSTATE_UINT32_ARRAY(regs, LM32SysState, R_MAX),
  120. VMSTATE_BUFFER(testname, LM32SysState),
  121. VMSTATE_END_OF_LIST()
  122. }
  123. };
  124. static Property lm32_sys_properties[] = {
  125. DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
  126. DEFINE_PROP_END_OF_LIST(),
  127. };
  128. static void lm32_sys_class_init(ObjectClass *klass, void *data)
  129. {
  130. DeviceClass *dc = DEVICE_CLASS(klass);
  131. SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
  132. k->init = lm32_sys_init;
  133. dc->reset = sys_reset;
  134. dc->vmsd = &vmstate_lm32_sys;
  135. dc->props = lm32_sys_properties;
  136. }
  137. static const TypeInfo lm32_sys_info = {
  138. .name = "lm32-sys",
  139. .parent = TYPE_SYS_BUS_DEVICE,
  140. .instance_size = sizeof(LM32SysState),
  141. .class_init = lm32_sys_class_init,
  142. };
  143. static void lm32_sys_register_types(void)
  144. {
  145. type_register_static(&lm32_sys_info);
  146. }
  147. type_init(lm32_sys_register_types)