View Full Version : Problem on spe_context_run
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?
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
vBulletin® v3.8.6, Copyright ©2000-2013, Jelsoft Enterprises Ltd.