qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [4723] ETRAX: More DMA context level related fixes.
@ 2008-06-10  0:11 Edgar E. Iglesias
  0 siblings, 0 replies; only message in thread
From: Edgar E. Iglesias @ 2008-06-10  0:11 UTC (permalink / raw)
  To: qemu-devel

Revision: 4723
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4723
Author:   edgar_igl
Date:     2008-06-10 00:11:48 +0000 (Tue, 10 Jun 2008)

Log Message:
-----------
ETRAX: More DMA context level related fixes.

* When hitting EOL (end of list) at the data descriptor level, the DMA should mark the current context-descriptor as disabled and perform a context-store so software can see whats goin on.
* Context loads update RW_SAVED_DATA_BUF, data loads dont. This fixes an issue with ethernet bootstrapping.
* Reorder the logic for processing out channels to be more like the one for input channels.

Modified Paths:
--------------
    trunk/hw/etraxfs_dma.c

Modified: trunk/hw/etraxfs_dma.c
===================================================================
--- trunk/hw/etraxfs_dma.c	2008-06-09 23:44:44 UTC (rev 4722)
+++ trunk/hw/etraxfs_dma.c	2008-06-10 00:11:48 UTC (rev 4723)
@@ -267,23 +267,33 @@
 	target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA);
 
 	/* Load and decode. FIXME: handle endianness.  */
-	D(printf("%s addr=%x\n", __func__, addr));
+	D(printf("%s ch=%d addr=%x\n", __func__, c, addr));
 	cpu_physical_memory_read (addr,
 				  (void *) &ctrl->channels[c].current_d, 
 				  sizeof ctrl->channels[c].current_d);
 
 	D(dump_d(c, &ctrl->channels[c].current_d));
 	ctrl->channels[c].regs[RW_DATA] = addr;
-	ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
-		(uint32_t)ctrl->channels[c].current_d.buf;
 }
 
+static void channel_store_c(struct fs_dma_ctrl *ctrl, int c)
+{
+	target_phys_addr_t addr = channel_reg(ctrl, c, RW_GROUP_DOWN);
+
+	/* Encode and store. FIXME: handle endianness.  */
+	D(printf("%s ch=%d addr=%x\n", __func__, c, addr));
+	D(dump_d(c, &ctrl->channels[c].current_d));
+	cpu_physical_memory_write (addr,
+				  (void *) &ctrl->channels[c].current_c,
+				  sizeof ctrl->channels[c].current_c);
+}
+
 static void channel_store_d(struct fs_dma_ctrl *ctrl, int c)
 {
 	target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA);
 
-	/* Load and decode. FIXME: handle endianness.  */
-	D(printf("%s addr=%x\n", __func__, addr));
+	/* Encode and store. FIXME: handle endianness.  */
+	D(printf("%s ch=%d addr=%x\n", __func__, c, addr));
 	cpu_physical_memory_write (addr,
 				  (void *) &ctrl->channels[c].current_d, 
 				  sizeof ctrl->channels[c].current_d);
@@ -326,20 +336,23 @@
 	/* If the current descriptor cleared the eol flag and we had already
 	   reached eol state, do the continue.  */
 	if (!ctrl->channels[c].current_d.eol && ctrl->channels[c].eol) {
-		D(printf("continue %d ok %x\n", c,
+		D(printf("continue %d ok %p\n", c,
 			 ctrl->channels[c].current_d.next));
 		ctrl->channels[c].regs[RW_SAVED_DATA] =
 			(uint32_t) ctrl->channels[c].current_d.next;
 		channel_load_d(ctrl, c);
 		channel_start(ctrl, c);
 	}
+	ctrl->channels[c].regs[RW_SAVED_DATA_BUF] =
+		(uint32_t) ctrl->channels[c].current_d.buf;
 }
 
 static void channel_stream_cmd(struct fs_dma_ctrl *ctrl, int c, uint32_t v)
 {
 	unsigned int cmd = v & ((1 << 10) - 1);
 
-	D(printf("%s cmd=%x\n", __func__, cmd));
+	D(printf("%s ch=%d cmd=%x pc=%x\n",
+		 __func__, c, cmd, ctrl->env->pc));
 	if (cmd & regk_dma_load_d) {
 		channel_load_d(ctrl, c);
 		if (cmd & regk_dma_burst)
@@ -348,6 +361,7 @@
 
 	if (cmd & regk_dma_load_c) {
 		channel_load_c(ctrl, c);
+		channel_start(ctrl, c);
 	}
 }
 
@@ -382,11 +396,30 @@
 
 	saved_data_buf = channel_reg(ctrl, c, RW_SAVED_DATA_BUF);
 
-	D(printf("buf=%x after=%x saved_data_buf=%x\n",
+	D(fprintf(logfile, "ch=%d buf=%x after=%x saved_data_buf=%x\n",
+		 c,
 		 (uint32_t)ctrl->channels[c].current_d.buf,
 		 (uint32_t)ctrl->channels[c].current_d.after,
 		 saved_data_buf));
 
+	len = (uint32_t) ctrl->channels[c].current_d.after;
+	len -= saved_data_buf;
+
+	if (len > sizeof buf)
+		len = sizeof buf;
+	cpu_physical_memory_read (saved_data_buf, buf, len);
+
+	D(printf("channel %d pushes %x %u bytes\n", c, 
+		 saved_data_buf, len));
+
+	if (ctrl->channels[c].client->client.push)
+		ctrl->channels[c].client->client.push(
+			ctrl->channels[c].client->client.opaque, buf, len);
+	else
+		printf("WARNING: DMA ch%d dataloss, no attached client.\n", c);
+
+	saved_data_buf += len;
+
 	if (saved_data_buf == (uint32_t)ctrl->channels[c].current_d.after) {
 		/* Done. Step to next.  */
 		if (ctrl->channels[c].current_d.out_eop) {
@@ -403,36 +436,26 @@
 		if (ctrl->channels[c].current_d.eol) {
 			D(printf("channel %d EOL\n", c));
 			ctrl->channels[c].eol = 1;
+
+			/* Mark the context as disabled.  */
+			ctrl->channels[c].current_c.dis = 1;
+			channel_store_c(ctrl, c);
+
 			channel_stop(ctrl, c);
 		} else {
 			ctrl->channels[c].regs[RW_SAVED_DATA] =
 				(uint32_t) ctrl->channels[c].current_d.next;
 			/* Load new descriptor.  */
 			channel_load_d(ctrl, c);
+			saved_data_buf = (uint32_t)
+				ctrl->channels[c].current_d.buf;
 		}
 
 		channel_store_d(ctrl, c);
+		ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
 		D(dump_d(c, &ctrl->channels[c].current_d));
-		return;
 	}
-
-	len = (uint32_t) ctrl->channels[c].current_d.after;
-	len -= saved_data_buf;
-
-	if (len > sizeof buf)
-		len = sizeof buf;
-	cpu_physical_memory_read (saved_data_buf, buf, len);
-
-	D(printf("channel %d pushes %x %u bytes\n", c, 
-		 saved_data_buf, len));
-	/* TODO: Push content.  */
-	if (ctrl->channels[c].client->client.push)
-		ctrl->channels[c].client->client.push(
-			ctrl->channels[c].client->client.opaque, buf, len);
-	else
-		printf("WARNING: DMA ch%d dataloss, no attached client.\n", c);
-
-	ctrl->channels[c].regs[RW_SAVED_DATA_BUF] += len;
+	ctrl->channels[c].regs[RW_SAVED_DATA_BUF] = saved_data_buf;
 }
 
 static int channel_in_process(struct fs_dma_ctrl *ctrl, int c, 
@@ -483,14 +506,19 @@
 		if (ctrl->channels[c].current_d.eol) {
 			D(printf("channel %d EOL\n", c));
 			ctrl->channels[c].eol = 1;
+
+			/* Mark the context as disabled.  */
+			ctrl->channels[c].current_c.dis = 1;
+			channel_store_c(ctrl, c);
+
 			channel_stop(ctrl, c);
 		} else {
 			ctrl->channels[c].regs[RW_SAVED_DATA] =
 				(uint32_t) ctrl->channels[c].current_d.next;
 			/* Load new descriptor.  */
 			channel_load_d(ctrl, c);
-			saved_data_buf =
-				ctrl->channels[c].regs[RW_SAVED_DATA_BUF];
+			saved_data_buf = (uint32_t)
+				ctrl->channels[c].current_d.buf;
 		}
 	}
 
@@ -523,21 +551,21 @@
 
 	/* Make addr relative to this instances base.  */
 	c = fs_channel(ctrl->base, addr);
-        addr &= 0x1fff;
+	addr &= 0x1fff;
 	switch (addr)
-        {
+	{
 		case RW_STAT:
 			r = ctrl->channels[c].state & 7;
 			r |= ctrl->channels[c].eol << 5;
 			r |= ctrl->channels[c].stream_cmd_src << 8;
 			break;
 
-                default:
+		default:
 			r = ctrl->channels[c].regs[addr];
 			D(printf ("%s c=%d addr=%x pc=%x\n",
-				 __func__, c, addr, env->pc));
-                        break;
-        }
+				  __func__, c, addr, ctrl->env->pc));
+			break;
+	}
 	return r;
 }
 
@@ -560,7 +588,7 @@
 	c = fs_channel(ctrl->base, addr);
         addr &= 0x1fff;
         switch (addr)
-        {
+	{
 		case RW_DATA:
 			ctrl->channels[c].regs[addr] = value;
 			break;
@@ -591,13 +619,15 @@
 
 		case RW_STREAM_CMD:
 			ctrl->channels[c].regs[addr] = value;
+			D(printf("stream_cmd ch=%d pc=%x\n",
+				 c, ctrl->env->pc));
 			channel_stream_cmd(ctrl, c, value);
 			break;
 
-                default:
-                        D(printf ("%s c=%d %x %x pc=%x\n",
-				  __func__, c, addr, value, env->pc));
-                        break;
+	        default:
+			D(printf ("%s c=%d %x %x pc=%x\n",
+				  __func__, c, addr, value, ctrl->env->pc));
+			break;
         }
 }
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-06-10  0:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-10  0:11 [Qemu-devel] [4723] ETRAX: More DMA context level related fixes Edgar E. Iglesias

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).