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