xlnx-zynq-devcfg.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. /*
  2. * QEMU model of the Xilinx Zynq Devcfg Interface
  3. *
  4. * (C) 2011 PetaLogix Pty Ltd
  5. * (C) 2014 Xilinx Inc.
  6. * Written by Peter Crosthwaite <peter.crosthwaite@xilinx.com>
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include "qemu/osdep.h"
  27. #include "hw/dma/xlnx-zynq-devcfg.h"
  28. #include "hw/irq.h"
  29. #include "migration/vmstate.h"
  30. #include "qemu/bitops.h"
  31. #include "sysemu/dma.h"
  32. #include "qemu/log.h"
  33. #include "qemu/module.h"
  34. #define FREQ_HZ 900000000
  35. #define BTT_MAX 0x400
  36. #ifndef XLNX_ZYNQ_DEVCFG_ERR_DEBUG
  37. #define XLNX_ZYNQ_DEVCFG_ERR_DEBUG 0
  38. #endif
  39. #define DB_PRINT(fmt, args...) do { \
  40. if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
  41. qemu_log("%s: " fmt, __func__, ## args); \
  42. } \
  43. } while (0)
  44. REG32(CTRL, 0x00)
  45. FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */
  46. FIELD(CTRL, PCAP_PR, 27, 1) /* Forced to 0 on bad unlock */
  47. FIELD(CTRL, PCAP_MODE, 26, 1)
  48. FIELD(CTRL, MULTIBOOT_EN, 24, 1)
  49. FIELD(CTRL, USER_MODE, 15, 1)
  50. FIELD(CTRL, PCFG_AES_FUSE, 12, 1)
  51. FIELD(CTRL, PCFG_AES_EN, 9, 3)
  52. FIELD(CTRL, SEU_EN, 8, 1)
  53. FIELD(CTRL, SEC_EN, 7, 1)
  54. FIELD(CTRL, SPNIDEN, 6, 1)
  55. FIELD(CTRL, SPIDEN, 5, 1)
  56. FIELD(CTRL, NIDEN, 4, 1)
  57. FIELD(CTRL, DBGEN, 3, 1)
  58. FIELD(CTRL, DAP_EN, 0, 3)
  59. REG32(LOCK, 0x04)
  60. #define AES_FUSE_LOCK 4
  61. #define AES_EN_LOCK 3
  62. #define SEU_LOCK 2
  63. #define SEC_LOCK 1
  64. #define DBG_LOCK 0
  65. /* mapping bits in R_LOCK to what they lock in R_CTRL */
  66. static const uint32_t lock_ctrl_map[] = {
  67. [AES_FUSE_LOCK] = R_CTRL_PCFG_AES_FUSE_MASK,
  68. [AES_EN_LOCK] = R_CTRL_PCFG_AES_EN_MASK,
  69. [SEU_LOCK] = R_CTRL_SEU_EN_MASK,
  70. [SEC_LOCK] = R_CTRL_SEC_EN_MASK,
  71. [DBG_LOCK] = R_CTRL_SPNIDEN_MASK | R_CTRL_SPIDEN_MASK |
  72. R_CTRL_NIDEN_MASK | R_CTRL_DBGEN_MASK |
  73. R_CTRL_DAP_EN_MASK,
  74. };
  75. REG32(CFG, 0x08)
  76. FIELD(CFG, RFIFO_TH, 10, 2)
  77. FIELD(CFG, WFIFO_TH, 8, 2)
  78. FIELD(CFG, RCLK_EDGE, 7, 1)
  79. FIELD(CFG, WCLK_EDGE, 6, 1)
  80. FIELD(CFG, DISABLE_SRC_INC, 5, 1)
  81. FIELD(CFG, DISABLE_DST_INC, 4, 1)
  82. #define R_CFG_RESET 0x50B
  83. REG32(INT_STS, 0x0C)
  84. FIELD(INT_STS, PSS_GTS_USR_B, 31, 1)
  85. FIELD(INT_STS, PSS_FST_CFG_B, 30, 1)
  86. FIELD(INT_STS, PSS_CFG_RESET_B, 27, 1)
  87. FIELD(INT_STS, RX_FIFO_OV, 18, 1)
  88. FIELD(INT_STS, WR_FIFO_LVL, 17, 1)
  89. FIELD(INT_STS, RD_FIFO_LVL, 16, 1)
  90. FIELD(INT_STS, DMA_CMD_ERR, 15, 1)
  91. FIELD(INT_STS, DMA_Q_OV, 14, 1)
  92. FIELD(INT_STS, DMA_DONE, 13, 1)
  93. FIELD(INT_STS, DMA_P_DONE, 12, 1)
  94. FIELD(INT_STS, P2D_LEN_ERR, 11, 1)
  95. FIELD(INT_STS, PCFG_DONE, 2, 1)
  96. #define R_INT_STS_RSVD ((0x7 << 24) | (0x1 << 19) | (0xF < 7))
  97. REG32(INT_MASK, 0x10)
  98. REG32(STATUS, 0x14)
  99. FIELD(STATUS, DMA_CMD_Q_F, 31, 1)
  100. FIELD(STATUS, DMA_CMD_Q_E, 30, 1)
  101. FIELD(STATUS, DMA_DONE_CNT, 28, 2)
  102. FIELD(STATUS, RX_FIFO_LVL, 20, 5)
  103. FIELD(STATUS, TX_FIFO_LVL, 12, 7)
  104. FIELD(STATUS, PSS_GTS_USR_B, 11, 1)
  105. FIELD(STATUS, PSS_FST_CFG_B, 10, 1)
  106. FIELD(STATUS, PSS_CFG_RESET_B, 5, 1)
  107. REG32(DMA_SRC_ADDR, 0x18)
  108. REG32(DMA_DST_ADDR, 0x1C)
  109. REG32(DMA_SRC_LEN, 0x20)
  110. REG32(DMA_DST_LEN, 0x24)
  111. REG32(ROM_SHADOW, 0x28)
  112. REG32(SW_ID, 0x30)
  113. REG32(UNLOCK, 0x34)
  114. #define R_UNLOCK_MAGIC 0x757BDF0D
  115. REG32(MCTRL, 0x80)
  116. FIELD(MCTRL, PS_VERSION, 28, 4)
  117. FIELD(MCTRL, PCFG_POR_B, 8, 1)
  118. FIELD(MCTRL, INT_PCAP_LPBK, 4, 1)
  119. FIELD(MCTRL, QEMU, 3, 1)
  120. static void xlnx_zynq_devcfg_update_ixr(XlnxZynqDevcfg *s)
  121. {
  122. qemu_set_irq(s->irq, ~s->regs[R_INT_MASK] & s->regs[R_INT_STS]);
  123. }
  124. static void xlnx_zynq_devcfg_reset(DeviceState *dev)
  125. {
  126. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(dev);
  127. int i;
  128. for (i = 0; i < XLNX_ZYNQ_DEVCFG_R_MAX; ++i) {
  129. register_reset(&s->regs_info[i]);
  130. }
  131. }
  132. static void xlnx_zynq_devcfg_dma_go(XlnxZynqDevcfg *s)
  133. {
  134. do {
  135. uint8_t buf[BTT_MAX];
  136. XlnxZynqDevcfgDMACmd *dmah = s->dma_cmd_fifo;
  137. uint32_t btt = BTT_MAX;
  138. bool loopback = s->regs[R_MCTRL] & R_MCTRL_INT_PCAP_LPBK_MASK;
  139. btt = MIN(btt, dmah->src_len);
  140. if (loopback) {
  141. btt = MIN(btt, dmah->dest_len);
  142. }
  143. DB_PRINT("reading %x bytes from %x\n", btt, dmah->src_addr);
  144. dma_memory_read(&address_space_memory, dmah->src_addr, buf, btt);
  145. dmah->src_len -= btt;
  146. dmah->src_addr += btt;
  147. if (loopback && (dmah->src_len || dmah->dest_len)) {
  148. DB_PRINT("writing %x bytes from %x\n", btt, dmah->dest_addr);
  149. dma_memory_write(&address_space_memory, dmah->dest_addr, buf, btt);
  150. dmah->dest_len -= btt;
  151. dmah->dest_addr += btt;
  152. }
  153. if (!dmah->src_len && !dmah->dest_len) {
  154. DB_PRINT("dma operation finished\n");
  155. s->regs[R_INT_STS] |= R_INT_STS_DMA_DONE_MASK |
  156. R_INT_STS_DMA_P_DONE_MASK;
  157. s->dma_cmd_fifo_num--;
  158. memmove(s->dma_cmd_fifo, &s->dma_cmd_fifo[1],
  159. sizeof(s->dma_cmd_fifo) - sizeof(s->dma_cmd_fifo[0]));
  160. }
  161. xlnx_zynq_devcfg_update_ixr(s);
  162. } while (s->dma_cmd_fifo_num);
  163. }
  164. static void r_ixr_post_write(RegisterInfo *reg, uint64_t val)
  165. {
  166. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
  167. xlnx_zynq_devcfg_update_ixr(s);
  168. }
  169. static uint64_t r_ctrl_pre_write(RegisterInfo *reg, uint64_t val)
  170. {
  171. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
  172. int i;
  173. for (i = 0; i < ARRAY_SIZE(lock_ctrl_map); ++i) {
  174. if (s->regs[R_LOCK] & 1 << i) {
  175. val &= ~lock_ctrl_map[i];
  176. val |= lock_ctrl_map[i] & s->regs[R_CTRL];
  177. }
  178. }
  179. return val;
  180. }
  181. static void r_ctrl_post_write(RegisterInfo *reg, uint64_t val)
  182. {
  183. const char *device_prefix = object_get_typename(OBJECT(reg->opaque));
  184. uint32_t aes_en = FIELD_EX32(val, CTRL, PCFG_AES_EN);
  185. if (aes_en != 0 && aes_en != 7) {
  186. qemu_log_mask(LOG_UNIMP, "%s: warning, aes-en bits inconsistent,"
  187. "unimplemented security reset should happen!\n",
  188. device_prefix);
  189. }
  190. }
  191. static void r_unlock_post_write(RegisterInfo *reg, uint64_t val)
  192. {
  193. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
  194. const char *device_prefix = object_get_typename(OBJECT(s));
  195. if (val == R_UNLOCK_MAGIC) {
  196. DB_PRINT("successful unlock\n");
  197. s->regs[R_CTRL] |= R_CTRL_PCAP_PR_MASK;
  198. s->regs[R_CTRL] |= R_CTRL_PCFG_AES_EN_MASK;
  199. memory_region_set_enabled(&s->iomem, true);
  200. } else { /* bad unlock attempt */
  201. qemu_log_mask(LOG_GUEST_ERROR, "%s: failed unlock\n", device_prefix);
  202. s->regs[R_CTRL] &= ~R_CTRL_PCAP_PR_MASK;
  203. s->regs[R_CTRL] &= ~R_CTRL_PCFG_AES_EN_MASK;
  204. /* core becomes inaccessible */
  205. memory_region_set_enabled(&s->iomem, false);
  206. }
  207. }
  208. static uint64_t r_lock_pre_write(RegisterInfo *reg, uint64_t val)
  209. {
  210. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
  211. /* once bits are locked they stay locked */
  212. return s->regs[R_LOCK] | val;
  213. }
  214. static void r_dma_dst_len_post_write(RegisterInfo *reg, uint64_t val)
  215. {
  216. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
  217. s->dma_cmd_fifo[s->dma_cmd_fifo_num] = (XlnxZynqDevcfgDMACmd) {
  218. .src_addr = s->regs[R_DMA_SRC_ADDR] & ~0x3UL,
  219. .dest_addr = s->regs[R_DMA_DST_ADDR] & ~0x3UL,
  220. .src_len = s->regs[R_DMA_SRC_LEN] << 2,
  221. .dest_len = s->regs[R_DMA_DST_LEN] << 2,
  222. };
  223. s->dma_cmd_fifo_num++;
  224. DB_PRINT("dma transfer started; %d total transfers pending\n",
  225. s->dma_cmd_fifo_num);
  226. xlnx_zynq_devcfg_dma_go(s);
  227. }
  228. static const RegisterAccessInfo xlnx_zynq_devcfg_regs_info[] = {
  229. { .name = "CTRL", .addr = A_CTRL,
  230. .reset = R_CTRL_PCAP_PR_MASK | R_CTRL_PCAP_MODE_MASK | 0x3 << 13,
  231. .rsvd = 0x1 << 28 | 0x3ff << 13 | 0x3 << 13,
  232. .pre_write = r_ctrl_pre_write,
  233. .post_write = r_ctrl_post_write,
  234. },
  235. { .name = "LOCK", .addr = A_LOCK,
  236. .rsvd = MAKE_64BIT_MASK(5, 64 - 5),
  237. .pre_write = r_lock_pre_write,
  238. },
  239. { .name = "CFG", .addr = A_CFG,
  240. .reset = R_CFG_RESET,
  241. .rsvd = 0xfffff00f,
  242. },
  243. { .name = "INT_STS", .addr = A_INT_STS,
  244. .w1c = ~R_INT_STS_RSVD,
  245. .reset = R_INT_STS_PSS_GTS_USR_B_MASK |
  246. R_INT_STS_PSS_CFG_RESET_B_MASK |
  247. R_INT_STS_WR_FIFO_LVL_MASK,
  248. .rsvd = R_INT_STS_RSVD,
  249. .post_write = r_ixr_post_write,
  250. },
  251. { .name = "INT_MASK", .addr = A_INT_MASK,
  252. .reset = ~0,
  253. .rsvd = R_INT_STS_RSVD,
  254. .post_write = r_ixr_post_write,
  255. },
  256. { .name = "STATUS", .addr = A_STATUS,
  257. .reset = R_STATUS_DMA_CMD_Q_E_MASK |
  258. R_STATUS_PSS_GTS_USR_B_MASK |
  259. R_STATUS_PSS_CFG_RESET_B_MASK,
  260. .ro = ~0,
  261. },
  262. { .name = "DMA_SRC_ADDR", .addr = A_DMA_SRC_ADDR, },
  263. { .name = "DMA_DST_ADDR", .addr = A_DMA_DST_ADDR, },
  264. { .name = "DMA_SRC_LEN", .addr = A_DMA_SRC_LEN,
  265. .ro = MAKE_64BIT_MASK(27, 64 - 27) },
  266. { .name = "DMA_DST_LEN", .addr = A_DMA_DST_LEN,
  267. .ro = MAKE_64BIT_MASK(27, 64 - 27),
  268. .post_write = r_dma_dst_len_post_write,
  269. },
  270. { .name = "ROM_SHADOW", .addr = A_ROM_SHADOW,
  271. .rsvd = ~0ull,
  272. },
  273. { .name = "SW_ID", .addr = A_SW_ID, },
  274. { .name = "UNLOCK", .addr = A_UNLOCK,
  275. .post_write = r_unlock_post_write,
  276. },
  277. { .name = "MCTRL", .addr = R_MCTRL * 4,
  278. /* Silicon 3.0 for version field, the mysterious reserved bit 23
  279. * and QEMU platform identifier.
  280. */
  281. .reset = 0x2 << R_MCTRL_PS_VERSION_SHIFT | 1 << 23 | R_MCTRL_QEMU_MASK,
  282. .ro = ~R_MCTRL_INT_PCAP_LPBK_MASK,
  283. .rsvd = 0x00f00303,
  284. },
  285. };
  286. static const MemoryRegionOps xlnx_zynq_devcfg_reg_ops = {
  287. .read = register_read_memory,
  288. .write = register_write_memory,
  289. .endianness = DEVICE_LITTLE_ENDIAN,
  290. .valid = {
  291. .min_access_size = 4,
  292. .max_access_size = 4,
  293. }
  294. };
  295. static const VMStateDescription vmstate_xlnx_zynq_devcfg_dma_cmd = {
  296. .name = "xlnx_zynq_devcfg_dma_cmd",
  297. .version_id = 1,
  298. .minimum_version_id = 1,
  299. .fields = (VMStateField[]) {
  300. VMSTATE_UINT32(src_addr, XlnxZynqDevcfgDMACmd),
  301. VMSTATE_UINT32(dest_addr, XlnxZynqDevcfgDMACmd),
  302. VMSTATE_UINT32(src_len, XlnxZynqDevcfgDMACmd),
  303. VMSTATE_UINT32(dest_len, XlnxZynqDevcfgDMACmd),
  304. VMSTATE_END_OF_LIST()
  305. }
  306. };
  307. static const VMStateDescription vmstate_xlnx_zynq_devcfg = {
  308. .name = "xlnx_zynq_devcfg",
  309. .version_id = 1,
  310. .minimum_version_id = 1,
  311. .fields = (VMStateField[]) {
  312. VMSTATE_STRUCT_ARRAY(dma_cmd_fifo, XlnxZynqDevcfg,
  313. XLNX_ZYNQ_DEVCFG_DMA_CMD_FIFO_LEN, 0,
  314. vmstate_xlnx_zynq_devcfg_dma_cmd,
  315. XlnxZynqDevcfgDMACmd),
  316. VMSTATE_UINT8(dma_cmd_fifo_num, XlnxZynqDevcfg),
  317. VMSTATE_UINT32_ARRAY(regs, XlnxZynqDevcfg, XLNX_ZYNQ_DEVCFG_R_MAX),
  318. VMSTATE_END_OF_LIST()
  319. }
  320. };
  321. static void xlnx_zynq_devcfg_init(Object *obj)
  322. {
  323. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  324. XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(obj);
  325. RegisterInfoArray *reg_array;
  326. sysbus_init_irq(sbd, &s->irq);
  327. memory_region_init(&s->iomem, obj, "devcfg", XLNX_ZYNQ_DEVCFG_R_MAX * 4);
  328. reg_array =
  329. register_init_block32(DEVICE(obj), xlnx_zynq_devcfg_regs_info,
  330. ARRAY_SIZE(xlnx_zynq_devcfg_regs_info),
  331. s->regs_info, s->regs,
  332. &xlnx_zynq_devcfg_reg_ops,
  333. XLNX_ZYNQ_DEVCFG_ERR_DEBUG,
  334. XLNX_ZYNQ_DEVCFG_R_MAX);
  335. memory_region_add_subregion(&s->iomem,
  336. A_CTRL,
  337. &reg_array->mem);
  338. sysbus_init_mmio(sbd, &s->iomem);
  339. }
  340. static void xlnx_zynq_devcfg_class_init(ObjectClass *klass, void *data)
  341. {
  342. DeviceClass *dc = DEVICE_CLASS(klass);
  343. dc->reset = xlnx_zynq_devcfg_reset;
  344. dc->vmsd = &vmstate_xlnx_zynq_devcfg;
  345. }
  346. static const TypeInfo xlnx_zynq_devcfg_info = {
  347. .name = TYPE_XLNX_ZYNQ_DEVCFG,
  348. .parent = TYPE_SYS_BUS_DEVICE,
  349. .instance_size = sizeof(XlnxZynqDevcfg),
  350. .instance_init = xlnx_zynq_devcfg_init,
  351. .class_init = xlnx_zynq_devcfg_class_init,
  352. };
  353. static void xlnx_zynq_devcfg_register_types(void)
  354. {
  355. type_register_static(&xlnx_zynq_devcfg_info);
  356. }
  357. type_init(xlnx_zynq_devcfg_register_types)