[Cbe-oss-dev] [PATCH] libspe2: use mapped dma registers to speed up proxy dma
stenzel at de.ibm.com
stenzel at de.ibm.com
Wed Jun 6 19:38:10 EST 2007
The following patch speeds up the MFC proxy command functions by
writing to the dma registers directly via mapped problem state.
This new implementation has two small side effects, but this should
have no impact on existing applications because the current
implementation does not support proxy command at all, if the context
was created with the SPE_MAP_PS flag.
The two side effects are, if a context is created with SPE_MAP_PS:
1) A mask value of 0 will not be interpreted as "all outsanding tags"
2) An event handler can not register for a SPE_EVENT_TAG_GROUP
Signed-off-by: Gerhard Stenzel <stenzel at de.ibm.com>
===================================================================
Index: libspe2/spebase/dma.c
===================================================================
--- libspe2/spebase/dma.c (revision 48)
+++ 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,21 @@ 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");
+ *tag_status = 0;
+ 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 +270,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 +312,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) {
Index: libspe2/speevent/spe_event.c
===================================================================
--- libspe2/speevent/spe_event.c (revision 48)
+++ libspe2/speevent/spe_event.c (working copy)
@@ -221,6 +221,12 @@ int _event_spe_event_handler_register(sp
_event_spe_context_unlock(event->spe);
return -1;
}
+
+ if (event->spe->base_private->flags & SPE_MAP_PS) {
+ _event_spe_context_unlock(event->spe);
+ errno = ENOTSUP;
+ return -1;
+ }
ev_buf = &evctx->events[__SPE_EVENT_TAG_GROUP];
ev_buf->events = SPE_EVENT_TAG_GROUP;
===================================================================
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