Revision b42ec42d hw/mac_dbdma.c

b/hw/mac_dbdma.c
158 158
    int channel;
159 159
    uint32_t regs[DBDMA_REGS];
160 160
    qemu_irq irq;
161
    DBDMA_transfer io;
162
    DBDMA_transfer_handler transfer_handler;
161
    DBDMA_io io;
162
    DBDMA_rw rw;
163 163
    dbdma_cmd current;
164
    int processing;
164 165
} DBDMA_channel;
165 166

  
166 167
#ifdef DEBUG_DBDMA
......
218 219

  
219 220
    DBDMA_DPRINTF("conditional_interrupt\n");
220 221

  
221
    intr = be16_to_cpu(current->command) & INTR_MASK;
222
    intr = le16_to_cpu(current->command) & INTR_MASK;
222 223

  
223 224
    switch(intr) {
224 225
    case INTR_NEVER:  /* don't interrupt */
......
257 258

  
258 259
    DBDMA_DPRINTF("conditional_wait\n");
259 260

  
260
    wait = be16_to_cpu(current->command) & WAIT_MASK;
261
    wait = le16_to_cpu(current->command) & WAIT_MASK;
261 262

  
262 263
    switch(wait) {
263 264
    case WAIT_NEVER:  /* don't wait */
......
318 319

  
319 320
    /* check if we must branch */
320 321

  
321
    br = be16_to_cpu(current->command) & BR_MASK;
322
    br = le16_to_cpu(current->command) & BR_MASK;
322 323

  
323 324
    switch(br) {
324 325
    case BR_NEVER:  /* don't branch */
......
352 353
    }
353 354
}
354 355

  
355
static int dbdma_read_memory(DBDMA_transfer *io)
356
{
357
    DBDMA_channel *ch = io->channel;
358
    dbdma_cmd *current = &ch->current;
359

  
360
    DBDMA_DPRINTF("DBDMA_read_memory\n");
361

  
362
    cpu_physical_memory_read(le32_to_cpu(current->phy_addr) + io->buf_pos,
363
                             io->buf, io->buf_len);
364

  
365
    return io->buf_len;
366
}
356
static QEMUBH *dbdma_bh;
357
static void channel_run(DBDMA_channel *ch);
367 358

  
368
static int dbdma_write_memory(DBDMA_transfer *io)
359
static void dbdma_end(DBDMA_io *io)
369 360
{
370 361
    DBDMA_channel *ch = io->channel;
371 362
    dbdma_cmd *current = &ch->current;
372 363

  
373
    DBDMA_DPRINTF("DBDMA_write_memory\n");
364
    if (conditional_wait(ch))
365
        goto wait;
374 366

  
375
    cpu_physical_memory_write(le32_to_cpu(current->phy_addr) + io->buf_pos,
376
                              io->buf, io->buf_len);
367
    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
368
    current->res_count = cpu_to_le16(be32_to_cpu(io->len));
369
    dbdma_cmdptr_save(ch);
370
    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
371

  
372
    conditional_interrupt(ch);
373
    conditional_branch(ch);
377 374

  
378
    return io->buf_len;
375
wait:
376
    ch->processing = 0;
377
    if ((ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN)) &&
378
        (ch->regs[DBDMA_STATUS] & cpu_to_be32(ACTIVE)))
379
        channel_run(ch);
379 380
}
380 381

  
381
static int start_output(DBDMA_channel *ch, int key, uint32_t addr,
382
static void start_output(DBDMA_channel *ch, int key, uint32_t addr,
382 383
                        uint16_t req_count, int is_last)
383 384
{
384
    dbdma_cmd *current = &ch->current;
385
    uint32_t n;
386

  
387 385
    DBDMA_DPRINTF("start_output\n");
388 386

  
389 387
    /* KEY_REGS, KEY_DEVICE and KEY_STREAM
......
393 391
    DBDMA_DPRINTF("addr 0x%x key 0x%x\n", addr, key);
394 392
    if (!addr || key > KEY_STREAM3) {
395 393
        kill_channel(ch);
396
        return 0;
394
        return;
397 395
    }
398 396

  
399
    ch->io.buf = NULL;
400
    ch->io.buf_pos = 0;
401
    ch->io.buf_len = 0;
397
    ch->io.addr = addr;
402 398
    ch->io.len = req_count;
403 399
    ch->io.is_last = is_last;
404
    n = ch->transfer_handler(&ch->io, dbdma_read_memory);
405

  
406
    if (conditional_wait(ch))
407
        return 1;
408

  
409
    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
410
    current->res_count = cpu_to_le16(0);
411
    dbdma_cmdptr_save(ch);
412

  
413
    conditional_interrupt(ch);
414
    conditional_branch(ch);
415

  
416
    return 1;
400
    ch->io.dma_end = dbdma_end;
401
    ch->io.is_dma_out = 1;
402
    ch->processing = 1;
403
    ch->rw(&ch->io);
417 404
}
418 405

  
419
static int start_input(DBDMA_channel *ch, int key, uint32_t addr,
406
static void start_input(DBDMA_channel *ch, int key, uint32_t addr,
420 407
                       uint16_t req_count, int is_last)
421 408
{
422
    dbdma_cmd *current = &ch->current;
423
    uint32_t n;
424

  
425 409
    DBDMA_DPRINTF("start_input\n");
426 410

  
427 411
    /* KEY_REGS, KEY_DEVICE and KEY_STREAM
......
430 414

  
431 415
    if (!addr || key > KEY_STREAM3) {
432 416
        kill_channel(ch);
433
        return 0;
417
        return;
434 418
    }
435 419

  
436
    ch->io.buf = NULL;
437
    ch->io.buf_pos = 0;
438
    ch->io.buf_len = 0;
420
    ch->io.addr = addr;
439 421
    ch->io.len = req_count;
440 422
    ch->io.is_last = is_last;
441
    n = ch->transfer_handler(&ch->io, dbdma_write_memory);
442

  
443
    if (conditional_wait(ch))
444
        return 1;
445

  
446
    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
447
    current->res_count = cpu_to_le16(0);
448
    dbdma_cmdptr_save(ch);
449

  
450
    conditional_interrupt(ch);
451
    conditional_branch(ch);
452

  
453
    return 1;
423
    ch->io.dma_end = dbdma_end;
424
    ch->io.is_dma_out = 0;
425
    ch->processing = 1;
426
    ch->rw(&ch->io);
454 427
}
455 428

  
456
static int load_word(DBDMA_channel *ch, int key, uint32_t addr,
429
static void load_word(DBDMA_channel *ch, int key, uint32_t addr,
457 430
                     uint16_t len)
458 431
{
459 432
    dbdma_cmd *current = &ch->current;
......
466 439
    if (key != KEY_SYSTEM) {
467 440
        printf("DBDMA: LOAD_WORD, unimplemented key %x\n", key);
468 441
        kill_channel(ch);
469
        return 0;
442
        return;
470 443
    }
471 444

  
472 445
    cpu_physical_memory_read(addr, (uint8_t*)&val, len);
......
479 452
    current->cmd_dep = val;
480 453

  
481 454
    if (conditional_wait(ch))
482
        return 1;
455
        goto wait;
483 456

  
484 457
    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
485 458
    dbdma_cmdptr_save(ch);
459
    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
486 460

  
487 461
    conditional_interrupt(ch);
488 462
    next(ch);
489 463

  
490
    return 1;
464
wait:
465
    qemu_bh_schedule(dbdma_bh);
491 466
}
492 467

  
493
static int store_word(DBDMA_channel *ch, int key, uint32_t addr,
468
static void store_word(DBDMA_channel *ch, int key, uint32_t addr,
494 469
                      uint16_t len)
495 470
{
496 471
    dbdma_cmd *current = &ch->current;
......
503 478
    if (key != KEY_SYSTEM) {
504 479
        printf("DBDMA: STORE_WORD, unimplemented key %x\n", key);
505 480
        kill_channel(ch);
506
        return 0;
481
        return;
507 482
    }
508 483

  
509 484
    val = current->cmd_dep;
......
515 490
    cpu_physical_memory_write(addr, (uint8_t*)&val, len);
516 491

  
517 492
    if (conditional_wait(ch))
518
        return 1;
493
        goto wait;
519 494

  
520 495
    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
521 496
    dbdma_cmdptr_save(ch);
497
    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
522 498

  
523 499
    conditional_interrupt(ch);
524 500
    next(ch);
525 501

  
526
    return 1;
502
wait:
503
    qemu_bh_schedule(dbdma_bh);
527 504
}
528 505

  
529
static int nop(DBDMA_channel *ch)
506
static void nop(DBDMA_channel *ch)
530 507
{
531 508
    dbdma_cmd *current = &ch->current;
532 509

  
533 510
    if (conditional_wait(ch))
534
        return 1;
511
        goto wait;
535 512

  
536 513
    current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS]));
537 514
    dbdma_cmdptr_save(ch);
......
539 516
    conditional_interrupt(ch);
540 517
    conditional_branch(ch);
541 518

  
542
    return 1;
519
wait:
520
    qemu_bh_schedule(dbdma_bh);
543 521
}
544 522

  
545
static int stop(DBDMA_channel *ch)
523
static void stop(DBDMA_channel *ch)
546 524
{
547
    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD));
525
    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD|FLUSH));
548 526

  
549 527
    /* the stop command does not increment command pointer */
550

  
551
    return 0;
552 528
}
553 529

  
554
static int channel_run(DBDMA_channel *ch)
530
static void channel_run(DBDMA_channel *ch)
555 531
{
556 532
    dbdma_cmd *current = &ch->current;
557 533
    uint16_t cmd, key;
......
569 545

  
570 546
    switch (cmd) {
571 547
    case DBDMA_NOP:
572
        return nop(ch);
548
        nop(ch);
549
	return;
573 550

  
574 551
    case DBDMA_STOP:
575
        return stop(ch);
552
        stop(ch);
553
	return;
576 554
    }
577 555

  
578 556
    key = le16_to_cpu(current->command) & 0x0700;
......
582 560
    if (key == KEY_STREAM4) {
583 561
        printf("command %x, invalid key 4\n", cmd);
584 562
        kill_channel(ch);
585
        return 0;
563
        return;
586 564
    }
587 565

  
588 566
    switch (cmd) {
589 567
    case OUTPUT_MORE:
590
        return start_output(ch, key, phy_addr, req_count, 0);
568
        start_output(ch, key, phy_addr, req_count, 0);
569
	return;
591 570

  
592 571
    case OUTPUT_LAST:
593
        return start_output(ch, key, phy_addr, req_count, 1);
572
        start_output(ch, key, phy_addr, req_count, 1);
573
	return;
594 574

  
595 575
    case INPUT_MORE:
596
        return start_input(ch, key, phy_addr, req_count, 0);
576
        start_input(ch, key, phy_addr, req_count, 0);
577
	return;
597 578

  
598 579
    case INPUT_LAST:
599
        return start_input(ch, key, phy_addr, req_count, 1);
580
        start_input(ch, key, phy_addr, req_count, 1);
581
	return;
600 582
    }
601 583

  
602 584
    if (key < KEY_REGS) {
......
620 602

  
621 603
    switch (cmd) {
622 604
    case LOAD_WORD:
623
        return load_word(ch, key, phy_addr, req_count);
605
        load_word(ch, key, phy_addr, req_count);
606
	return;
624 607

  
625 608
    case STORE_WORD:
626
        return store_word(ch, key, phy_addr, req_count);
609
        store_word(ch, key, phy_addr, req_count);
610
	return;
627 611
    }
628

  
629
    return 0;
630 612
}
631 613

  
632
static QEMUBH *dbdma_bh;
633

  
634 614
static void DBDMA_run (DBDMA_channel *ch)
635 615
{
636 616
    int channel;
637
    int rearm = 0;
638 617

  
639 618
    for (channel = 0; channel < DBDMA_CHANNELS; channel++, ch++) {
640 619
            uint32_t status = be32_to_cpu(ch->regs[DBDMA_STATUS]);
641
            if ((status & RUN) && (status & ACTIVE)) {
642
		if (status & FLUSH)
643
                    while (channel_run(ch));
644
                else if (channel_run(ch))
645
                    rearm = 1;
646
            }
647
            ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH);
620
            if (!ch->processing && (status & RUN) && (status & ACTIVE))
621
                channel_run(ch);
648 622
    }
649

  
650
    if (rearm)
651
        qemu_bh_schedule_idle(dbdma_bh);
652 623
}
653 624

  
654 625
static void DBDMA_run_bh(void *opaque)
......
661 632
}
662 633

  
663 634
void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
664
                            DBDMA_transfer_handler transfer_handler,
635
                            DBDMA_rw rw,
665 636
                            void *opaque)
666 637
{
667 638
    DBDMA_channel *ch = ( DBDMA_channel *)dbdma + nchan;
......
670 641

  
671 642
    ch->irq = irq;
672 643
    ch->channel = nchan;
673
    ch->transfer_handler = transfer_handler;
644
    ch->rw = rw;
674 645
    ch->io.opaque = opaque;
675 646
    ch->io.channel = ch;
676 647
}
......
714 685

  
715 686
    ch->regs[DBDMA_STATUS] = cpu_to_be32(status);
716 687

  
717
    if (status & ACTIVE) {
718
        qemu_bh_schedule_idle(dbdma_bh);
719
        if (status & FLUSH)
720
            DBDMA_schedule();
721
    }
688
    if (status & ACTIVE)
689
        qemu_bh_schedule(dbdma_bh);
722 690
}
723 691

  
724 692
static void dbdma_writel (void *opaque,

Also available in: Unified diff