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