Commit 930c86820e8e0b6dfcf211bda5e835463d72ff42
1 parent
44654490
Musicpal ram access cleanup.
Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7061 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
90 additions
and
59 deletions
hw/musicpal.c
| ... | ... | @@ -72,30 +72,6 @@ static uint32_t gpio_isr; |
| 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,7 +229,7 @@ typedef struct musicpal_audio_state { |
| 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,6 +241,7 @@ static void audio_callback(void *opaque, int free_out, int free_in) |
| 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,7 +258,12 @@ static void audio_callback(void *opaque, int free_out, int free_in) |
| 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,7 +381,7 @@ static void musicpal_audio_write(void *opaque, target_phys_addr_t offset, |
| 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,7 +392,7 @@ static void musicpal_audio_write(void *opaque, target_phys_addr_t offset, |
| 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,13 +537,33 @@ typedef struct mv88w8618_eth_state { |
| 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,47 +572,76 @@ static int eth_can_receive(void *opaque) |
| 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,13 +672,13 @@ 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,16 +719,16 @@ static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset, |
| 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 | } | ... | ... |