qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [5750] Add 40-bit DMA support to LSI scsi emulation (Ryan H


From: Anthony Liguori
Subject: [Qemu-devel] [5750] Add 40-bit DMA support to LSI scsi emulation (Ryan Harper)
Date: Tue, 18 Nov 2008 22:00:43 +0000

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 <address@hidden>
Signed-off-by: Anthony Liguori <address@hidden>

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) {






reply via email to

[Prev in Thread] Current Thread [Next in Thread]