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