PDA

View Full Version : Problem on spe_context_run


jhhsia
08-Oct-2007, 06:28
Hi All,

For some reason the address argument that I want to pass to SPU does not get through. I am following the simple DMA sample from SDK 2.0 and I am passing my stuff like:

spe_context_run(speid, &entry, 0, &cb, NULL, &stop_info)

Where cb is aligned to 128 byte. and my SPU entry looks like:

int main( unsigned long long spuid, unsigned long long argp, unsigned long long envp)

If I print argp out, it always shows 0. And I will get bus error trying to do DMA. :cry: However, if I hard code the address in SPU I get correct result no problem. Please help!

Thanks

OzzyBC42
08-Oct-2007, 08:19
Hard to say. Can you post the rest of the code?

jhhsia
09-Oct-2007, 06:15
PPU:

control_block cb __attribute__ ((aligned (128)));
int data[64] __attribute__ ((aligned (128)));

int main(){

unsigned int flag = 0;
unsigned int runflag = 0;
unsigned int entry = SPE_DEFAULT_ENTRY;
void* envp = 0;
spe_stop_info_t stop_info;

printf("Address being sent in control block: %p\n", data);
data[0] = 1; data[1] = 2; data[2] = 3;
cb.addr.p = data;
printf("Address being sent in control block: %p\n", cb.addr.p);
printf("Address being sent in control block: %p\n", (void*)&cb);

spe_program_handle_t* program = spe_image_open("spu_hello");
spe_context_ptr_t spe = spe_context_create(flag, NULL);

spe_program_load(spe, program);
/* run the SPE context */
if (spe_context_run(spe, &entry, 0, &cb, NULL, &stop_info) < 0) {
fprintf (stderr, "FAILED: spe_context_run(errno=%d )\n", errno);
exit (1);
}
spe_image_close(program);
spe_context_destroy(spe);
return (0);
}

SPU:
/* Here's the local copy of the control block, to be filled by the DMA */
control_block cb __attribute__ ((aligned (128)));

/* Here's the local copy of the data array, to be filled by the DMA */
int data[DATA_BUFFER_ENTRIES] __attribute__ ((aligned (128)));

int main( unsigned long long spuid, unsigned long long argp, unsigned long long envp)
{
printf("speid = 0x%llx\n", spuid);
printf("Address received through control block = 0x%llx\n", spuid);
argp = 0x10011780;
mfc_get(&cb, argp, sizeof(cb), 31, 0, 0);


mfc_write_tag_mask(1<<31);

/* Now, issue the read and wait to guarantee DMA completion before we continue. */
mfc_read_tag_status_all();

printf("Address received through control block = 0x%llx\n", cb.addr.ull);
/* DMA the data from system memory to our local store buffer. */
mfc_get(data, cb.addr.ull, DATA_BUFFER_SIZE, 31, 0, 0);

printf("data 0 %d \n",data[0]);
printf("data 1 %d \n",data[1]);
printf("data 2 %d \n",data[2]);
return (0);
}

Thanks.

OzzyBC42
09-Oct-2007, 09:43
Works fine for me (after commenting that "argp= 0x...", in the spu code of course) and using the 64-Bit Compiler.

You don't seem to check for thar last mfc_get line to finish, though, even that worked fine on my end.

You can try to read out the spe_stop_info_t struct, that should give you a clue.

But have to enable it first with

spe_context_ptr_t spe = spe_context_create(SPE_EVENTS_ENABLE, NULL);

You can check the returned Status(int) with

spe_stop_info_read(spe, &stop_info)

Vitaly Vidmirov
09-Oct-2007, 11:31
jhhsia

from SDK 2.0
This is known SDK 2.0 bug.

argp stored as LOW | HIGH
should be HIGH | LOW

So, you'll need to swap argp or just do
argp >>= 32;

Sousuke
09-Oct-2007, 12:04
I had the same problem but didn't find out what it was so I used a workaround with mbox.
So thats how to fix it ;) thanks Vitaly.

Filippo
09-Nov-2007, 12:13
Hi, Im experiencing a similiar problem to the above. I have just started on a project but cant the DMA transfer to work. Ill post the essential part of my code below:

PPU:

extern spe_program_handle_t rrt_spu;
typedef struct ppu_pthread_data {
spe_context_ptr_t spe_ctx;
pthread_t pthread;
unsigned int entry;
void *argp;
} ppu_pthread_data_t;

void intersect()
{
ppu_pthread_data_t ppuThreadData;
context ctx __attribute__ ((aligned (16)));

ctx._nU = 1;
ctx._nV = 2;
ctx._nD = 3;

if ((ppuThreadData.spe_ctx = spe_context_create (0, NULL)) == NULL)
{
perror ("Failed creating context");
exit (1);
}

if (spe_program_load (ppuThreadData.spe_ctx, &rrt_spu))
{
perror ("Failed loading program");
exit (1);
}

ppuThreadData.entry = SPE_DEFAULT_ENTRY;
ppuThreadData.argp = &ctx;

if (pthread_create (&ppuThreadData.pthread, NULL, &ppu_pthread_function, &ppuThreadData))
{
perror ("Failed creating thread");
exit (1);
}
}

if (pthread_join (ppuThreadData.pthread, NULL))
{
perror("Failed pthread_join");
exit (1);
}
}


SPE:

// LS structures
volatile context ctx;

int main(unsigned long long spe_id, unsigned long long parm)
{
unsigned int tag_id = mfc_tag_reserve();

spu_writech(MFC_WrTagMask, -1);

printf("spe p.2\n");

printf("speid = 0x%llx : ", spe_id);
printf("parm 0x%llx : ", parm);
printf("size cb %d : ", sizeof(context));
printf("tag id 0x%llx\n", tag_id);

spu_mfcdma32((void *)(&ctx), parm, sizeof(context), tag_id, MFC_GET_CMD);

printf("spe p.3\n");
(void)spu_mfcstat(MFC_TAG_UPDATE_ALL);

printf("spe p.4\n");

float nU = ctx._nU;
float nV = ctx._nV;
float nD = ctx._nD;
float uiProj = ctx._uiProj;

printf("spe p.5\n");

printf("%f %f %f %f \n", nU, nV, nD, uiProj);


(void)spu_mfcstat(MFC_TAG_UPDATE_ALL);

printf("spe p.6\n");
return 0;
}


In this case 'parm' is equal to zero and as I understood it should be the adress of the context? I also tried using a mailbox and send the value ppuThreadData.argp through the mailbox and then use this for the DMA call, Bot h cases give a a buss error.

How can I do it correctly? If i were to use mailbox, which value should I send?

Im using a PS3 with fedora 7 installed and the early release of the cell sdk 3.0

$>>uname -a
Linux ps3 2.6.23-rc3 #1 SMP Fri Aug 17 11:39:09 JST 2007 ppc64 ppc64 ppc64 GNU/Linux

If anyone could help me out I would be grateful

//Filip