[Cbe-oss-dev] [RFC/PATCH] libspe2: use mapped dma registers to speed up proxy dma

stenzel at de.ibm.com stenzel at de.ibm.com
Fri May 18 22:58:07 EST 2007


The following patch speeds up the MFC proxy command functions by
writing to the dma registers directly via mapped problem state
if the context was created with the SPE_MAP_PS flag.

Comments are appreciated

Signed-off-by: Gerhard Stenzel <stenzel at de.ibm.com>

===================================================================
Index: libspe2/spebase/dma.c
===================================================================
--- libspe2/spebase/dma.c	(revision 39)
+++ libspe2/spebase/dma.c	(working copy)
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -28,8 +29,8 @@
 #include "create.h"
 #include "dma.h"
 
-static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int *tag_status);
-static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int *tag_status);
+static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status);
+static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status);
 
 static int spe_do_mfc_put(spe_context_ptr_t spectx, unsigned src, void *dst,
 			  unsigned size, unsigned tag, unsigned class,
@@ -44,15 +45,31 @@ static int spe_do_mfc_put(spe_context_pt
 		.cmd   = cmd,
 	};
 	int ret, fd;
+	unsigned int eah, eal;
+	volatile struct spe_mfc_command_area *cmd_area = 
+                spectx->base_private->mfc_mmap_base;
 
 	DEBUG_PRINTF("queuing DMA %x %lx %x %x %x %x\n", parm.lsa,
 		parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
-#if 0 // fixme
+
 	if (spectx->base_private->flags & SPE_MAP_PS) {
-		return 0;
+		_base_spe_context_lock(spectx, FD_MFC);
+		eal = (uintptr_t) dst & 0xFFFFFFFF;
+		eah = (unsigned long long)(uintptr_t) dst >> 32;
+		while ((cmd_area->MFC_QStatus & 0x0000FFFF) == 0) ;
+		do {
+			cmd_area->MFC_LSA         = src;
+			cmd_area->MFC_EAH         = eah;
+			cmd_area->MFC_EAL         = eal;
+			cmd_area->MFC_Size_Tag    = (size << 16) | tag;
+                        cmd_area->MFC_ClassID_CMD = (class << 16) | cmd;
+
+			ret = cmd_area->MFC_CMDStatus & 0x00000003;
+		} while (ret); // at least one of the two bits is set
+		_base_spe_context_unlock(spectx, FD_MFC);
+		return ret;
 	}
-#endif
-	DEBUG_PRINTF("%s $d\n", __FUNCTION__, __LINE__);
+
 	fd = open_if_closed(spectx, FD_MFC, 0);
 	if (fd != -1) {
 		ret = write(fd, &parm, sizeof (parm));
@@ -79,15 +96,31 @@ static int spe_do_mfc_get(spe_context_pt
 		.cmd   = cmd,
 	};
 	int ret, fd;
+	unsigned int eah, eal;
+	volatile struct spe_mfc_command_area *cmd_area = 
+                spectx->base_private->mfc_mmap_base;
+
+	DEBUG_PRINTF("queuing DMA %x %x %x %x %x %x\n", parm.lsa,
+	                                           parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
+	
+
+        if (spectx->base_private->flags & SPE_MAP_PS) {
+		_base_spe_context_lock(spectx, FD_MFC);
+		eal = (uintptr_t) src & 0xFFFFFFFF;
+		eah = (unsigned long long)(uintptr_t) src >> 32;
+                while ((cmd_area->MFC_QStatus & 0x0000FFFF) == 0) ;
+                do {
+                        cmd_area->MFC_LSA         = dst;
+                        cmd_area->MFC_EAH         = eah;
+                        cmd_area->MFC_EAL         = eal;
+                        cmd_area->MFC_Size_Tag    = (size << 16) | tag;
+                        cmd_area->MFC_ClassID_CMD = (class << 16) | cmd;
+                        ret = cmd_area->MFC_CMDStatus & 0x00000003;
+                } while (ret); // at least one of the two bits is set
+		_base_spe_context_unlock(spectx, FD_MFC);
+                return ret;
+        }
 
-	DEBUG_PRINTF("queuing DMA %x %lx %x %x %x %x\n", parm.lsa,
-		parm.ea, parm.size, parm.tag, parm.class, parm.cmd);
-#if 0 // fixme
-	if (spectx->base_private->flags & SPE_MAP_PS) {
-		return 0;
-	}
-#endif
-	DEBUG_PRINTF("%s $d\n", __FUNCTION__, __LINE__);
 	fd = open_if_closed(spectx, FD_MFC, 0);
 	if (fd != -1) {
 		ret = write(fd, &parm, sizeof (parm));
@@ -182,8 +215,7 @@ static int spe_mfcio_tag_status_read_all
 	int fd;
 
 	if (spectx->base_private->flags & SPE_MAP_PS) {
-		// fixme
-		errno = ENOTSUP;
+		return spe_read_tag_status_block(spectx, mask, tag_status);
 	} else {
 		fd = open_if_closed(spectx, FD_MFC, 0);
 
@@ -191,7 +223,7 @@ static int spe_mfcio_tag_status_read_all
 			return -1;
 		}
 
-		return spe_read_tag_status_block(spectx, tag_status);
+		return spe_read_tag_status_block(spectx, mask, tag_status);
 	}
 	return -1;
 }
@@ -199,13 +231,13 @@ static int spe_mfcio_tag_status_read_all
 static int spe_mfcio_tag_status_read_any(spe_context_ptr_t spectx,
 					unsigned int mask, unsigned int *tag_status)
 {
-	return spe_read_tag_status_block(spectx, tag_status);
+	return spe_read_tag_status_block(spectx, mask, tag_status);
 }
 
 static int spe_mfcio_tag_status_read_immediate(spe_context_ptr_t spectx,
 						     unsigned int mask, unsigned int *tag_status)
 {
-	return spe_read_tag_status_noblock(spectx, tag_status);
+	return spe_read_tag_status_noblock(spectx, mask, tag_status);
 }
 
 
@@ -213,13 +245,20 @@ static int spe_mfcio_tag_status_read_imm
 /* MFC Read tag status functions
  *
  */
-static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int *tag_status)
+static int spe_read_tag_status_block(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status)
 {
 	int fd;
+	volatile struct spe_mfc_command_area *cmd_area = 
+                spectx->base_private->mfc_mmap_base;
 
 	if (spectx->base_private->flags & SPE_MAP_PS) {
-		// fixme
-		errno = ENOTSUP;
+		_base_spe_context_lock(spectx, FD_MFC);
+		cmd_area->Prxy_QueryMask = mask;
+		__asm__ ("eieio");
+		while  (*tag_status ^ mask) 
+			*tag_status =  cmd_area->Prxy_TagStatus;
+		_base_spe_context_unlock(spectx, FD_MFC);
+		return 0;
 	} else {
 		fd = open_if_closed(spectx, FD_MFC, 0);
 		
@@ -230,16 +269,22 @@ static int spe_read_tag_status_block(spe
 	return -1;
 }
 
-static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int *tag_status)
+static int spe_read_tag_status_noblock(spe_context_ptr_t spectx, unsigned int mask, unsigned int *tag_status)
 {
 	struct pollfd poll_fd;
 	
 	int fd;
 	unsigned int ret;
+	volatile struct spe_mfc_command_area *cmd_area = 
+                spectx->base_private->mfc_mmap_base;
 
 	if (spectx->base_private->flags & SPE_MAP_PS) {
-		// fixme
-		errno = ENOTSUP;
+		_base_spe_context_lock(spectx, FD_MFC);
+		cmd_area->Prxy_QueryMask = mask;
+		__asm__ ("eieio");
+		*tag_status =  cmd_area->Prxy_TagStatus;
+		_base_spe_context_unlock(spectx, FD_MFC);
+		return 0;
 	} else {
 		fd = open_if_closed(spectx, FD_MFC, 0);
 		
@@ -266,8 +311,8 @@ static int spe_read_tag_status_noblock(s
 int _base_spe_mfcio_tag_status_read(spe_context_ptr_t spectx, unsigned int mask, unsigned int behavior, unsigned int *tag_status)
 {
 	if ( mask != 0 ) {
-		errno = ENOTSUP;
-		return -1;
+		if (!(spectx->base_private->flags & SPE_MAP_PS)) 
+			mask = 0;
 	}
 
 	switch (behavior) {

===================================================================

Best regards, 

Gerhard Stenzel, Linux on Cell Development, LTC
-------------------------------------------------------------------------------------
IBM Deutschland Entwicklung GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter | Geschaeftsfuehrung: Herbert Kircher
Sitz der Gesellschaft: Boeblingen | Registergericht: Amtsgericht Stuttgart, HRB 243294




More information about the cbe-oss-dev mailing list