2
0

stm32f2xx_syscfg.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * STM32F2XX SYSCFG
  3. *
  4. * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "hw/misc/stm32f2xx_syscfg.h"
  26. #include "qemu/log.h"
  27. #include "qemu/module.h"
  28. #ifndef STM_SYSCFG_ERR_DEBUG
  29. #define STM_SYSCFG_ERR_DEBUG 0
  30. #endif
  31. #define DB_PRINT_L(lvl, fmt, args...) do { \
  32. if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
  33. qemu_log("%s: " fmt, __func__, ## args); \
  34. } \
  35. } while (0)
  36. #define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
  37. static void stm32f2xx_syscfg_reset(DeviceState *dev)
  38. {
  39. STM32F2XXSyscfgState *s = STM32F2XX_SYSCFG(dev);
  40. s->syscfg_memrmp = 0x00000000;
  41. s->syscfg_pmc = 0x00000000;
  42. s->syscfg_exticr1 = 0x00000000;
  43. s->syscfg_exticr2 = 0x00000000;
  44. s->syscfg_exticr3 = 0x00000000;
  45. s->syscfg_exticr4 = 0x00000000;
  46. s->syscfg_cmpcr = 0x00000000;
  47. }
  48. static uint64_t stm32f2xx_syscfg_read(void *opaque, hwaddr addr,
  49. unsigned int size)
  50. {
  51. STM32F2XXSyscfgState *s = opaque;
  52. DB_PRINT("0x%"HWADDR_PRIx"\n", addr);
  53. switch (addr) {
  54. case SYSCFG_MEMRMP:
  55. return s->syscfg_memrmp;
  56. case SYSCFG_PMC:
  57. return s->syscfg_pmc;
  58. case SYSCFG_EXTICR1:
  59. return s->syscfg_exticr1;
  60. case SYSCFG_EXTICR2:
  61. return s->syscfg_exticr2;
  62. case SYSCFG_EXTICR3:
  63. return s->syscfg_exticr3;
  64. case SYSCFG_EXTICR4:
  65. return s->syscfg_exticr4;
  66. case SYSCFG_CMPCR:
  67. return s->syscfg_cmpcr;
  68. default:
  69. qemu_log_mask(LOG_GUEST_ERROR,
  70. "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
  71. return 0;
  72. }
  73. return 0;
  74. }
  75. static void stm32f2xx_syscfg_write(void *opaque, hwaddr addr,
  76. uint64_t val64, unsigned int size)
  77. {
  78. STM32F2XXSyscfgState *s = opaque;
  79. uint32_t value = val64;
  80. DB_PRINT("0x%x, 0x%"HWADDR_PRIx"\n", value, addr);
  81. switch (addr) {
  82. case SYSCFG_MEMRMP:
  83. qemu_log_mask(LOG_UNIMP,
  84. "%s: Changing the memory mapping isn't supported " \
  85. "in QEMU\n", __func__);
  86. return;
  87. case SYSCFG_PMC:
  88. qemu_log_mask(LOG_UNIMP,
  89. "%s: Changing the memory mapping isn't supported " \
  90. "in QEMU\n", __func__);
  91. return;
  92. case SYSCFG_EXTICR1:
  93. s->syscfg_exticr1 = (value & 0xFFFF);
  94. return;
  95. case SYSCFG_EXTICR2:
  96. s->syscfg_exticr2 = (value & 0xFFFF);
  97. return;
  98. case SYSCFG_EXTICR3:
  99. s->syscfg_exticr3 = (value & 0xFFFF);
  100. return;
  101. case SYSCFG_EXTICR4:
  102. s->syscfg_exticr4 = (value & 0xFFFF);
  103. return;
  104. case SYSCFG_CMPCR:
  105. s->syscfg_cmpcr = value;
  106. return;
  107. default:
  108. qemu_log_mask(LOG_GUEST_ERROR,
  109. "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
  110. }
  111. }
  112. static const MemoryRegionOps stm32f2xx_syscfg_ops = {
  113. .read = stm32f2xx_syscfg_read,
  114. .write = stm32f2xx_syscfg_write,
  115. .endianness = DEVICE_NATIVE_ENDIAN,
  116. };
  117. static void stm32f2xx_syscfg_init(Object *obj)
  118. {
  119. STM32F2XXSyscfgState *s = STM32F2XX_SYSCFG(obj);
  120. memory_region_init_io(&s->mmio, obj, &stm32f2xx_syscfg_ops, s,
  121. TYPE_STM32F2XX_SYSCFG, 0x400);
  122. sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
  123. }
  124. static void stm32f2xx_syscfg_class_init(ObjectClass *klass, void *data)
  125. {
  126. DeviceClass *dc = DEVICE_CLASS(klass);
  127. device_class_set_legacy_reset(dc, stm32f2xx_syscfg_reset);
  128. }
  129. static const TypeInfo stm32f2xx_syscfg_info = {
  130. .name = TYPE_STM32F2XX_SYSCFG,
  131. .parent = TYPE_SYS_BUS_DEVICE,
  132. .instance_size = sizeof(STM32F2XXSyscfgState),
  133. .instance_init = stm32f2xx_syscfg_init,
  134. .class_init = stm32f2xx_syscfg_class_init,
  135. };
  136. static void stm32f2xx_syscfg_register_types(void)
  137. {
  138. type_register_static(&stm32f2xx_syscfg_info);
  139. }
  140. type_init(stm32f2xx_syscfg_register_types)