qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Joerg Platte <lists@naasa.net>
To: Blue Swirl <blueswir1@hotmail.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] SPARC iommu mapping
Date: Fri, 14 Apr 2006 18:07:35 +0200	[thread overview]
Message-ID: <200604141807.36928.lists@naasa.net> (raw)
In-Reply-To: <BAY104-F14A6DE1E43777AC300D3D2FFCD0@phx.gbl>

[-- Attachment #1: Type: text/plain, Size: 1689 bytes --]

Am Dienstag, 11. April 2006 21:21 schrieb Blue Swirl:
Hi!

> Great work! Now the Debian 3.0r4 installer with 2.6.11+tcx kernel almost
> finishes. Performance is also much better.

I tried to boot a deb-bootstrapped SPARC image. But the first executed script 
segfaults when executing another command in backticks. The same happens when 
executing the bash and inside the bash another command. When the other 
command exits the bash segfaults. Other shells like the csh or the tcsh don't 
suffer from this problem.

After replacing the bash in the image with a minimal bourne compatible shell 
qemu was able to execute all scripts in rcS.

Then I tried to track down this problem with gdb and strace. But 
unfortunately, both are segfaulting, too. This makes debugging somewhat 
harder... Now, I'll try to analyze the core files of the crashing programs to 
get an idea what's going wrong. Or do you have any idea? What's the 
difference between bash compared to other shells?

> There is some problem with CDROM access, the files on CD look corrupt,
> whereas the same image used as hdb works perfectly.

Strange. I started qemu with "-cdrom /dev/cdrom" and could see all contents 
without a problem. What exactly did you try?

> Some comments on the code: Instead of adding s->bufstart, maybe you could
> use the s->rptr, as it is used for similar purpose for FIFO. Please add
> more spaces to conform to general code style.

OK, have a look at the attached patch.

> For even better performance, you could try to avoid the memory to buffer
> copy and give bdrv_read pointer to host memory.

Yes, I'll try this in the next patch :-)

regards,
Jörg

[-- Attachment #2: qemu-sparc-write-patch.diff --]
[-- Type: text/x-diff, Size: 4303 bytes --]

--- esp.c	2006-04-14 17:53:09.000000000 +0200
+++ esp.c.new	2006-04-14 17:49:55.000000000 +0200
@@ -229,12 +229,17 @@
                             target_phys_addr_t phys_addr, 
                             int transfer_size1)
 {
+    int len;
+    if (bdrv_get_type_hint(s->bd[s->target]) == BDRV_TYPE_CDROM) {
+        len = transfer_size1/2048;
+    } else {
+        len = transfer_size1/512;
+    }
     DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n",
             s->offset, s->len, s->ti_size, transfer_size1);
-    bdrv_write(s->bd[s->target], s->offset, s->ti_buf, s->len);
-    s->offset = 0;
-    s->len = 0;
-    s->target = 0;
+
+    bdrv_write(s->bd[s->target], s->offset, s->ti_buf+s->ti_rptr, len);
+    s->offset+=len;
     return 0;
 }
 
@@ -336,6 +341,7 @@
 	    bdrv_read(s->bd[target], offset, s->ti_buf, len);
 	    // XXX error handling
 	    s->ti_dir = 1;
+	    s->ti_rptr = 0;
 	    break;
 	}
     case 0x2a:
@@ -359,6 +365,7 @@
             s->offset = offset;
             s->len = len;
             s->target = target;
+            s->ti_rptr = 0;
 	    // XXX error handling
 	    s->ti_dir = 0;
 	    break;
@@ -415,10 +422,9 @@
 
 static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len)
 {
-    uint32_t dmaptr, dmalen;
+    uint32_t dmaptr;
 
-    dmalen = s->wregs[0] | (s->wregs[1] << 8);
-    DPRINTF("Transfer status len %d\n", dmalen);
+    DPRINTF("Transfer status len %d\n", len);
     if (s->dma) {
 	dmaptr = iommu_translate(s->espdmaregs[1]);
 	DPRINTF("DMA Direction: %c\n", s->espdmaregs[0] & 0x100? 'w': 'r');
@@ -428,10 +434,10 @@
 	s->rregs[6] = SEQ_CD;
     } else {
 	memcpy(s->ti_buf, buf, len);
-	s->ti_size = dmalen;
+	s->ti_size = len;
 	s->ti_rptr = 0;
 	s->ti_wptr = 0;
-	s->rregs[7] = dmalen;
+	s->rregs[7] = len;
     }
     s->espdmaregs[0] |= DMA_INTR;
     pic_set_irq(s->irq, 1);
@@ -442,34 +448,58 @@
 
 static void handle_ti(ESPState *s)
 {
-    uint32_t dmaptr, dmalen;
+    uint32_t dmaptr, dmalen, minlen, len, from, to;
     unsigned int i;
 
     dmalen = s->wregs[0] | (s->wregs[1] << 8);
-    DPRINTF("Transfer Information len %d\n", dmalen);
+    if (dmalen==0) {
+      dmalen=0x10000;
+    }
+
+    minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
+    DPRINTF("Transfer Information len %d\n", minlen);
     if (s->dma) {
 	dmaptr = iommu_translate(s->espdmaregs[1]);
-	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr);
-	for (i = 0; i < s->ti_size; i++) {
+	DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x %d %d\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr, s->ti_size, s->ti_rptr, s->ti_dir);
+	from = s->espdmaregs[1];
+	to = from + minlen;
+	for (i = 0; i < minlen; i += len, from += len) {
 	    dmaptr = iommu_translate(s->espdmaregs[1] + i);
+	    if ((from & TARGET_PAGE_MASK) != (to & TARGET_PAGE_MASK)) {
+               len = TARGET_PAGE_SIZE - (from & ~TARGET_PAGE_MASK);
+            } else {
+	       len = to - from;
+            }
+            DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to %08x\n", dmaptr, s->espdmaregs[1] + i, len, from, to);
 	    if (s->ti_dir)
-		cpu_physical_memory_write(dmaptr, &s->ti_buf[i], 1);
+		cpu_physical_memory_write(dmaptr, &s->ti_buf[s->ti_rptr + i], len);
 	    else
-		cpu_physical_memory_read(dmaptr, &s->ti_buf[i], 1);
+		cpu_physical_memory_read(dmaptr, &s->ti_buf[s->ti_rptr + i], len);
 	}
         if (s->dma_cb) {
-            s->dma_cb(s, s->espdmaregs[1], dmalen);
+            s->dma_cb(s, s->espdmaregs[1], minlen);
+        }
+        if (minlen < s->ti_size) {
+	    s->rregs[4] = STAT_IN | STAT_TC | (s->ti_dir ? STAT_DO : STAT_DI);
+	    s->ti_size -= minlen;
+	    s->ti_rptr += minlen;
+        } else {
+	    s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
             s->dma_cb = NULL;
+            s->offset = 0;
+            s->len = 0;
+            s->target = 0;
+            s->ti_rptr = 0;
         }
-	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
-	s->rregs[5] = INTR_BS;
+        s->rregs[5] = INTR_BS;
 	s->rregs[6] = 0;
+	s->rregs[7] = 0;
 	s->espdmaregs[0] |= DMA_INTR;
     } else {
-	s->ti_size = dmalen;
+	s->ti_size = minlen;
 	s->ti_rptr = 0;
 	s->ti_wptr = 0;
-	s->rregs[7] = dmalen;
+	s->rregs[7] = minlen;
     }	
     pic_set_irq(s->irq, 1);
 }

  reply	other threads:[~2006-04-14 16:07 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-04-07 15:44 [Qemu-devel] SPARC iommu mapping Blue Swirl
2006-04-07 21:33 ` Joerg Platte
2006-04-09 16:31 ` Joerg Platte
2006-04-10 13:18 ` Joerg Platte
2006-04-11 19:21   ` Blue Swirl
2006-04-14 16:07     ` Joerg Platte [this message]
2006-04-17  8:49       ` Blue Swirl
2006-05-03 18:37         ` Joerg Platte
2006-05-03 18:52           ` Blue Swirl
  -- strict thread matches above, loose matches on Subject: below --
2006-04-04 19:27 Joerg Platte
2006-04-05 15:23 ` Joerg Platte
2006-04-05 17:36   ` Blue Swirl
2006-04-05 18:14     ` Joerg Platte
2006-04-05 18:25     ` Joerg Platte
2006-04-05 20:03     ` Joerg Platte
2006-04-06 16:53     ` Joerg Platte

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200604141807.36928.lists@naasa.net \
    --to=lists@naasa.net \
    --cc=blueswir1@hotmail.com \
    --cc=jplatte@naasa.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).