2
0

lm32_sys.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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.h"
  34. #include "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. uint32_t base;
  46. uint32_t regs[R_MAX];
  47. uint8_t testname[MAX_TESTNAME_LEN];
  48. };
  49. typedef struct LM32SysState LM32SysState;
  50. static void copy_testname(LM32SysState *s)
  51. {
  52. cpu_physical_memory_read(s->regs[R_TESTNAME], s->testname,
  53. MAX_TESTNAME_LEN);
  54. s->testname[MAX_TESTNAME_LEN - 1] = '\0';
  55. }
  56. static void sys_write(void *opaque, target_phys_addr_t addr, uint32_t value)
  57. {
  58. LM32SysState *s = opaque;
  59. char *testname;
  60. trace_lm32_sys_memory_write(addr, value);
  61. addr >>= 2;
  62. switch (addr) {
  63. case R_CTRL:
  64. qemu_system_shutdown_request();
  65. break;
  66. case R_PASSFAIL:
  67. s->regs[addr] = value;
  68. testname = (char *)s->testname;
  69. qemu_log("TC %-16s %s\n", testname, (value) ? "FAILED" : "OK");
  70. break;
  71. case R_TESTNAME:
  72. s->regs[addr] = value;
  73. copy_testname(s);
  74. break;
  75. default:
  76. error_report("lm32_sys: write access to unknown register 0x"
  77. TARGET_FMT_plx, addr << 2);
  78. break;
  79. }
  80. }
  81. static CPUReadMemoryFunc * const sys_read_fn[] = {
  82. NULL,
  83. NULL,
  84. NULL,
  85. };
  86. static CPUWriteMemoryFunc * const sys_write_fn[] = {
  87. NULL,
  88. NULL,
  89. &sys_write,
  90. };
  91. static void sys_reset(DeviceState *d)
  92. {
  93. LM32SysState *s = container_of(d, LM32SysState, busdev.qdev);
  94. int i;
  95. for (i = 0; i < R_MAX; i++) {
  96. s->regs[i] = 0;
  97. }
  98. memset(s->testname, 0, MAX_TESTNAME_LEN);
  99. }
  100. static int lm32_sys_init(SysBusDevice *dev)
  101. {
  102. LM32SysState *s = FROM_SYSBUS(typeof(*s), dev);
  103. int sys_regs;
  104. sys_regs = cpu_register_io_memory(sys_read_fn, sys_write_fn, s,
  105. DEVICE_NATIVE_ENDIAN);
  106. sysbus_init_mmio(dev, R_MAX * 4, sys_regs);
  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 SysBusDeviceInfo lm32_sys_info = {
  125. .init = lm32_sys_init,
  126. .qdev.name = "lm32-sys",
  127. .qdev.size = sizeof(LM32SysState),
  128. .qdev.vmsd = &vmstate_lm32_sys,
  129. .qdev.reset = sys_reset,
  130. .qdev.props = (Property[]) {
  131. DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
  132. DEFINE_PROP_END_OF_LIST(),
  133. }
  134. };
  135. static void lm32_sys_register(void)
  136. {
  137. sysbus_register_withprop(&lm32_sys_info);
  138. }
  139. device_init(lm32_sys_register)