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 | } | ... | ... |