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