Commit 930c86820e8e0b6dfcf211bda5e835463d72ff42

Authored by pbrook
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 }
... ...