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 unsigned char txbuf[16 * 1024]; 115 }; 116 117 struct XilinxAXIDMAStreamSlave { 118 Object parent; 119 120 struct XilinxAXIDMA *dma; 121 }; 122 123 struct XilinxAXIDMA { 124 SysBusDevice busdev; 125 MemoryRegion iomem; 126 uint32_t freqhz; 127 StreamSlave *tx_data_dev; 128 StreamSlave *tx_control_dev; 129 XilinxAXIDMAStreamSlave rx_data_dev; 130 XilinxAXIDMAStreamSlave rx_control_dev; 131 132 struct Stream streams[2]; 133 134 StreamCanPushNotifyFn notify; 135 void *notify_opaque; 136 }; 137 138 /* 139 * Helper calls to extract info from descriptors and other trivial 140 * state from regs. 141 */ 142 static inline int stream_desc_sof(struct SDesc *d) 143 { 144 return d->control & SDESC_CTRL_SOF; 145 } 146 147 static inline int stream_desc_eof(struct SDesc *d) 148 { 149 return d->control & SDESC_CTRL_EOF; 150 } 151 152 static inline int stream_resetting(struct Stream *s) 153 { 154 return !!(s->regs[R_DMACR] & DMACR_RESET); 155 } 156 157 static inline int stream_running(struct Stream *s) 158 { 159 return s->regs[R_DMACR] & DMACR_RUNSTOP; 160 } 161 162 static inline int stream_idle(struct Stream *s) 163 { 164 return !!(s->regs[R_DMASR] & DMASR_IDLE); 165 } 166 167 static void stream_reset(struct Stream *s) 168 { 169 s->regs[R_DMASR] = DMASR_HALTED; /* starts up halted. */ 170 s->regs[R_DMACR] = 1 << 16; /* Starts with one in compl threshold. */ 171 } 172 173 /* Map an offset addr into a channel index. */ 174 static inline int streamid_from_addr(hwaddr addr) 175 { 176 int sid; 177 178 sid = addr / (0x30); 179 sid &= 1; 180 return sid; 181 } 182 183 static void stream_desc_load(struct Stream *s, hwaddr addr) 184 { 185 struct SDesc *d = &s->desc; 186 187 cpu_physical_memory_read(addr, d, sizeof *d); 188 189 /* Convert from LE into host endianness. */ 190 d->buffer_address = le64_to_cpu(d->buffer_address); 191 d->nxtdesc = le64_to_cpu(d->nxtdesc); 192 d->control = le32_to_cpu(d->control); 193 d->status = le32_to_cpu(d->status); 194 } 195 196 static void stream_desc_store(struct Stream *s, hwaddr addr) 197 { 198 struct SDesc *d = &s->desc; 199 200 /* Convert from host endianness into LE. */ 201 d->buffer_address = cpu_to_le64(d->buffer_address); 202 d->nxtdesc = cpu_to_le64(d->nxtdesc); 203 d->control = cpu_to_le32(d->control); 204 d->status = cpu_to_le32(d->status); 205 cpu_physical_memory_write(addr, d, sizeof *d); 206 } 207 208 static void stream_update_irq(struct Stream *s) 209 { 210 unsigned int pending, mask, irq; 211 212 pending = s->regs[R_DMASR] & DMASR_IRQ_MASK; 213 mask = s->regs[R_DMACR] & DMASR_IRQ_MASK; 214 215 irq = pending & mask; 216 217 qemu_set_irq(s->irq, !!irq); 218 } 219 220 static void stream_reload_complete_cnt(struct Stream *s) 221 { 222 unsigned int comp_th; 223 comp_th = (s->regs[R_DMACR] >> 16) & 0xff; 224 s->complete_cnt = comp_th; 225 } 226 227 static void timer_hit(void *opaque) 228 { 229 struct Stream *s = opaque; 230 231 stream_reload_complete_cnt(s); 232 s->regs[R_DMASR] |= DMASR_DLY_IRQ; 233 stream_update_irq(s); 234 } 235 236 static void stream_complete(struct Stream *s) 237 { 238 unsigned int comp_delay; 239 240 /* Start the delayed timer. */ 241 comp_delay = s->regs[R_DMACR] >> 24; 242 if (comp_delay) { 243 ptimer_stop(s->ptimer); 244 ptimer_set_count(s->ptimer, comp_delay); 245 ptimer_run(s->ptimer, 1); 246 } 247 248 s->complete_cnt--; 249 if (s->complete_cnt == 0) { 250 /* Raise the IOC irq. */ 251 s->regs[R_DMASR] |= DMASR_IOC_IRQ; 252 stream_reload_complete_cnt(s); 253 } 254 } 255 256 static void stream_process_mem2s(struct Stream *s, StreamSlave *tx_data_dev, 257 StreamSlave *tx_control_dev) 258 { 259 uint32_t prev_d; 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 s->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 s->txbuf + s->pos, txlen); 287 s->pos += txlen; 288 289 if (stream_desc_eof(&s->desc)) { 290 stream_push(tx_data_dev, s->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 error_propagate(errp, local_err); 558 } 559 560 static void xilinx_axidma_init(Object *obj) 561 { 562 XilinxAXIDMA *s = XILINX_AXI_DMA(obj); 563 SysBusDevice *sbd = SYS_BUS_DEVICE(obj); 564 565 object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev), 566 TYPE_XILINX_AXI_DMA_DATA_STREAM); 567 object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev), 568 TYPE_XILINX_AXI_DMA_CONTROL_STREAM); 569 object_property_add_child(OBJECT(s), "axistream-connected-target", 570 (Object *)&s->rx_data_dev, &error_abort); 571 object_property_add_child(OBJECT(s), "axistream-control-connected-target", 572 (Object *)&s->rx_control_dev, &error_abort); 573 574 sysbus_init_irq(sbd, &s->streams[0].irq); 575 sysbus_init_irq(sbd, &s->streams[1].irq); 576 577 memory_region_init_io(&s->iomem, obj, &axidma_ops, s, 578 "xlnx.axi-dma", R_MAX * 4 * 2); 579 sysbus_init_mmio(sbd, &s->iomem); 580 } 581 582 static Property axidma_properties[] = { 583 DEFINE_PROP_UINT32("freqhz", XilinxAXIDMA, freqhz, 50000000), 584 DEFINE_PROP_LINK("axistream-connected", XilinxAXIDMA, 585 tx_data_dev, TYPE_STREAM_SLAVE, StreamSlave *), 586 DEFINE_PROP_LINK("axistream-control-connected", XilinxAXIDMA, 587 tx_control_dev, TYPE_STREAM_SLAVE, StreamSlave *), 588 DEFINE_PROP_END_OF_LIST(), 589 }; 590 591 static void axidma_class_init(ObjectClass *klass, void *data) 592 { 593 DeviceClass *dc = DEVICE_CLASS(klass); 594 595 dc->realize = xilinx_axidma_realize, 596 dc->reset = xilinx_axidma_reset; 597 dc->props = axidma_properties; 598 } 599 600 static StreamSlaveClass xilinx_axidma_data_stream_class = { 601 .push = xilinx_axidma_data_stream_push, 602 .can_push = xilinx_axidma_data_stream_can_push, 603 }; 604 605 static StreamSlaveClass xilinx_axidma_control_stream_class = { 606 .push = xilinx_axidma_control_stream_push, 607 }; 608 609 static void xilinx_axidma_stream_class_init(ObjectClass *klass, void *data) 610 { 611 StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass); 612 613 ssc->push = ((StreamSlaveClass *)data)->push; 614 ssc->can_push = ((StreamSlaveClass *)data)->can_push; 615 } 616 617 static const TypeInfo axidma_info = { 618 .name = TYPE_XILINX_AXI_DMA, 619 .parent = TYPE_SYS_BUS_DEVICE, 620 .instance_size = sizeof(XilinxAXIDMA), 621 .class_init = axidma_class_init, 622 .instance_init = xilinx_axidma_init, 623 }; 624 625 static const TypeInfo xilinx_axidma_data_stream_info = { 626 .name = TYPE_XILINX_AXI_DMA_DATA_STREAM, 627 .parent = TYPE_OBJECT, 628 .instance_size = sizeof(struct XilinxAXIDMAStreamSlave), 629 .class_init = xilinx_axidma_stream_class_init, 630 .class_data = &xilinx_axidma_data_stream_class, 631 .interfaces = (InterfaceInfo[]) { 632 { TYPE_STREAM_SLAVE }, 633 { } 634 } 635 }; 636 637 static const TypeInfo xilinx_axidma_control_stream_info = { 638 .name = TYPE_XILINX_AXI_DMA_CONTROL_STREAM, 639 .parent = TYPE_OBJECT, 640 .instance_size = sizeof(struct XilinxAXIDMAStreamSlave), 641 .class_init = xilinx_axidma_stream_class_init, 642 .class_data = &xilinx_axidma_control_stream_class, 643 .interfaces = (InterfaceInfo[]) { 644 { TYPE_STREAM_SLAVE }, 645 { } 646 } 647 }; 648 649 static void xilinx_axidma_register_types(void) 650 { 651 type_register_static(&axidma_info); 652 type_register_static(&xilinx_axidma_data_stream_info); 653 type_register_static(&xilinx_axidma_control_stream_info); 654 } 655 656 type_init(xilinx_axidma_register_types) 657