From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1L2Ycn-0002rD-MQ for qemu-devel@nongnu.org; Tue, 18 Nov 2008 17:00:45 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1L2Ycn-0002qe-7x for qemu-devel@nongnu.org; Tue, 18 Nov 2008 17:00:45 -0500 Received: from [199.232.76.173] (port=53141 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1L2Ycn-0002qZ-19 for qemu-devel@nongnu.org; Tue, 18 Nov 2008 17:00:45 -0500 Received: from savannah.gnu.org ([199.232.41.3]:37860 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1L2Ycn-00016I-1h for qemu-devel@nongnu.org; Tue, 18 Nov 2008 17:00:45 -0500 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1L2Ycm-0004UG-3Z for qemu-devel@nongnu.org; Tue, 18 Nov 2008 22:00:44 +0000 Received: from aliguori by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1L2Ycl-0004UB-Q4 for qemu-devel@nongnu.org; Tue, 18 Nov 2008 22:00:43 +0000 MIME-Version: 1.0 Errors-To: aliguori Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Anthony Liguori Message-Id: Date: Tue, 18 Nov 2008 22:00:43 +0000 Subject: [Qemu-devel] [5750] Add 40-bit DMA support to LSI scsi emulation (Ryan Harper) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 5750 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5750 Author: aliguori Date: 2008-11-18 22:00:43 +0000 (Tue, 18 Nov 2008) Log Message: ----------- Add 40-bit DMA support to LSI scsi emulation (Ryan Harper) This patch fixes Linux machines configured with > 4G of ram and using a SCSI device. Signed-off-by: Ryan Harper Signed-off-by: Anthony Liguori Modified Paths: -------------- trunk/hw/lsi53c895a.c Modified: trunk/hw/lsi53c895a.c =================================================================== --- trunk/hw/lsi53c895a.c 2008-11-18 21:52:54 UTC (rev 5749) +++ trunk/hw/lsi53c895a.c 2008-11-18 22:00:43 UTC (rev 5750) @@ -143,6 +143,14 @@ #define LSI_CCNTL0_PMJCTL 0x40 #define LSI_CCNTL0_ENPMJ 0x80 +#define LSI_CCNTL1_EN64DBMV 0x01 +#define LSI_CCNTL1_EN64TIBMV 0x02 +#define LSI_CCNTL1_64TIMOD 0x04 +#define LSI_CCNTL1_DDAC 0x08 +#define LSI_CCNTL1_ZMOD 0x80 + +#define LSI_CCNTL1_40BIT (LSI_CCNTL1_EN64TIBMV|LSI_CCNTL1_64TIMOD) + #define PHASE_DO 0 #define PHASE_DI 1 #define PHASE_CMD 2 @@ -323,6 +331,13 @@ s->csbc = 0; } +static int lsi_dma_40bit(LSIState *s) +{ + if ((s->ccntl1 & LSI_CCNTL1_40BIT) == LSI_CCNTL1_40BIT) + return 1; + return 0; +} + static uint8_t lsi_reg_readb(LSIState *s, int offset); static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val); static void lsi_execute_script(LSIState *s); @@ -449,7 +464,7 @@ static void lsi_do_dma(LSIState *s, int out) { uint32_t count; - uint32_t addr; + target_phys_addr_t addr; if (!s->current_dma_len) { /* Wait until data is available. */ @@ -460,9 +475,14 @@ count = s->dbc; if (count > s->current_dma_len) count = s->current_dma_len; - DPRINTF("DMA addr=0x%08x len=%d\n", s->dnad, count); addr = s->dnad; + if (lsi_dma_40bit(s)) + addr |= ((uint64_t)s->dnad64 << 32); + else if (s->sbms) + addr |= ((uint64_t)s->sbms << 32); + + DPRINTF("DMA addr=0x%" TARGET_FMT_plx " len=%d\n", addr, count); s->csbc += count; s->dnad += count; s->dbc -= count; @@ -839,7 +859,7 @@ static void lsi_execute_script(LSIState *s) { uint32_t insn; - uint32_t addr; + uint32_t addr, addr_high; int opcode; int insn_processed = 0; @@ -848,6 +868,7 @@ insn_processed++; insn = read_dword(s, s->dsp); addr = read_dword(s, s->dsp + 4); + addr_high = 0; DPRINTF("SCRIPTS dsp=%08x opcode %08x arg %08x\n", s->dsp, insn, addr); s->dsps = addr; s->dcmd = insn >> 24; @@ -870,9 +891,15 @@ /* Table indirect addressing. */ offset = sxt24(addr); cpu_physical_memory_read(s->dsa + offset, (uint8_t *)buf, 8); - s->dbc = cpu_to_le32(buf[0]); + /* byte count is stored in bits 0:23 only */ + s->dbc = cpu_to_le32(buf[0]) & 0xffffff; s->rbc = s->dbc; addr = cpu_to_le32(buf[1]); + + /* 40-bit DMA, upper addr bits [39:32] stored in first DWORD of + * table, bits [31:24] */ + if (lsi_dma_40bit(s)) + addr_high = cpu_to_le32(buf[0]) >> 24; } if ((s->sstat1 & PHASE_MASK) != ((insn >> 24) & 7)) { DPRINTF("Wrong phase got %d expected %d\n", @@ -881,6 +908,7 @@ break; } s->dnad = addr; + s->dnad64 = addr_high; /* ??? Set ESA. */ s->ia = s->dsp - 8; switch (s->sstat1 & 0x7) {