qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [4723] ETRAX: More DMA context level related fixes.
Date: Tue, 10 Jun 2008 00:11:50 +0000	[thread overview]
Message-ID: <E1K5rSn-0000aY-Vd@cvs.savannah.gnu.org> (raw)

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;
         }
 }
 

                 reply	other threads:[~2008-06-10  0:11 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1K5rSn-0000aY-Vd@cvs.savannah.gnu.org \
    --to=edgar.iglesias@gmail.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).