master
c 425 lines 14.8 KB
Raw
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
27 #include "qemu/osdep.h"
28 #include "hw/dma/xlnx-zynq-devcfg.h"
29 #include "hw/core/irq.h"
30 #include "migration/vmstate.h"
31 #include "qemu/bitops.h"
32 #include "system/dma.h"
33 #include "qemu/log.h"
34 #include "qemu/module.h"
35
36 #define FREQ_HZ 900000000
37
38 #define BTT_MAX 0x400
39
40 #ifndef XLNX_ZYNQ_DEVCFG_ERR_DEBUG
41 #define XLNX_ZYNQ_DEVCFG_ERR_DEBUG 0
42 #endif
43
44 #define DB_PRINT(fmt, args...) do { \
45 if (XLNX_ZYNQ_DEVCFG_ERR_DEBUG) { \
46 qemu_log("%s: " fmt, __func__, ## args); \
47 } \
48 } while (0)
49
50 REG32(CTRL, 0x00)
51 FIELD(CTRL, FORCE_RST, 31, 1) /* Not supported, wr ignored */
52 FIELD(CTRL, PCFG_PROG_B, 30, 1)
53 FIELD(CTRL, PCAP_PR, 27, 1) /* Forced to 0 on bad unlock */
54 FIELD(CTRL, PCAP_MODE, 26, 1)
55 FIELD(CTRL, MULTIBOOT_EN, 24, 1)
56 FIELD(CTRL, USER_MODE, 15, 1)
57 FIELD(CTRL, PCFG_AES_FUSE, 12, 1)
58 FIELD(CTRL, PCFG_AES_EN, 9, 3)
59 FIELD(CTRL, SEU_EN, 8, 1)
60 FIELD(CTRL, SEC_EN, 7, 1)
61 FIELD(CTRL, SPNIDEN, 6, 1)
62 FIELD(CTRL, SPIDEN, 5, 1)
63 FIELD(CTRL, NIDEN, 4, 1)
64 FIELD(CTRL, DBGEN, 3, 1)
65 FIELD(CTRL, DAP_EN, 0, 3)
66
67 REG32(LOCK, 0x04)
68 #define AES_FUSE_LOCK 4
69 #define AES_EN_LOCK 3
70 #define SEU_LOCK 2
71 #define SEC_LOCK 1
72 #define DBG_LOCK 0
73
74 /* mapping bits in R_LOCK to what they lock in R_CTRL */
75 static const uint32_t lock_ctrl_map[] = {
76 [AES_FUSE_LOCK] = R_CTRL_PCFG_AES_FUSE_MASK,
77 [AES_EN_LOCK] = R_CTRL_PCFG_AES_EN_MASK,
78 [SEU_LOCK] = R_CTRL_SEU_EN_MASK,
79 [SEC_LOCK] = R_CTRL_SEC_EN_MASK,
80 [DBG_LOCK] = R_CTRL_SPNIDEN_MASK | R_CTRL_SPIDEN_MASK |
81 R_CTRL_NIDEN_MASK | R_CTRL_DBGEN_MASK |
82 R_CTRL_DAP_EN_MASK,
83 };
84
85 REG32(CFG, 0x08)
86 FIELD(CFG, RFIFO_TH, 10, 2)
87 FIELD(CFG, WFIFO_TH, 8, 2)
88 FIELD(CFG, RCLK_EDGE, 7, 1)
89 FIELD(CFG, WCLK_EDGE, 6, 1)
90 FIELD(CFG, DISABLE_SRC_INC, 5, 1)
91 FIELD(CFG, DISABLE_DST_INC, 4, 1)
92 #define R_CFG_RESET 0x50B
93
94 REG32(INT_STS, 0x0C)
95 FIELD(INT_STS, PSS_GTS_USR_B, 31, 1)
96 FIELD(INT_STS, PSS_FST_CFG_B, 30, 1)
97 FIELD(INT_STS, PSS_CFG_RESET_B, 27, 1)
98 FIELD(INT_STS, RX_FIFO_OV, 18, 1)
99 FIELD(INT_STS, WR_FIFO_LVL, 17, 1)
100 FIELD(INT_STS, RD_FIFO_LVL, 16, 1)
101 FIELD(INT_STS, DMA_CMD_ERR, 15, 1)
102 FIELD(INT_STS, DMA_Q_OV, 14, 1)
103 FIELD(INT_STS, DMA_DONE, 13, 1)
104 FIELD(INT_STS, DMA_P_DONE, 12, 1)
105 FIELD(INT_STS, P2D_LEN_ERR, 11, 1)
106 FIELD(INT_STS, PCFG_DONE, 2, 1)
107 #define R_INT_STS_RSVD ((0x7 << 24) | (0x1 << 19) | (0xF < 7))
108
109 REG32(INT_MASK, 0x10)
110
111 REG32(STATUS, 0x14)
112 FIELD(STATUS, DMA_CMD_Q_F, 31, 1)
113 FIELD(STATUS, DMA_CMD_Q_E, 30, 1)
114 FIELD(STATUS, DMA_DONE_CNT, 28, 2)
115 FIELD(STATUS, RX_FIFO_LVL, 20, 5)
116 FIELD(STATUS, TX_FIFO_LVL, 12, 7)
117 FIELD(STATUS, PSS_GTS_USR_B, 11, 1)
118 FIELD(STATUS, PSS_FST_CFG_B, 10, 1)
119 FIELD(STATUS, PSS_CFG_RESET_B, 5, 1)
120 FIELD(STATUS, PCFG_INIT, 4, 1)
121
122 REG32(DMA_SRC_ADDR, 0x18)
123 REG32(DMA_DST_ADDR, 0x1C)
124 REG32(DMA_SRC_LEN, 0x20)
125 REG32(DMA_DST_LEN, 0x24)
126 REG32(ROM_SHADOW, 0x28)
127 REG32(SW_ID, 0x30)
128 REG32(UNLOCK, 0x34)
129
130 #define R_UNLOCK_MAGIC 0x757BDF0D
131
132 REG32(MCTRL, 0x80)
133 FIELD(MCTRL, PS_VERSION, 28, 4)
134 FIELD(MCTRL, PCFG_POR_B, 8, 1)
135 FIELD(MCTRL, INT_PCAP_LPBK, 4, 1)
136 FIELD(MCTRL, QEMU, 3, 1)
137
138 static void xlnx_zynq_devcfg_update_ixr(XlnxZynqDevcfg *s)
139 {
140 qemu_set_irq(s->irq, ~s->regs[R_INT_MASK] & s->regs[R_INT_STS]);
141 }
142
143 static void xlnx_zynq_devcfg_reset(DeviceState *dev)
144 {
145 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(dev);
146 int i;
147
148 for (i = 0; i < XLNX_ZYNQ_DEVCFG_R_MAX; ++i) {
149 register_reset(&s->regs_info[i]);
150 }
151 }
152
153 static void xlnx_zynq_devcfg_dma_go(XlnxZynqDevcfg *s)
154 {
155 do {
156 uint8_t buf[BTT_MAX];
157 XlnxZynqDevcfgDMACmd *dmah = s->dma_cmd_fifo;
158 uint32_t btt = BTT_MAX;
159 bool loopback = s->regs[R_MCTRL] & R_MCTRL_INT_PCAP_LPBK_MASK;
160
161 btt = MIN(btt, dmah->src_len);
162 if (loopback) {
163 btt = MIN(btt, dmah->dest_len);
164 }
165 DB_PRINT("reading %x bytes from %x\n", btt, dmah->src_addr);
166 dma_memory_read(&address_space_memory, dmah->src_addr, buf, btt,
167 MEMTXATTRS_UNSPECIFIED);
168 dmah->src_len -= btt;
169 dmah->src_addr += btt;
170 if (loopback && (dmah->src_len || dmah->dest_len)) {
171 DB_PRINT("writing %x bytes from %x\n", btt, dmah->dest_addr);
172 dma_memory_write(&address_space_memory, dmah->dest_addr, buf, btt,
173 MEMTXATTRS_UNSPECIFIED);
174 dmah->dest_len -= btt;
175 dmah->dest_addr += btt;
176 }
177 if (!dmah->src_len && !dmah->dest_len) {
178 DB_PRINT("dma operation finished\n");
179 s->regs[R_INT_STS] |= R_INT_STS_DMA_DONE_MASK |
180 R_INT_STS_DMA_P_DONE_MASK;
181 s->dma_cmd_fifo_num--;
182 memmove(s->dma_cmd_fifo, &s->dma_cmd_fifo[1],
183 sizeof(s->dma_cmd_fifo) - sizeof(s->dma_cmd_fifo[0]));
184 }
185 xlnx_zynq_devcfg_update_ixr(s);
186 } while (s->dma_cmd_fifo_num);
187 }
188
189 static void r_ixr_post_write(RegisterInfo *reg, uint64_t val)
190 {
191 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
192
193 s->regs[R_INT_STS] |= R_INT_STS_PCFG_DONE_MASK;
194
195 xlnx_zynq_devcfg_update_ixr(s);
196 }
197
198 static uint64_t r_ctrl_pre_write(RegisterInfo *reg, uint64_t val)
199 {
200 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
201 int i;
202
203 for (i = 0; i < ARRAY_SIZE(lock_ctrl_map); ++i) {
204 if (s->regs[R_LOCK] & 1 << i) {
205 val &= ~lock_ctrl_map[i];
206 val |= lock_ctrl_map[i] & s->regs[R_CTRL];
207 }
208 }
209
210 if (FIELD_EX32(val, CTRL, PCFG_PROG_B)) {
211 s->regs[R_STATUS] |= R_STATUS_PCFG_INIT_MASK;
212 } else {
213 s->regs[R_STATUS] &= ~R_STATUS_PCFG_INIT_MASK;
214 }
215
216 return val;
217 }
218
219 static void r_ctrl_post_write(RegisterInfo *reg, uint64_t val)
220 {
221 const char *device_prefix = object_get_typename(OBJECT(reg->opaque));
222 uint32_t aes_en = FIELD_EX32(val, CTRL, PCFG_AES_EN);
223
224 if (aes_en != 0 && aes_en != 7) {
225 qemu_log_mask(LOG_UNIMP, "%s: warning, aes-en bits inconsistent,"
226 "unimplemented security reset should happen!\n",
227 device_prefix);
228 }
229 }
230
231 static void r_unlock_post_write(RegisterInfo *reg, uint64_t val)
232 {
233 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
234 const char *device_prefix = object_get_typename(OBJECT(s));
235 if (device_is_in_reset(DEVICE(s))) {
236 return;
237 }
238 if (val == R_UNLOCK_MAGIC) {
239 DB_PRINT("successful unlock\n");
240 s->regs[R_CTRL] |= R_CTRL_PCAP_PR_MASK;
241 s->regs[R_CTRL] |= R_CTRL_PCFG_AES_EN_MASK;
242 memory_region_set_enabled(&s->iomem, true);
243 } else { /* bad unlock attempt */
244 qemu_log_mask(LOG_GUEST_ERROR, "%s: failed unlock\n", device_prefix);
245 s->regs[R_CTRL] &= ~R_CTRL_PCAP_PR_MASK;
246 s->regs[R_CTRL] &= ~R_CTRL_PCFG_AES_EN_MASK;
247 /* core becomes inaccessible */
248 memory_region_set_enabled(&s->iomem, false);
249 }
250 }
251
252 static uint64_t r_lock_pre_write(RegisterInfo *reg, uint64_t val)
253 {
254 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
255
256 /* once bits are locked they stay locked */
257 return s->regs[R_LOCK] | val;
258 }
259
260 static void r_dma_dst_len_post_write(RegisterInfo *reg, uint64_t val)
261 {
262 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(reg->opaque);
263 if ((s->regs[R_DMA_DST_ADDR]) == 0xffffffff) {
264 DB_PRINT("bitstream loading detected\n");
265 s->regs[R_INT_STS] |= R_INT_STS_DMA_DONE_MASK |
266 R_INT_STS_DMA_P_DONE_MASK |
267 R_INT_STS_PCFG_DONE_MASK;
268 xlnx_zynq_devcfg_update_ixr(s);
269 return;
270 }
271 s->dma_cmd_fifo[s->dma_cmd_fifo_num] = (XlnxZynqDevcfgDMACmd) {
272 .src_addr = s->regs[R_DMA_SRC_ADDR] & ~0x3UL,
273 .dest_addr = s->regs[R_DMA_DST_ADDR] & ~0x3UL,
274 .src_len = s->regs[R_DMA_SRC_LEN] << 2,
275 .dest_len = s->regs[R_DMA_DST_LEN] << 2,
276 };
277 s->dma_cmd_fifo_num++;
278 DB_PRINT("dma transfer started; %d total transfers pending\n",
279 s->dma_cmd_fifo_num);
280 xlnx_zynq_devcfg_dma_go(s);
281 }
282
283 static const RegisterAccessInfo xlnx_zynq_devcfg_regs_info[] = {
284 { .name = "CTRL", .addr = A_CTRL,
285 .reset = R_CTRL_PCAP_PR_MASK | R_CTRL_PCAP_MODE_MASK | 0x3 << 13,
286 .rsvd = 0x1 << 28 | 0x3ff << 13 | 0x3 << 13,
287 .pre_write = r_ctrl_pre_write,
288 .post_write = r_ctrl_post_write,
289 },
290 { .name = "LOCK", .addr = A_LOCK,
291 .rsvd = MAKE_64BIT_MASK(5, 64 - 5),
292 .pre_write = r_lock_pre_write,
293 },
294 { .name = "CFG", .addr = A_CFG,
295 .reset = R_CFG_RESET,
296 .rsvd = 0xfffff00f,
297 },
298 { .name = "INT_STS", .addr = A_INT_STS,
299 .w1c = ~R_INT_STS_RSVD,
300 .reset = R_INT_STS_PSS_GTS_USR_B_MASK |
301 R_INT_STS_PSS_CFG_RESET_B_MASK |
302 R_INT_STS_WR_FIFO_LVL_MASK,
303 .rsvd = R_INT_STS_RSVD,
304 .post_write = r_ixr_post_write,
305 },
306 { .name = "INT_MASK", .addr = A_INT_MASK,
307 .reset = ~0,
308 .rsvd = R_INT_STS_RSVD,
309 .post_write = r_ixr_post_write,
310 },
311 { .name = "STATUS", .addr = A_STATUS,
312 .reset = R_STATUS_DMA_CMD_Q_E_MASK |
313 R_STATUS_PSS_GTS_USR_B_MASK |
314 R_STATUS_PSS_CFG_RESET_B_MASK,
315 .ro = ~0,
316 },
317 { .name = "DMA_SRC_ADDR", .addr = A_DMA_SRC_ADDR, },
318 { .name = "DMA_DST_ADDR", .addr = A_DMA_DST_ADDR, },
319 { .name = "DMA_SRC_LEN", .addr = A_DMA_SRC_LEN,
320 .ro = MAKE_64BIT_MASK(27, 64 - 27) },
321 { .name = "DMA_DST_LEN", .addr = A_DMA_DST_LEN,
322 .ro = MAKE_64BIT_MASK(27, 64 - 27),
323 .post_write = r_dma_dst_len_post_write,
324 },
325 { .name = "ROM_SHADOW", .addr = A_ROM_SHADOW,
326 .rsvd = ~0ull,
327 },
328 { .name = "SW_ID", .addr = A_SW_ID, },
329 { .name = "UNLOCK", .addr = A_UNLOCK,
330 .post_write = r_unlock_post_write,
331 },
332 { .name = "MCTRL", .addr = R_MCTRL * 4,
333 /* Silicon 3.0 for version field, the mysterious reserved bit 23
334 * and QEMU platform identifier.
335 */
336 .reset = 0x2 << R_MCTRL_PS_VERSION_SHIFT | 1 << 23 |
337 R_MCTRL_PCFG_POR_B_MASK | R_MCTRL_QEMU_MASK,
338 .ro = ~R_MCTRL_INT_PCAP_LPBK_MASK,
339 .rsvd = 0x00f00303,
340 },
341 };
342
343 static const MemoryRegionOps xlnx_zynq_devcfg_reg_ops = {
344 .read = register_read_memory,
345 .write = register_write_memory,
346 .endianness = DEVICE_LITTLE_ENDIAN,
347 .valid = {
348 .min_access_size = 4,
349 .max_access_size = 4,
350 }
351 };
352
353 static const VMStateDescription vmstate_xlnx_zynq_devcfg_dma_cmd = {
354 .name = "xlnx_zynq_devcfg_dma_cmd",
355 .version_id = 1,
356 .minimum_version_id = 1,
357 .fields = (const VMStateField[]) {
358 VMSTATE_UINT32(src_addr, XlnxZynqDevcfgDMACmd),
359 VMSTATE_UINT32(dest_addr, XlnxZynqDevcfgDMACmd),
360 VMSTATE_UINT32(src_len, XlnxZynqDevcfgDMACmd),
361 VMSTATE_UINT32(dest_len, XlnxZynqDevcfgDMACmd),
362 VMSTATE_END_OF_LIST()
363 }
364 };
365
366 static const VMStateDescription vmstate_xlnx_zynq_devcfg = {
367 .name = "xlnx_zynq_devcfg",
368 .version_id = 1,
369 .minimum_version_id = 1,
370 .fields = (const VMStateField[]) {
371 VMSTATE_STRUCT_ARRAY(dma_cmd_fifo, XlnxZynqDevcfg,
372 XLNX_ZYNQ_DEVCFG_DMA_CMD_FIFO_LEN, 0,
373 vmstate_xlnx_zynq_devcfg_dma_cmd,
374 XlnxZynqDevcfgDMACmd),
375 VMSTATE_UINT8(dma_cmd_fifo_num, XlnxZynqDevcfg),
376 VMSTATE_UINT32_ARRAY(regs, XlnxZynqDevcfg, XLNX_ZYNQ_DEVCFG_R_MAX),
377 VMSTATE_END_OF_LIST()
378 }
379 };
380
381 static void xlnx_zynq_devcfg_init(Object *obj)
382 {
383 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
384 XlnxZynqDevcfg *s = XLNX_ZYNQ_DEVCFG(obj);
385 RegisterInfoArray *reg_array;
386
387 sysbus_init_irq(sbd, &s->irq);
388
389 memory_region_init(&s->iomem, obj, "devcfg", XLNX_ZYNQ_DEVCFG_R_MAX * 4);
390 reg_array =
391 register_init_block32(DEVICE(obj), xlnx_zynq_devcfg_regs_info,
392 ARRAY_SIZE(xlnx_zynq_devcfg_regs_info),
393 s->regs_info, s->regs,
394 &xlnx_zynq_devcfg_reg_ops,
395 XLNX_ZYNQ_DEVCFG_ERR_DEBUG,
396 XLNX_ZYNQ_DEVCFG_R_MAX * 4);
397 memory_region_add_subregion(&s->iomem,
398 A_CTRL,
399 &reg_array->mem);
400
401 sysbus_init_mmio(sbd, &s->iomem);
402 }
403
404 static void xlnx_zynq_devcfg_class_init(ObjectClass *klass, const void *data)
405 {
406 DeviceClass *dc = DEVICE_CLASS(klass);
407
408 device_class_set_legacy_reset(dc, xlnx_zynq_devcfg_reset);
409 dc->vmsd = &vmstate_xlnx_zynq_devcfg;
410 }
411
412 static const TypeInfo xlnx_zynq_devcfg_info = {
413 .name = TYPE_XLNX_ZYNQ_DEVCFG,
414 .parent = TYPE_SYS_BUS_DEVICE,
415 .instance_size = sizeof(XlnxZynqDevcfg),
416 .instance_init = xlnx_zynq_devcfg_init,
417 .class_init = xlnx_zynq_devcfg_class_init,
418 };
419
420 static void xlnx_zynq_devcfg_register_types(void)
421 {
422 type_register_static(&xlnx_zynq_devcfg_info);
423 }
424
425 type_init(xlnx_zynq_devcfg_register_types)