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,30 +72,6 @@ static uint32_t gpio_isr; | ||
| 72 | static uint32_t gpio_out_state; | 72 | static uint32_t gpio_out_state; |
| 73 | static ram_addr_t sram_off; | 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 | typedef enum i2c_state { | 75 | typedef enum i2c_state { |
| 100 | STOPPED = 0, | 76 | STOPPED = 0, |
| 101 | INITIALIZING, | 77 | INITIALIZING, |
| @@ -253,7 +229,7 @@ typedef struct musicpal_audio_state { | @@ -253,7 +229,7 @@ typedef struct musicpal_audio_state { | ||
| 253 | uint32_t status; | 229 | uint32_t status; |
| 254 | uint32_t irq_enable; | 230 | uint32_t irq_enable; |
| 255 | unsigned long phys_buf; | 231 | unsigned long phys_buf; |
| 256 | - int8_t *target_buffer; | 232 | + uint32_t target_buffer; |
| 257 | unsigned int threshold; | 233 | unsigned int threshold; |
| 258 | unsigned int play_pos; | 234 | unsigned int play_pos; |
| 259 | unsigned int last_free; | 235 | unsigned int last_free; |
| @@ -265,6 +241,7 @@ static void audio_callback(void *opaque, int free_out, int free_in) | @@ -265,6 +241,7 @@ static void audio_callback(void *opaque, int free_out, int free_in) | ||
| 265 | { | 241 | { |
| 266 | musicpal_audio_state *s = opaque; | 242 | musicpal_audio_state *s = opaque; |
| 267 | int16_t *codec_buffer; | 243 | int16_t *codec_buffer; |
| 244 | + int8_t buf[4096]; | ||
| 268 | int8_t *mem_buffer; | 245 | int8_t *mem_buffer; |
| 269 | int pos, block_size; | 246 | int pos, block_size; |
| 270 | 247 | ||
| @@ -281,7 +258,12 @@ static void audio_callback(void *opaque, int free_out, int free_in) | @@ -281,7 +258,12 @@ static void audio_callback(void *opaque, int free_out, int free_in) | ||
| 281 | if (free_out - s->last_free < block_size) | 258 | if (free_out - s->last_free < block_size) |
| 282 | return; | 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 | if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) { | 267 | if (s->playback_mode & MP_AUDIO_16BIT_SAMPLE) { |
| 286 | if (s->playback_mode & MP_AUDIO_MONO) { | 268 | if (s->playback_mode & MP_AUDIO_MONO) { |
| 287 | codec_buffer = wm8750_dac_buffer(s->wm, block_size >> 1); | 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,7 +381,7 @@ static void musicpal_audio_write(void *opaque, target_phys_addr_t offset, | ||
| 399 | 381 | ||
| 400 | case MP_AUDIO_TX_START_LO: | 382 | case MP_AUDIO_TX_START_LO: |
| 401 | s->phys_buf = (s->phys_buf & 0xFFFF0000) | (value & 0xFFFF); | 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 | s->play_pos = 0; | 385 | s->play_pos = 0; |
| 404 | s->last_free = 0; | 386 | s->last_free = 0; |
| 405 | break; | 387 | break; |
| @@ -410,7 +392,7 @@ static void musicpal_audio_write(void *opaque, target_phys_addr_t offset, | @@ -410,7 +392,7 @@ static void musicpal_audio_write(void *opaque, target_phys_addr_t offset, | ||
| 410 | 392 | ||
| 411 | case MP_AUDIO_TX_START_HI: | 393 | case MP_AUDIO_TX_START_HI: |
| 412 | s->phys_buf = (s->phys_buf & 0xFFFF) | (value << 16); | 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 | s->play_pos = 0; | 396 | s->play_pos = 0; |
| 415 | s->last_free = 0; | 397 | s->last_free = 0; |
| 416 | break; | 398 | break; |
| @@ -555,13 +537,33 @@ typedef struct mv88w8618_eth_state { | @@ -555,13 +537,33 @@ typedef struct mv88w8618_eth_state { | ||
| 555 | uint32_t icr; | 537 | uint32_t icr; |
| 556 | uint32_t imr; | 538 | uint32_t imr; |
| 557 | int vlan_header; | 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 | VLANClientState *vc; | 544 | VLANClientState *vc; |
| 563 | } mv88w8618_eth_state; | 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 | static int eth_can_receive(void *opaque) | 567 | static int eth_can_receive(void *opaque) |
| 566 | { | 568 | { |
| 567 | return 1; | 569 | return 1; |
| @@ -570,47 +572,76 @@ static int eth_can_receive(void *opaque) | @@ -570,47 +572,76 @@ static int eth_can_receive(void *opaque) | ||
| 570 | static void eth_receive(void *opaque, const uint8_t *buf, int size) | 572 | static void eth_receive(void *opaque, const uint8_t *buf, int size) |
| 571 | { | 573 | { |
| 572 | mv88w8618_eth_state *s = opaque; | 574 | mv88w8618_eth_state *s = opaque; |
| 573 | - mv88w8618_rx_desc *desc; | 575 | + uint32_t desc_addr; |
| 576 | + mv88w8618_rx_desc desc; | ||
| 574 | int i; | 577 | int i; |
| 575 | 578 | ||
| 576 | for (i = 0; i < 4; i++) { | 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 | continue; | 582 | continue; |
| 580 | do { | 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 | s->icr |= MP_ETH_IRQ_RX; | 592 | s->icr |= MP_ETH_IRQ_RX; |
| 591 | if (s->icr & s->imr) | 593 | if (s->icr & s->imr) |
| 592 | qemu_irq_raise(s->irq); | 594 | qemu_irq_raise(s->irq); |
| 595 | + eth_rx_desc_put(desc_addr, &desc); | ||
| 593 | return; | 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 | static void eth_send(mv88w8618_eth_state *s, int queue_index) | 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 | do { | 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 | s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index); | 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 | static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset) | 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,13 +672,13 @@ static uint32_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset) | ||
| 641 | return s->imr; | 672 | return s->imr; |
| 642 | 673 | ||
| 643 | case MP_ETH_FRDP0 ... MP_ETH_FRDP3: | 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 | case MP_ETH_CRDP0 ... MP_ETH_CRDP3: | 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 | case MP_ETH_CTDP0 ... MP_ETH_CTDP3: | 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 | default: | 683 | default: |
| 653 | return 0; | 684 | return 0; |
| @@ -688,16 +719,16 @@ static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset, | @@ -688,16 +719,16 @@ static void mv88w8618_eth_write(void *opaque, target_phys_addr_t offset, | ||
| 688 | break; | 719 | break; |
| 689 | 720 | ||
| 690 | case MP_ETH_FRDP0 ... MP_ETH_FRDP3: | 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 | break; | 723 | break; |
| 693 | 724 | ||
| 694 | case MP_ETH_CRDP0 ... MP_ETH_CRDP3: | 725 | case MP_ETH_CRDP0 ... MP_ETH_CRDP3: |
| 695 | s->rx_queue[(offset - MP_ETH_CRDP0)/4] = | 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 | break; | 728 | break; |
| 698 | 729 | ||
| 699 | case MP_ETH_CTDP0 ... MP_ETH_CTDP3: | 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 | break; | 732 | break; |
| 702 | } | 733 | } |
| 703 | } | 734 | } |