1 /* 2 * QEMU model of Xilinx AXI-DMA block. 3 * 4 * Copyright (c) 2011 Edgar E. Iglesias. 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 25 #include "hw/sysbus.h" 26 #include "qemu/timer.h" 27 #include "hw/ptimer.h" 28 #include "qemu/log.h" 29 #include "qapi/qmp/qerror.h" 30 31 #include "hw/stream.h" 32 33 #define D(x) 34 35 #define TYPE_XILINX_AXI_DMA "xlnx.axi-dma" 36 #define TYPE_XILINX_AXI_DMA_DATA_STREAM "xilinx-axi-dma-data-stream" 37 #define TYPE_XILINX_AXI_DMA_CONTROL_STREAM "xilinx-axi-dma-control-stream" 38 39 #define XILINX_AXI_DMA(obj) \ 40 OBJECT_CHECK(XilinxAXIDMA, (obj), TYPE_XILINX_AXI_DMA) 41 42 #define XILINX_AXI_DMA_DATA_STREAM(obj) \ 43 OBJECT_CHECK(XilinxAXIDMAStreamSlave, (obj),\ 44 TYPE_XILINX_AXI_DMA_DATA_STREAM) 45 46 #define XILINX_AXI_DMA_CONTROL_STREAM(obj) \ 47 OBJECT_CHECK(XilinxAXIDMAStreamSlave, (obj),\ 48 TYPE_XILINX_AXI_DMA_CONTROL_STREAM) 49 50 #define R_DMACR (0x00 / 4) 51 #define R_DMASR (0x04 / 4) 52 #define R_CURDESC (0x08 / 4) 53 #define R_TAILDESC (0x10 / 4) 54 #define R_MAX (0x30 / 4) 55 56 #define CONTROL_PAYLOAD_WORDS 5 57 #define CONTROL_PAYLOAD_SIZE (CONTROL_PAYLOAD_WORDS * (sizeof(uint32_t))) 58 59 typedef struct XilinxAXIDMA XilinxAXIDMA; 60 typedef struct XilinxAXIDMAStreamSlave XilinxAXIDMAStreamSlave; 61 62 enum { 63 DMACR_RUNSTOP = 1, 64 DMACR_TAILPTR_MODE = 2, 65 DMACR_RESET = 4 66 }; 67 68 enum { 69 DMASR_HALTED = 1, 70 DMASR_IDLE = 2, 71 DMASR_IOC_IRQ = 1 << 12, 72 DMASR_DLY_IRQ = 1 << 13, 73 74 DMASR_IRQ_MASK = 7 << 12 75 }; 76 77 struct SDesc { 78 uint64_t nxtdesc; 79 uint64_t buffer_address; 80 uint64_t reserved; 81 uint32_t control; 82 uint32_t status; 83 uint8_t app[CONTROL_PAYLOAD_SIZE]; 84 }; 85 86 enum { 87 SDESC_CTRL_EOF = (1 << 26), 88 SDESC_CTRL_SOF = (1 << 27), 89 90 SDESC_CTRL_LEN_MASK = (1 << 23) - 1 91 }; 92 93 enum { 94 SDESC_STATUS_EOF = (1 << 26), 95 SDESC_STATUS_SOF_BIT = 27, 96 SDESC_STATUS_SOF = (1 << SDESC_STATUS_SOF_BIT), 97 SDESC_STATUS_COMPLETE = (1 << 31) 98 }; 99 100 struct Stream { 101 QEMUBH *bh; 102 ptimer_state *ptimer; 103 qemu_irq irq; 104 105 int nr; 106 107 struct SDesc desc; 108 int pos; 109 unsigned int complete_cnt; 110 uint32_t regs[R_MAX]; 111 uint8_t app[20]; 112 }; 113 114 struct XilinxAXIDMAStreamSlave { 115 Object parent; 116 117 struct XilinxAXIDMA *dma; 118 }; 119 120 struct XilinxAXIDMA { 121 SysBusDevice busdev; 122 MemoryRegion iomem; 123 uint32_t freqhz; 124 StreamSlave *tx_data_dev; 125 StreamSlave *tx_control_dev; 126 XilinxAXIDMAStreamSlave rx_data_dev; 127 XilinxAXIDMAStreamSlave rx_control_dev; 128 129 struct Stream streams[2]; 130 131 StreamCanPushNotifyFn notify; 132 void *notify_opaque; 133 }; 134 135 /* 136 * Helper calls to extract info from desriptors and other trivial 137 * state from regs. 138 */ 139 static inline int stream_desc_sof(struct SDesc *d) 140 { 141 return d->control & SDESC_CTRL_SOF; 142 } 143 144 static inline int stream_desc_eof(struct SDesc *d) 145 { 146 return d->control & SDESC_CTRL_EOF; 147 } 148 149 static inline int stream_resetting(struct Stream *s) 150 { 151 return !!(s->regs[R_DMACR] & DMACR_RESET); 152 } 153 154 static inline int stream_running(struct Stream *s) 155 { 156 return s->regs[R_DMACR] & DMACR_RUNSTOP; 157 } 158 159 static inline int stream_halted(struct Stream *s) 160 { 161 return s->regs[R_DMASR] & DMASR_HALTED; 162 } 163 164 static inline int stream_idle(struct Stream *s) 165 { 166 return !!(s->regs[R_DMASR] & DMASR_IDLE); 167 } 168 169 static void stream_reset(struct Stream *s) 170 { 171 s->regs[R_DMASR] = DMASR_HALTED; /* starts up halted. */ 172 s->regs[R_DMACR] = 1 << 16; /* Starts with one in compl threshold. */ 173 } 174 175 /* Map an offset addr into a channel index. */ 176 static inline int streamid_from_addr(hwaddr addr) 177 { 178 int sid; 179 180 sid = addr / (0x30); 181 sid &= 1; 182 return sid; 183 } 184 185 #ifdef DEBUG_ENET 186 static void stream_desc_show(struct SDesc *d) 187 { 188 qemu_log("buffer_addr = " PRIx64 "\n", d->buffer_address); 189 qemu_log("nxtdesc = " PRIx64 "\n", d->nxtdesc); 190 qemu_log("control = %x\n", d->control); 191 qemu_log("status = %x\n", d->status); 192 } 193 #endif 194 195 static void stream_desc_load(struct Stream *s, hwaddr addr) 196 { 197 struct SDesc *d = &s->desc; 198 199 cpu_physical_memory_read(addr, d, sizeof *d); 200 201 /* Convert from LE into host endianness. */ 202 d->buffer_address = le64_to_cpu(d->buffer_address); 203 d->nxtdesc = le64_to_cpu(d->nxtdesc); 204 d->control = le32_to_cpu(d->control); 205 d->status = le32_to_cpu(d->status); 206 } 207 208 static void stream_desc_store(struct Stream *s, hwaddr addr) 209 { 210 struct SDesc *d = &s->desc; 211 212 /* Convert from host endianness into LE. */ 213 d->buffer_address = cpu_to_le64(d->buffer_address); 214 d->nxtdesc = cpu_to_le64(d->nxtdesc); 215 d->control = cpu_to_le32(d->control); 216 d->status = cpu_to_le32(d->status); 217 cpu_physical_memory_write(addr, d, sizeof *d); 218 } 219 220 static void stream_update_irq(struct Stream *s) 221 { 222 unsigned int pending, mask, irq; 223 224 pending = s->regs[R_DMASR] & DMASR_IRQ_MASK; 225 mask = s->regs[R_DMACR] & DMASR_IRQ_MASK; 226 227 irq = pending & mask; 228 229 qemu_set_irq(s->irq, !!irq); 230 } 231 232 static void stream_reload_complete_cnt(struct Stream *s) 233 { 234 unsigned int comp_th; 235 comp_th = (s->regs[R_DMACR] >> 16) & 0xff; 236 s->complete_cnt = comp_th; 237 } 238 239 static void timer_hit(void *opaque) 240 { 241 struct Stream *s = opaque; 242 243 stream_reload_complete_cnt(s); 244 s->regs[R_DMASR] |= DMASR_DLY_IRQ; 245 stream_update_irq(s); 246 } 247 248 static void stream_complete(struct Stream *s) 249 { 250 unsigned int comp_delay; 251 252 /* Start the delayed timer. */ 253 comp_delay = s->regs[R_DMACR] >> 24; 254 if (comp_delay) { 255 ptimer_stop(s->ptimer); 256 ptimer_set_count(s->ptimer, comp_delay); 257 ptimer_run(s->ptimer, 1); 258 } 259 260 s->complete_cnt--; 261 if (s->complete_cnt == 0) { 262 /* Raise the IOC irq. */ 263 s->regs[R_DMASR] |= DMASR_IOC_IRQ; 264 stream_reload_complete_cnt(s); 265 } 266 } 267 268 static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev, 269 StreamSlave *tx_control_dev) 270 { 271 uint32_t prev_d; 272 unsigned char txbuf[16 * 1024]; 273 unsigned int txlen; 274 275 if (!stream_running(s) || stream_idle(s)) { 276 return; 277 } 278 279 while (1) { 280 stream_desc_load(s, s->regs[R_CURDESC]); 281 282 if (s->desc.status & SDESC_STATUS_COMPLETE) { 283 s->regs[R_DMASR] |= DMASR_HALTED; 284 break; 285 } 286 287 if (stream_desc_sof(&s->desc)) { 288 s->pos = 0; 289 stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app)); 290 } 291 292 txlen = s->desc.control & SDESC_CTRL_LEN_MASK; 293 if ((txlen + s->pos) > sizeof txbuf) { 294 hw_error("%s: too small internal txbuf! %d\n", __func__, 295 txlen + s->pos); 296 } 297 298 cpu_physical_memory_read(s->desc.buffer_address, 299 txbuf + s->pos, txlen); 300 s->pos += txlen; 301 302 if (stream_desc_eof(&s->desc)) { 303 stream_push(tx_data_dev, txbuf, s->pos); 304 s->pos = 0; 305 stream_complete(s); 306 } 307 308 /* Update the descriptor. */ 309 s->desc.status = txlen | SDESC_STATUS_COMPLETE; 310 stream_desc_store(s, s->regs[R_CURDESC]); 311 312 /* Advance. */ 313 prev_d = s->regs[R_CURDESC]; 314 s->regs[R_CURDESC] = s->desc.nxtdesc; 315 if (prev_d == s->regs[R_TAILDESC]) { 316 s->regs[R_DMASR] |= DMASR_IDLE; 317 break; 318 } 319 } 320 } 321 322 static size_t stream_process_s2mem(struct Stream *s, unsigned char *buf, 323 size_t len) 324 { 325 uint32_t prev_d; 326 unsigned int rxlen; 327 size_t pos = 0; 328 int sof = 1; 329 330 if (!stream_running(s) || stream_idle(s)) { 331 return 0; 332 } 333 334 while (len) { 335 stream_desc_load(s, s->regs[R_CURDESC]); 336 337 if (s->desc.status & SDESC_STATUS_COMPLETE) { 338 s->regs[R_DMASR] |= DMASR_HALTED; 339 break; 340 } 341 342 rxlen = s->desc.control & SDESC_CTRL_LEN_MASK; 343 if (rxlen > len) { 344 /* It fits. */ 345 rxlen = len; 346 } 347 348 cpu_physical_memory_write(s->desc.buffer_address, buf + pos, rxlen); 349 len -= rxlen; 350 pos += rxlen; 351 352 /* Update the descriptor. */ 353 if (!len) { 354 stream_complete(s); 355 memcpy(s->desc.app, s->app, sizeof(s->desc.app)); 356 s->desc.status |= SDESC_STATUS_EOF; 357 } 358 359 s->desc.status |= sof << SDESC_STATUS_SOF_BIT; 360 s->desc.status |= SDESC_STATUS_COMPLETE; 361 stream_desc_store(s, s->regs[R_CURDESC]); 362 sof = 0; 363 364 /* Advance. */ 365 prev_d = s->regs[R_CURDESC]; 366 s->regs[R_CURDESC] = s->desc.nxtdesc; 367 if (prev_d == s->regs[R_TAILDESC]) { 368 s->regs[R_DMASR] |= DMASR_IDLE; 369 break; 370 } 371 } 372 373 return pos; 374 } 375 376 static void xilinx_axidma_reset(DeviceState *dev) 377 { 378 int i; 379 XilinxAXIDMA *s = XILINX_AXI_DMA(dev); 380 381 for (i = 0; i < 2; i++) { 382 stream_reset(&s->streams[i]); 383 } 384 } 385 386 static size_t 387 xilinx_axidma_control_stream_push(StreamSlave *obj, unsigned char *buf, 388 size_t len) 389 { 390 XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(obj); 391 struct Stream *s = &cs->dma->streams[1]; 392 393 if (len != CONTROL_PAYLOAD_SIZE) { 394 hw_error("AXI DMA requires %d byte control stream payload\n", 395 (int)CONTROL_PAYLOAD_SIZE); 396 } 397 398 memcpy(s->app, buf, len); 399 return len; 400 } 401 402 static bool 403 xilinx_axidma_data_stream_can_push(StreamSlave *obj, 404 StreamCanPushNotifyFn notify, 405 void *notify_opaque) 406 { 407 XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj); 408 struct Stream *s = &ds->dma->streams[1]; 409 410 if (!stream_running(s) || stream_idle(s)) { 411 ds->dma->notify = notify; 412 ds->dma->notify_opaque = notify_opaque; 413 return false; 414 } 415 416 return true; 417 } 418 419 static size_t 420 xilinx_axidma_data_stream_push(StreamSlave *obj, unsigned char *buf, size_t len) 421 { 422 XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(obj); 423 struct Stream *s = &ds->dma->streams[1]; 424 size_t ret; 425 426 ret = stream_process_s2mem(s, buf, len); 427 stream_update_irq(s); 428 return ret; 429 } 430 431 static uint64_t axidma_read(void *opaque, hwaddr addr, 432 unsigned size) 433 { 434 XilinxAXIDMA *d = opaque; 435 struct Stream *s; 436 uint32_t r = 0; 437 int sid; 438 439 sid = streamid_from_addr(addr); 440 s = &d->streams[sid]; 441 442 addr = addr % 0x30; 443 addr >>= 2; 444 switch (addr) { 445 case R_DMACR: 446 /* Simulate one cycles reset delay. */ 447 s->regs[addr] &= ~DMACR_RESET; 448 r = s->regs[addr]; 449 break; 450 case R_DMASR: 451 s->regs[addr] &= 0xffff; 452 s->regs[addr] |= (s->complete_cnt & 0xff) << 16; 453 s->regs[addr] |= (ptimer_get_count(s->ptimer) & 0xff) << 24; 454 r = s->regs[addr]; 455 break; 456 default: 457 r = s->regs[addr]; 458 D(qemu_log("%s ch=%d addr=" TARGET_FMT_plx " v=%x\n", 459 __func__, sid, addr * 4, r)); 460 break; 461 } 462 return r; 463 464 } 465 466 static void axidma_write(void *opaque, hwaddr addr, 467 uint64_t value, unsigned size) 468 { 469 XilinxAXIDMA *d = opaque; 470 struct Stream *s; 471 int sid; 472 473 sid = streamid_from_addr(addr); 474 s = &d->streams[sid]; 475 476 addr = addr % 0x30; 477 addr >>= 2; 478 switch (addr) { 479 case R_DMACR: 480 /* Tailptr mode is always on. */ 481 value |= DMACR_TAILPTR_MODE; 482 /* Remember our previous reset state. */ 483 value |= (s->regs[addr] & DMACR_RESET); 484 s->regs[addr] = value; 485 486 if (value & DMACR_RESET) { 487 stream_reset(s); 488 } 489 490 if ((value & 1) && !stream_resetting(s)) { 491 /* Start processing. */ 492 s->regs[R_DMASR] &= ~(DMASR_HALTED | DMASR_IDLE); 493 } 494 stream_reload_complete_cnt(s); 495 break; 496 497 case R_DMASR: 498 /* Mask away write to clear irq lines. */ 499 value &= ~(value & DMASR_IRQ_MASK); 500 s->regs[addr] = value; 501 break; 502 503 case R_TAILDESC: 504 s->regs[addr] = value; 505 s->regs[R_DMASR] &= ~DMASR_IDLE; /* Not idle. */ 506 if (!sid) { 507 stream_process_mem2s(s, d->tx_data_dev, d->tx_control_dev); 508 } 509 break; 510 default: 511 D(qemu_log("%s: ch=%d addr=" TARGET_FMT_plx " v=%x\n", 512 __func__, sid, addr * 4, (unsigned)value)); 513 s->regs[addr] = value; 514 break; 515 } 516 if (sid == 1 && d->notify) { 517 StreamCanPushNotifyFn notifytmp = d->notify; 518 d->notify = NULL; 519 notifytmp(d->notify_opaque); 520 } 521 stream_update_irq(s); 522 } 523 524 static const MemoryRegionOps axidma_ops = { 525 .read = axidma_read, 526 .write = axidma_write, 527 .endianness = DEVICE_NATIVE_ENDIAN, 528 }; 529 530 static void xilinx_axidma_realize(DeviceState *dev, Error **errp) 531 { 532 XilinxAXIDMA *s = XILINX_AXI_DMA(dev); 533 XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev); 534 XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM( 535 &s->rx_control_dev); 536 Error *local_errp = NULL; 537 538 object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA, 539 (Object **)&ds->dma, &local_errp); 540 object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA, 541 (Object **)&cs->dma, &local_errp); 542 if (local_errp) { 543 goto xilinx_axidma_realize_fail; 544 } 545 object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_errp); 546 object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_errp); 547 if (local_errp) { 548 goto xilinx_axidma_realize_fail; 549 } 550 551 int i; 552 553 for (i = 0; i < 2; i++) { 554 s->streams[i].nr = i; 555 s->streams[i].bh = qemu_bh_new(timer_hit, &s->streams[i]); 556 s->streams[i].ptimer = ptimer_init(s->streams[i].bh); 557 ptimer_set_freq(s->streams[i].ptimer, s->freqhz); 558 } 559 return; 560 561 xilinx_axidma_realize_fail: 562 if (!*errp) { 563 *errp = local_errp; 564 } 565 } 566 567 static void xilinx_axidma_init(Object *obj) 568 { 569 XilinxAXIDMA *s = XILINX_AXI_DMA(obj); 570 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 571 Error *errp = NULL; 572 573 object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE, 574 (Object **) &s->tx_data_dev, &errp); 575 assert_no_error(errp); 576 object_property_add_link(obj, "axistream-control-connected", 577 TYPE_STREAM_SLAVE, 578 (Object **) &s->tx_control_dev, &errp); 579 assert_no_error(errp); 580 581 object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_DMA_DATA_STREAM); 582 object_initialize(&s->rx_control_dev, TYPE_XILINX_AXI_DMA_CONTROL_STREAM); 583 object_property_add_child(OBJECT(s), "axistream-connected-target", 584 (Object *)&s->rx_data_dev, &errp); 585 assert_no_error(errp); 586 object_property_add_child(OBJECT(s), "axistream-control-connected-target", 587 (Object *)&s->rx_control_dev, &errp); 588 assert_no_error(errp); 589 590 sysbus_init_irq(sbd, &s->streams[0].irq); 591 sysbus_init_irq(sbd, &s->streams[1].irq); 592 593 memory_region_init_io(&s->iomem, obj, &axidma_ops, s, 594 "xlnx.axi-dma", R_MAX * 4 * 2); 595 sysbus_init_mmio(sbd, &s->iomem); 596 } 597 598 static Property axidma_properties[] = { 599 DEFINE_PROP_UINT32("freqhz", XilinxAXIDMA, freqhz, 50000000), 600 DEFINE_PROP_END_OF_LIST(), 601 }; 602 603 static void axidma_class_init(ObjectClass *klass, void *data) 604 { 605 DeviceClass *dc = DEVICE_CLASS(klass); 606 607 dc->realize = xilinx_axidma_realize, 608 dc->reset = xilinx_axidma_reset; 609 dc->props = axidma_properties; 610 } 611 612 static StreamSlaveClass xilinx_axidma_data_stream_class = { 613 .push = xilinx_axidma_data_stream_push, 614 .can_push = xilinx_axidma_data_stream_can_push, 615 }; 616 617 static StreamSlaveClass xilinx_axidma_control_stream_class = { 618 .push = xilinx_axidma_control_stream_push, 619 }; 620 621 static void xilinx_axidma_stream_class_init(ObjectClass *klass, void *data) 622 { 623 StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass); 624 625 ssc->push = ((StreamSlaveClass *)data)->push; 626 ssc->can_push = ((StreamSlaveClass *)data)->can_push; 627 } 628 629 static const TypeInfo axidma_info = { 630 .name = TYPE_XILINX_AXI_DMA, 631 .parent = TYPE_SYS_BUS_DEVICE, 632 .instance_size = sizeof(XilinxAXIDMA), 633 .class_init = axidma_class_init, 634 .instance_init = xilinx_axidma_init, 635 }; 636 637 static const TypeInfo xilinx_axidma_data_stream_info = { 638 .name = TYPE_XILINX_AXI_DMA_DATA_STREAM, 639 .parent = TYPE_OBJECT, 640 .instance_size = sizeof(struct XilinxAXIDMAStreamSlave), 641 .class_init = xilinx_axidma_stream_class_init, 642 .class_data = &xilinx_axidma_data_stream_class, 643 .interfaces = (InterfaceInfo[]) { 644 { TYPE_STREAM_SLAVE }, 645 { } 646 } 647 }; 648 649 static const TypeInfo xilinx_axidma_control_stream_info = { 650 .name = TYPE_XILINX_AXI_DMA_CONTROL_STREAM, 651 .parent = TYPE_OBJECT, 652 .instance_size = sizeof(struct XilinxAXIDMAStreamSlave), 653 .class_init = xilinx_axidma_stream_class_init, 654 .class_data = &xilinx_axidma_control_stream_class, 655 .interfaces = (InterfaceInfo[]) { 656 { TYPE_STREAM_SLAVE }, 657 { } 658 } 659 }; 660 661 static void xilinx_axidma_register_types(void) 662 { 663 type_register_static(&axidma_info); 664 type_register_static(&xilinx_axidma_data_stream_info); 665 type_register_static(&xilinx_axidma_control_stream_info); 666 } 667 668 type_init(xilinx_axidma_register_types) 669