avr_usart.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * AVR USART
  3. *
  4. * Copyright (c) 2018 University of Kent
  5. * Author: Sarah Harris
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, see
  19. * <http://www.gnu.org/licenses/lgpl-2.1.html>
  20. */
  21. #include "qemu/osdep.h"
  22. #include "hw/char/avr_usart.h"
  23. #include "qemu/log.h"
  24. #include "hw/irq.h"
  25. #include "hw/qdev-properties.h"
  26. #include "hw/qdev-properties-system.h"
  27. static int avr_usart_can_receive(void *opaque)
  28. {
  29. AVRUsartState *usart = opaque;
  30. if (usart->data_valid || !(usart->csrb & USART_CSRB_RXEN)) {
  31. return 0;
  32. }
  33. return 1;
  34. }
  35. static void avr_usart_receive(void *opaque, const uint8_t *buffer, int size)
  36. {
  37. AVRUsartState *usart = opaque;
  38. assert(size == 1);
  39. assert(!usart->data_valid);
  40. usart->data = buffer[0];
  41. usart->data_valid = true;
  42. usart->csra |= USART_CSRA_RXC;
  43. if (usart->csrb & USART_CSRB_RXCIE) {
  44. qemu_set_irq(usart->rxc_irq, 1);
  45. }
  46. }
  47. static void update_char_mask(AVRUsartState *usart)
  48. {
  49. uint8_t mode = ((usart->csrc & USART_CSRC_CSZ0) ? 1 : 0) |
  50. ((usart->csrc & USART_CSRC_CSZ1) ? 2 : 0) |
  51. ((usart->csrb & USART_CSRB_CSZ2) ? 4 : 0);
  52. switch (mode) {
  53. case 0:
  54. usart->char_mask = 0b11111;
  55. break;
  56. case 1:
  57. usart->char_mask = 0b111111;
  58. break;
  59. case 2:
  60. usart->char_mask = 0b1111111;
  61. break;
  62. case 3:
  63. usart->char_mask = 0b11111111;
  64. break;
  65. case 4:
  66. /* Fallthrough. */
  67. case 5:
  68. /* Fallthrough. */
  69. case 6:
  70. qemu_log_mask(
  71. LOG_GUEST_ERROR,
  72. "%s: Reserved character size 0x%x\n",
  73. __func__,
  74. mode);
  75. break;
  76. case 7:
  77. qemu_log_mask(
  78. LOG_GUEST_ERROR,
  79. "%s: Nine bit character size not supported (forcing eight)\n",
  80. __func__);
  81. usart->char_mask = 0b11111111;
  82. break;
  83. default:
  84. assert(0);
  85. }
  86. }
  87. static void avr_usart_reset(DeviceState *dev)
  88. {
  89. AVRUsartState *usart = AVR_USART(dev);
  90. usart->data_valid = false;
  91. usart->csra = 0b00100000;
  92. usart->csrb = 0b00000000;
  93. usart->csrc = 0b00000110;
  94. usart->brrl = 0;
  95. usart->brrh = 0;
  96. update_char_mask(usart);
  97. qemu_set_irq(usart->rxc_irq, 0);
  98. qemu_set_irq(usart->txc_irq, 0);
  99. qemu_set_irq(usart->dre_irq, 0);
  100. }
  101. static uint64_t avr_usart_read(void *opaque, hwaddr addr, unsigned int size)
  102. {
  103. AVRUsartState *usart = opaque;
  104. uint8_t data;
  105. assert(size == 1);
  106. if (!usart->enabled) {
  107. return 0;
  108. }
  109. switch (addr) {
  110. case USART_DR:
  111. if (!(usart->csrb & USART_CSRB_RXEN)) {
  112. /* Receiver disabled, ignore. */
  113. return 0;
  114. }
  115. if (usart->data_valid) {
  116. data = usart->data & usart->char_mask;
  117. usart->data_valid = false;
  118. } else {
  119. data = 0;
  120. }
  121. usart->csra &= 0xff ^ USART_CSRA_RXC;
  122. qemu_set_irq(usart->rxc_irq, 0);
  123. qemu_chr_fe_accept_input(&usart->chr);
  124. return data;
  125. case USART_CSRA:
  126. return usart->csra;
  127. case USART_CSRB:
  128. return usart->csrb;
  129. case USART_CSRC:
  130. return usart->csrc;
  131. case USART_BRRL:
  132. return usart->brrl;
  133. case USART_BRRH:
  134. return usart->brrh;
  135. default:
  136. qemu_log_mask(
  137. LOG_GUEST_ERROR,
  138. "%s: Bad offset 0x%"HWADDR_PRIx"\n",
  139. __func__,
  140. addr);
  141. }
  142. return 0;
  143. }
  144. static void avr_usart_write(void *opaque, hwaddr addr, uint64_t value,
  145. unsigned int size)
  146. {
  147. AVRUsartState *usart = opaque;
  148. uint8_t mask;
  149. uint8_t data;
  150. assert((value & 0xff) == value);
  151. assert(size == 1);
  152. if (!usart->enabled) {
  153. return;
  154. }
  155. switch (addr) {
  156. case USART_DR:
  157. if (!(usart->csrb & USART_CSRB_TXEN)) {
  158. /* Transmitter disabled, ignore. */
  159. return;
  160. }
  161. usart->csra |= USART_CSRA_TXC;
  162. usart->csra |= USART_CSRA_DRE;
  163. if (usart->csrb & USART_CSRB_TXCIE) {
  164. qemu_set_irq(usart->txc_irq, 1);
  165. usart->csra &= 0xff ^ USART_CSRA_TXC;
  166. }
  167. if (usart->csrb & USART_CSRB_DREIE) {
  168. qemu_set_irq(usart->dre_irq, 1);
  169. }
  170. data = value;
  171. qemu_chr_fe_write_all(&usart->chr, &data, 1);
  172. break;
  173. case USART_CSRA:
  174. mask = 0b01000011;
  175. /* Mask read-only bits. */
  176. value = (value & mask) | (usart->csra & (0xff ^ mask));
  177. usart->csra = value;
  178. if (value & USART_CSRA_TXC) {
  179. usart->csra ^= USART_CSRA_TXC;
  180. qemu_set_irq(usart->txc_irq, 0);
  181. }
  182. if (value & USART_CSRA_MPCM) {
  183. qemu_log_mask(
  184. LOG_GUEST_ERROR,
  185. "%s: MPCM not supported by USART\n",
  186. __func__);
  187. }
  188. break;
  189. case USART_CSRB:
  190. mask = 0b11111101;
  191. /* Mask read-only bits. */
  192. value = (value & mask) | (usart->csrb & (0xff ^ mask));
  193. usart->csrb = value;
  194. if (!(value & USART_CSRB_RXEN)) {
  195. /* Receiver disabled, flush input buffer. */
  196. usart->data_valid = false;
  197. }
  198. qemu_set_irq(usart->rxc_irq,
  199. ((value & USART_CSRB_RXCIE) &&
  200. (usart->csra & USART_CSRA_RXC)) ? 1 : 0);
  201. qemu_set_irq(usart->txc_irq,
  202. ((value & USART_CSRB_TXCIE) &&
  203. (usart->csra & USART_CSRA_TXC)) ? 1 : 0);
  204. qemu_set_irq(usart->dre_irq,
  205. ((value & USART_CSRB_DREIE) &&
  206. (usart->csra & USART_CSRA_DRE)) ? 1 : 0);
  207. update_char_mask(usart);
  208. break;
  209. case USART_CSRC:
  210. usart->csrc = value;
  211. if ((value & USART_CSRC_MSEL1) && (value & USART_CSRC_MSEL0)) {
  212. qemu_log_mask(
  213. LOG_GUEST_ERROR,
  214. "%s: SPI mode not supported by USART\n",
  215. __func__);
  216. }
  217. if ((value & USART_CSRC_MSEL1) && !(value & USART_CSRC_MSEL0)) {
  218. qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad USART mode\n", __func__);
  219. }
  220. if (!(value & USART_CSRC_PM1) && (value & USART_CSRC_PM0)) {
  221. qemu_log_mask(
  222. LOG_GUEST_ERROR,
  223. "%s: Bad USART parity mode\n",
  224. __func__);
  225. }
  226. update_char_mask(usart);
  227. break;
  228. case USART_BRRL:
  229. usart->brrl = value;
  230. break;
  231. case USART_BRRH:
  232. usart->brrh = value & 0b00001111;
  233. break;
  234. default:
  235. qemu_log_mask(
  236. LOG_GUEST_ERROR,
  237. "%s: Bad offset 0x%"HWADDR_PRIx"\n",
  238. __func__,
  239. addr);
  240. }
  241. }
  242. static const MemoryRegionOps avr_usart_ops = {
  243. .read = avr_usart_read,
  244. .write = avr_usart_write,
  245. .endianness = DEVICE_NATIVE_ENDIAN,
  246. .impl = {.min_access_size = 1, .max_access_size = 1}
  247. };
  248. static Property avr_usart_properties[] = {
  249. DEFINE_PROP_CHR("chardev", AVRUsartState, chr),
  250. DEFINE_PROP_END_OF_LIST(),
  251. };
  252. static void avr_usart_pr(void *opaque, int irq, int level)
  253. {
  254. AVRUsartState *s = AVR_USART(opaque);
  255. s->enabled = !level;
  256. if (!s->enabled) {
  257. avr_usart_reset(DEVICE(s));
  258. }
  259. }
  260. static void avr_usart_init(Object *obj)
  261. {
  262. AVRUsartState *s = AVR_USART(obj);
  263. sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rxc_irq);
  264. sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->dre_irq);
  265. sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->txc_irq);
  266. memory_region_init_io(&s->mmio, obj, &avr_usart_ops, s, TYPE_AVR_USART, 7);
  267. sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
  268. qdev_init_gpio_in(DEVICE(s), avr_usart_pr, 1);
  269. s->enabled = true;
  270. }
  271. static void avr_usart_realize(DeviceState *dev, Error **errp)
  272. {
  273. AVRUsartState *s = AVR_USART(dev);
  274. qemu_chr_fe_set_handlers(&s->chr, avr_usart_can_receive,
  275. avr_usart_receive, NULL, NULL,
  276. s, NULL, true);
  277. avr_usart_reset(dev);
  278. }
  279. static void avr_usart_class_init(ObjectClass *klass, void *data)
  280. {
  281. DeviceClass *dc = DEVICE_CLASS(klass);
  282. device_class_set_legacy_reset(dc, avr_usart_reset);
  283. device_class_set_props(dc, avr_usart_properties);
  284. dc->realize = avr_usart_realize;
  285. }
  286. static const TypeInfo avr_usart_info = {
  287. .name = TYPE_AVR_USART,
  288. .parent = TYPE_SYS_BUS_DEVICE,
  289. .instance_size = sizeof(AVRUsartState),
  290. .instance_init = avr_usart_init,
  291. .class_init = avr_usart_class_init,
  292. };
  293. static void avr_usart_register_types(void)
  294. {
  295. type_register_static(&avr_usart_info);
  296. }
  297. type_init(avr_usart_register_types)