Revision 930c8682

b/hw/musicpal.c
72 72
static uint32_t gpio_out_state;
73 73
static ram_addr_t sram_off;
74 74

  
75
/* Address conversion helpers */
76
static void *target2host_addr(uint32_t addr)
77
{
78
    if (addr < MP_SRAM_BASE) {
79
        if (addr >= MP_RAM_DEFAULT_SIZE)
80
            return NULL;
81
        return (void *)(phys_ram_base + addr);
82
    } else {
83
        if (addr >= MP_SRAM_BASE + MP_SRAM_SIZE)
84
            return NULL;
85
        return (void *)(phys_ram_base + sram_off + addr - MP_SRAM_BASE);
86
    }
87
}
88

  
89
static uint32_t host2target_addr(void *addr)
90
{
91
    if (addr < ((void *)phys_ram_base) + sram_off)
92
        return (unsigned long)addr - (unsigned long)phys_ram_base;
93
    else
94
        return (unsigned long)addr - (unsigned long)phys_ram_base -
95
            sram_off + MP_SRAM_BASE;
96
}
97

  
98

  
99 75
typedef enum i2c_state {
100 76
    STOPPED = 0,
101 77
    INITIALIZING,
......
253 229
    uint32_t status;
254 230
    uint32_t irq_enable;
255 231
    unsigned long phys_buf;
256
    int8_t *target_buffer;
232
    uint32_t target_buffer;
257 233
    unsigned int threshold;
258 234
    unsigned int play_pos;
259 235
    unsigned int last_free;
......
265 241
{
266 242
    musicpal_audio_state *s = opaque;
267 243
    int16_t *codec_buffer;
244
    int8_t buf[4096];
268 245
    int8_t *mem_buffer;
269 246
    int pos, block_size;
270 247

  
......
281 258
    if (free_out - s->last_free < block_size)
282 259
        return;
283 260

  
284
    mem_buffer = s->target_buffer + s->play_pos;
261
    if (block_size > 4096)
262
        return;
263

  
264
    cpu_physical_memory_read(s->target_buffer + s->play_pos, (void *)buf,
265
                             block_size);
266
    mem_buffer = buf;
285 267
    if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) {
286 268
        if (s->playback_mode & MP_AUDIO_MONO) {
287 269
            codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1);
......
399 381

  
400 382
    case MP_AUDIO_TX_START_LO:
401 383
        s->phys_buf = (s->phys_buf & 0xFFFF0000) | (value & 0xFFFF);
402
        s->target_buffer = target2host_addr(s->phys_buf);
384
        s->target_buffer = s->phys_buf;
403 385
        s->play_pos = 0;
404 386
        s->last_free = 0;
405 387
        break;
......
410 392

  
411 393
    case MP_AUDIO_TX_START_HI:
412 394
        s->phys_buf = (s->phys_buf & 0xFFFF) | (value << 16);
413
        s->target_buffer = target2host_addr(s->phys_buf);
395
        s->target_buffer = s->phys_buf;
414 396
        s->play_pos = 0;
415 397
        s->last_free = 0;
416 398
        break;
......
555 537
    uint32_t icr;
556 538
    uint32_t imr;
557 539
    int vlan_header;
558
    mv88w8618_tx_desc *tx_queue[2];
559
    mv88w8618_rx_desc *rx_queue[4];
560
    mv88w8618_rx_desc *frx_queue[4];
561
    mv88w8618_rx_desc *cur_rx[4];
540
    uint32_t tx_queue[2];
541
    uint32_t rx_queue[4];
542
    uint32_t frx_queue[4];
543
    uint32_t cur_rx[4];
562 544
    VLANClientState *vc;
563 545
} mv88w8618_eth_state;
564 546

  
547
static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
548
{
549
    cpu_to_le32s(&desc->cmdstat);
550
    cpu_to_le16s(&desc->bytes);
551
    cpu_to_le16s(&desc->buffer_size);
552
    cpu_to_le32s(&desc->buffer);
553
    cpu_to_le32s(&desc->next);
554
    cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc));
555
}
556

  
557
static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
558
{
559
    cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc));
560
    le32_to_cpus(&desc->cmdstat);
561
    le16_to_cpus(&desc->bytes);
562
    le16_to_cpus(&desc->buffer_size);
563
    le32_to_cpus(&desc->buffer);
564
    le32_to_cpus(&desc->next);
565
}
566

  
565 567
static int eth_can_receive(void *opaque)
566 568
{
567 569
    return 1;
......
570 572
static void eth_receive(void *opaque, const uint8_t *buf, int size)
571 573
{
572 574
    mv88w8618_eth_state *s = opaque;
573
    mv88w8618_rx_desc *desc;
575
    uint32_t desc_addr;
576
    mv88w8618_rx_desc desc;
574 577
    int i;
575 578

  
576 579
    for (i = 0; i < 4; i++) {
577
        desc = s->cur_rx[i];
578
        if (!desc)
580
        desc_addr = s->cur_rx[i];
581
        if (!desc_addr)
579 582
            continue;
580 583
        do {
581
            if (le32_to_cpu(desc->cmdstat) & MP_ETH_RX_OWN &&
582
                le16_to_cpu(desc->buffer_size) >= size) {
583
                memcpy(target2host_addr(le32_to_cpu(desc->buffer) +
584
                                        s->vlan_header),
585
                       buf, size);
586
                desc->bytes = cpu_to_le16(size + s->vlan_header);
587
                desc->cmdstat &= cpu_to_le32(~MP_ETH_RX_OWN);
588
                s->cur_rx[i] = target2host_addr(le32_to_cpu(desc->next));
584
            eth_rx_desc_get(desc_addr, &desc);
585
            if ((desc.cmdstat & MP_ETH_RX_OWN) && desc.buffer_size >= size) {
586
                cpu_physical_memory_write(desc.buffer + s->vlan_header,
587
                                          buf, size);
588
                desc.bytes = size + s->vlan_header;
589
                desc.cmdstat &= ~MP_ETH_RX_OWN;
590
                s->cur_rx[i] = desc.next;
589 591

  
590 592
                s->icr |= MP_ETH_IRQ_RX;
591 593
                if (s->icr & s->imr)
592 594
                    qemu_irq_raise(s->irq);
595
                eth_rx_desc_put(desc_addr, &desc);
593 596
                return;
594 597
            }
595
            desc = target2host_addr(le32_to_cpu(desc->next));
596
        } while (desc != s->rx_queue[i]);
598
            desc_addr = desc.next;
599
        } while (desc_addr != s->rx_queue[i]);
597 600
    }
598 601
}
599 602

  
603
static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
604
{
605
    cpu_to_le32s(&desc->cmdstat);
606
    cpu_to_le16s(&desc->res);
607
    cpu_to_le16s(&desc->bytes);
608
    cpu_to_le32s(&desc->buffer);
609
    cpu_to_le32s(&desc->next);
610
    cpu_physical_memory_write(addr, (void *)desc, sizeof(*desc));
611
}
612

  
613
static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc)
614
{
615
    cpu_physical_memory_read(addr, (void *)desc, sizeof(*desc));
616
    le32_to_cpus(&desc->cmdstat);
617
    le16_to_cpus(&desc->res);
618
    le16_to_cpus(&desc->bytes);
619
    le32_to_cpus(&desc->buffer);
620
    le32_to_cpus(&desc->next);
621
}
622

  
600 623
static void eth_send(mv88w8618_eth_state *s, int queue_index)
601 624
{
602
    mv88w8618_tx_desc *desc = s->tx_queue[queue_index];
625
    uint32_t desc_addr = s->tx_queue[queue_index];
626
    mv88w8618_tx_desc desc;
627
    uint8_t buf[2048];
628
    int len;
629

  
603 630

  
604 631
    do {
605
        if (le32_to_cpu(desc->cmdstat) & MP_ETH_TX_OWN) {
606
            qemu_send_packet(s->vc,
607
                             target2host_addr(le32_to_cpu(desc->buffer)),
608
                             le16_to_cpu(desc->bytes));
609
            desc->cmdstat &= cpu_to_le32(~MP_ETH_TX_OWN);
632
        eth_tx_desc_get(desc_addr, &desc);
633
        if (desc.cmdstat & MP_ETH_TX_OWN) {
634
            len = desc.bytes;
635
            if (len < 2048) {
636
                cpu_physical_memory_read(desc.buffer, buf, len);
637
                qemu_send_packet(s->vc, buf, len);
638
            }
639
            desc.cmdstat &= ~MP_ETH_TX_OWN;
610 640
            s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index);
641
            eth_tx_desc_put(desc_addr, &desc);
611 642
        }
612
        desc = target2host_addr(le32_to_cpu(desc->next));
613
    } while (desc != s->tx_queue[queue_index]);
643
        desc_addr = desc.next;
644
    } while (desc_addr != s->tx_queue[queue_index]);
614 645
}
615 646

  
616 647
static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset)
......
641 672
        return s->imr;
642 673

  
643 674
    case MP_ETH_FRDP0 ... MP_ETH_FRDP3:
644
        return host2target_addr(s->frx_queue[(offset - MP_ETH_FRDP0)/4]);
675
        return s->frx_queue[(offset - MP_ETH_FRDP0)/4];
645 676

  
646 677
    case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
647
        return host2target_addr(s->rx_queue[(offset - MP_ETH_CRDP0)/4]);
678
        return s->rx_queue[(offset - MP_ETH_CRDP0)/4];
648 679

  
649 680
    case MP_ETH_CTDP0 ... MP_ETH_CTDP3:
650
        return host2target_addr(s->tx_queue[(offset - MP_ETH_CTDP0)/4]);
681
        return s->tx_queue[(offset - MP_ETH_CTDP0)/4];
651 682

  
652 683
    default:
653 684
        return 0;
......
688 719
        break;
689 720

  
690 721
    case MP_ETH_FRDP0 ... MP_ETH_FRDP3:
691
        s->frx_queue[(offset - MP_ETH_FRDP0)/4] = target2host_addr(value);
722
        s->frx_queue[(offset - MP_ETH_FRDP0)/4] = value;
692 723
        break;
693 724

  
694 725
    case MP_ETH_CRDP0 ... MP_ETH_CRDP3:
695 726
        s->rx_queue[(offset - MP_ETH_CRDP0)/4] =
696
            s->cur_rx[(offset - MP_ETH_CRDP0)/4] = target2host_addr(value);
727
            s->cur_rx[(offset - MP_ETH_CRDP0)/4] = value;
697 728
        break;
698 729

  
699 730
    case MP_ETH_CTDP0 ... MP_ETH_CTDP3:
700
        s->tx_queue[(offset - MP_ETH_CTDP0)/4] = target2host_addr(value);
731
        s->tx_queue[(offset - MP_ETH_CTDP0)/4] = value;
701 732
        break;
702 733
    }
703 734
}

Also available in: Unified diff