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
--- 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); }
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel