r3741 - trunk/src/host/qemu-neo1973/hw

andrew at sita.openmoko.org andrew at sita.openmoko.org
Thu Dec 27 06:55:26 CET 2007


Author: andrew
Date: 2007-12-27 06:55:24 +0100 (Thu, 27 Dec 2007)
New Revision: 3741

Modified:
   trunk/src/host/qemu-neo1973/hw/ar6000.c
   trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c
Log:
Implement byte and half-word reads/writes from S3C MMCI FIFO.
BlockMode is in bit 27 instead of 28 in CMD53.
Make CMD53 return R5 instead of R1.
Replace receiving_state with transfer_state per the specs.


Modified: trunk/src/host/qemu-neo1973/hw/ar6000.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/ar6000.c	2007-12-27 03:48:28 UTC (rev 3740)
+++ trunk/src/host/qemu-neo1973/hw/ar6000.c	2007-12-27 05:55:24 UTC (rev 3741)
@@ -410,7 +410,7 @@
 
             if (unlikely(fun > ((sd->ioocr >> 28) & 7))) {
                 sd->card_status |= ADDRESS_ERROR;
-                return sd_r1b;
+                return sd_r5;
             }
 
             sd->transfer.dir = (req.arg >> 31) & 1;		/* R/W */
@@ -418,18 +418,22 @@
             sd->transfer.func = fun;
             sd->transfer.data_start = addr;
             sd->transfer.data_offset = 0;
-            if ((req.arg >> 28) & 1) {				/* BlockMode */
+            if ((req.arg >> 27) & 1) {				/* BlockMode */
                 if (sd->blk_len[fun] < 1 || sd->blk_len[fun] > 2048)
-                    return sd_r1b;
+                    return sd_r1;
 
                 sd->transfer.blk_len = sd->blk_len[fun];
             } else
                 sd->transfer.blk_len = 1;
             sd->transfer.blk_num = ((req.arg >> 0) & 0x1ff) ?:
-                    ((req.arg >> 28) & 1) ? -1 : 0x200;		/* BlockMode */
+                    ((req.arg >> 27) & 1) ? -1 : 0x200;		/* BlockMode */
 
+            /* XXX The R5 on real cards indicates command state for some
+             * reason.  Is that because the transfer hasn't started yet or
+             * because it has already finished when the response is made?  */
             sd->state = sd_transfer_state;
-            return sd_r1b;
+            sd->transfer.data[0] = 0x00;
+            return sd_r5;
 
         default:
             break;
@@ -553,7 +557,7 @@
     /* TODO: Append CRCs */
     uint8_t ret;
 
-    if (sd->state != sd_receivingdata_state) {
+    if (sd->state != sd_transfer_state) {
         printf("%s: not in Transfer state\n", __FUNCTION__);
         return 0x00;
     }

Modified: trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c
===================================================================
--- trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c	2007-12-27 03:48:28 UTC (rev 3740)
+++ trunk/src/host/qemu-neo1973/hw/s3c24xx_mmci.c	2007-12-27 05:55:24 UTC (rev 3741)
@@ -207,7 +207,7 @@
 
 #define S3C_SDIMAX	0x40
 
-static uint32_t s3c_mmci_read(void *opaque, target_phys_addr_t addr)
+static uint32_t s3c_mmci_readw(void *opaque, target_phys_addr_t addr)
 {
     struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
     uint32_t ret;
@@ -262,7 +262,6 @@
         else
             return s->fifolen;					/* FFCNT */
     case S3C_SDIDAT:
-        /* TODO: 8/16-bit access */
         ret = 0;
         if (s->fifolen >= 4) {
             ret |= s->fifo[s->fifostart ++] << 0;
@@ -289,7 +288,7 @@
     return 0;
 }
 
-static void s3c_mmci_write(void *opaque, target_phys_addr_t addr,
+static void s3c_mmci_writew(void *opaque, target_phys_addr_t addr,
                 uint32_t value)
 {
     struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
@@ -345,7 +344,6 @@
         s->dstatus &= ~(value & 0x3f8);
         break;
     case S3C_SDIDAT:
-        /* TODO: 8/16-bit access */
         s->fifo[(s->fifostart + s->fifolen ++) & 63] = (value >> 0) & 0xff;
         s->fifo[(s->fifostart + s->fifolen ++) & 63] = (value >> 8) & 0xff;
         s->fifo[(s->fifostart + s->fifolen ++) & 63] = (value >> 16) & 0xff;
@@ -361,16 +359,85 @@
     }
 }
 
+static uint32_t s3c_mmci_readh(void *opaque, target_phys_addr_t addr)
+{
+    struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
+    uint16_t ret = 0;
+
+    if (s->map[addr - s->base] == S3C_SDIDAT) {
+        if (s->fifolen >= 2) {
+            ret |= s->fifo[s->fifostart ++] << 0;
+            s->fifostart &= 63;
+            ret |= s->fifo[s->fifostart ++] << 8;
+            s->fifostart &= 63;
+            s->fifolen -= 2;
+            s3c_mmci_fifo_run(s);
+        } else
+            printf("%s: FIFO underrun\n", __FUNCTION__);
+
+        return ret;
+    }
+
+    printf("%s: Bad register 0x%lx\n", __FUNCTION__, addr - s->base);
+    return 0;
+}
+
+static void s3c_mmci_writeh(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
+
+    if (s->map[addr - s->base] == S3C_SDIDAT) {
+        s->fifo[(s->fifostart + s->fifolen ++) & 63] = (value >> 0) & 0xff;
+        s->fifo[(s->fifostart + s->fifolen ++) & 63] = (value >> 8) & 0xff;
+        s3c_mmci_fifo_run(s);
+    } else
+        printf("%s: Bad register 0x%lx\n", __FUNCTION__, addr - s->base);
+}
+
+static uint32_t s3c_mmci_readb(void *opaque, target_phys_addr_t addr)
+{
+    struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
+    uint8_t ret = 0;
+
+    if (s->map[addr - s->base] == S3C_SDIDAT) {
+        if (s->fifolen > 0) {
+            ret = s->fifo[s->fifostart ++];
+            s->fifostart &= 63;
+            s->fifolen --;
+            s3c_mmci_fifo_run(s);
+        } else
+            printf("%s: FIFO underrun\n", __FUNCTION__);
+
+        return ret;
+    }
+
+    printf("%s: Bad register 0x%lx\n", __FUNCTION__, addr - s->base);
+    return 0;
+}
+
+static void s3c_mmci_writeb(void *opaque, target_phys_addr_t addr,
+                uint32_t value)
+{
+    struct s3c_mmci_state_s *s = (struct s3c_mmci_state_s *) opaque;
+
+    if (s->map[addr - s->base] == S3C_SDIDAT) {
+        s->fifo[(s->fifostart + s->fifolen ++) & 63] = value;
+        s3c_mmci_fifo_run(s);
+    } else
+        printf("%s: Bad register 0x%lx\n", __FUNCTION__, addr - s->base);
+}
+
 static CPUReadMemoryFunc *s3c_mmci_readfn[] = {
-    s3c_mmci_read,
-    s3c_mmci_read,
-    s3c_mmci_read,
+    s3c_mmci_readb,
+    s3c_mmci_readh,
+    s3c_mmci_readw,
 };
 
 static CPUWriteMemoryFunc *s3c_mmci_writefn[] = {
-    s3c_mmci_write,
-    s3c_mmci_write,
-    s3c_mmci_write,
+    s3c_mmci_writeb,
+    s3c_mmci_writeh,
+    s3c_mmci_writew,
 };
 
 static void s3c_mmci_cardirq(void *opaque, int line, int level)





More information about the commitlog mailing list