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