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