Esempio n. 1
0
/*
 * The argv argument will be populated with the address that the PPE provided,
 * from the 4th argument to spe_context_run()
 */
int main(uint64_t speid, uint64_t argv, uint64_t envp)
{
    struct spe_args args __attribute__((aligned(SPE_ALIGN)));

    mfc_get(&args, argv, sizeof(args), 0, 0, 0);

    mfc_write_tag_mask(1 << 0);
    mfc_read_tag_status_all();

    cmap_calls = 0;
    dma_puts = 0;
    spu_write_decrementer(-1);

    // Run multiple renders with offsets.  Should be factored into render_fractal()
    render_fractal(&args.fractal, args.thread_idx, args.n_threads, 0.);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta * 7 / 8);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta * 3 / 4);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta * 5 / 8);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta / 2);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta * 3 / 8);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta / 4);
    render_fractal(&args.fractal, args.thread_idx, args.n_threads,
                   args.fractal.delta / 8);

    // Send remaining points
    if(fill%2048) {
        // select the last buffer used
        int f = fill / 2048;
        mfc_put(&points[f*2048], (uint)args.fractal.pointbuf[f], 16384, 0, 0, 0);
        // Block for completion
        mfc_write_tag_mask(1<<0);
        mfc_read_tag_status_all();
        // Send a message with top bit set to indicate final item
        spu_write_out_intr_mbox((1<<31)|f);
        // Send another message indicating count
        spu_write_out_intr_mbox(fill%2048);
        ++dma_puts;
    }

    // Report some stats
    uint ticks = -1 - spu_read_decrementer();
    printf("cmap calls %d ticks %u calls/tick %f\n",
           cmap_calls, ticks, (double)cmap_calls/ticks );
    printf("dma puts %d\n", dma_puts);

    return 0;
}
Esempio n. 2
0
int main() {
	while (1){
		int res;
		ppu_addr_t program_data_ea = spu_read_in_mbox();
		program_data_ea += ((ppu_addr_t)spu_read_in_mbox())<<32;
		res = handleCommand( program_data_ea );
// 		spu_write_out_mbox( res );
		spu_write_out_intr_mbox( res );
	}
	return 0;
}
/* Sends a message to PPU that the current frame has been processed */
static void send_frame_done(ppu_data_t ppu_data, int frame_id) {
	uint32_t mbox_message = SPU_FRAME_DONE;

	while (spu_stat_out_intr_mbox() <= 0)
		;
	spu_write_out_intr_mbox(mbox_message);
	dprintf("SPU[%d]: Finished frame %d. Informed PPU\n",
		ppu_data.spe_id, frame_id + 1);
	/* Suppress warnings of unused */
	ppu_data.spe_id = ppu_data.spe_id;
	frame_id = frame_id;
}
Esempio n. 4
0
int main(uint64_t speid, uint64_t argp, uint64_t envp){
	unsigned int data[NUM_STREAMS];
	unsigned int num_spus = (unsigned int)argp, i, num_images;
	struct image my_image __attribute__ ((aligned(16)));
	int mode = (int)envp;

	speid = speid; //get rid of warning

	while(1){
		num_images = 0;
		for (i = 0; i < NUM_STREAMS / num_spus; i++){
			//assume NUM_STREAMS is a multiple of num_spus
			while(spu_stat_in_mbox() == 0);
			data[i] = spu_read_in_mbox();
			if (!data[i])
				return 0;
			num_images++;
		}

		for (i = 0; i < num_images; i++){
			mfc_get(&my_image, data[i], sizeof(struct image), MY_TAG, 0, 0);
			mfc_write_tag_mask(1 << MY_TAG);
			mfc_read_tag_status_all();
			switch(mode){
				default:
				case MODE_SIMPLE:
					process_image_simple(&my_image);
					break;
				case MODE_2LINES:
					process_image_2lines(&my_image);
					break;
				case MODE_DOUBLE:
					process_image_double(&my_image);
					break;
				case MODE_DMALIST:
					process_image_dmalist(&my_image);
					break;
			}
		}	
		data[0] = DONE;
		spu_write_out_intr_mbox(data[0]);	
	}

	return 0;
}
Esempio n. 5
0
int
main (unsigned long long speid, unsigned long long argp,
      unsigned long long envp)
{
  /* Signal to PPU side that it should fork now.  */
  spu_write_out_intr_mbox (0);

  /* Wait until fork completed.  */
  spu_read_in_mbox ();

  /* Trigger watchpoint.  */
  var = 1;

  /* Now call some function to trigger breakpoint.  */
  func ();

  return 0;
}
Esempio n. 6
0
void
terminal_func ()
{
  spu_write_out_intr_mbox (0);
  spu_read_in_mbox ();
}
Esempio n. 7
0
/*
 * Colour the given framebuffer address pix.
 * i and params may be used to select the colour.
 */
static void write_colour(struct pixel *pix, float i,
                         struct fractal_params *params)
{
    // Mask for keeping track of ppe finishing with buffers
    static int valid = 0xff;
    static vector unsigned int sentinel = {1,0,0,0};

    ++cmap_calls;

    uint colour;

    // Various colouring alternatives are possible here

    // ignore the first few steps - reduces backgroud noise
    if(i<20) return;

    /*	if(i==0) return;
    	if(params->i_max < 10000) {
    		colour = 0x00010000;
    	} else if(params->i_max < 20000) {
    		if(i<10000) return;
    		colour = 0x00000200;
    	} else {
    		if(i<20000) return;
    		colour = 0x00000004;
    	}*/

    colour = 0x00010100;

    // If starting to fill a new buffer, check that any earlier use
    // is finished with - ppe signals completion
    if(fill%2048 == 0) {
        while(!(valid&(1<<(fill/2048)))) {
            valid |= spu_read_signal1();
        }
    }

    // set values
    points[fill].addr = (uint*)pix;
    points[fill].i = colour;
    ++fill;

    // if we just filled a buffer, send it to ppe
    if(fill%2048==0) {
        // select the specific buffer that is full
        int f = (fill / 2048) - 1;
        mfc_put(&points[f*2048], (uint)params->pointbuf[f], 16384, 0, 0, 0);
        // fence a sentinel - the ppe will spin on this completing...
        // What's a better way to achieve sync?
        mfc_putf(&sentinel, (uint)params->sentinel[f], 16, 0, 0, 0);
        // interrupt the ppe
        spu_write_out_intr_mbox(f);
        // unmask the relevant bit
        valid&=~(1<<f);

        if(fill==16384) {
            fill = 0;
        }
        ++dma_puts;
    }
}
Esempio n. 8
0
void work(param_t param)
{
printf("SPU[%u] work()\n", param.proc);
	unsigned int inbox, offset;
    unsigned int *in = malloc_align(param.bitset_size, ALIGN_EXP);
    unsigned int *out = malloc_align(param.bitset_size, ALIGN_EXP);
    unsigned int *use = malloc_align(param.bitset_size, ALIGN_EXP);
    unsigned int *def = malloc_align(param.bitset_size, ALIGN_EXP);
    if(in == NULL || out == NULL || use == NULL || def == NULL) {
	    printf("malloc_align() failed\n");
	    exit(1);
    }
    unsigned tag_1, tag_2, tag_3, tag_4;
    unsigned int tag_id;   
    /* Reserve a tag for application usage */ 
    if ((tag_1 = mfc_tag_reserve()) == MFC_TAG_INVALID) 
    {
        printf("ERROR: unable to reserve a tag_1\n"); 
    }
    if ((tag_2 = mfc_tag_reserve()) == MFC_TAG_INVALID) 
    {
        printf("ERROR: unable to reserve a tag_2\n"); 
    }
    if ((tag_3 = mfc_tag_reserve()) == MFC_TAG_INVALID) 
    {
        printf("ERROR: unable to reserve a tag_3\n"); 
    }
    if ((tag_4 = mfc_tag_reserve()) == MFC_TAG_INVALID) 
    {
        printf("ERROR: unable to reserve a tag_4\n");
    } 

	while(1) {
		inbox = spu_read_in_mbox();

        if(inbox == UINT_MAX)
        {
            printf("SPU[%u] received exit signal.. exiting.\n", param.proc);
            return;
        }
		
		offset = param.bitset_subsets*inbox;

		mfc_get(in,  (unsigned int) (param.bs_in_addr  + offset), param.bitset_size, tag_1, 0, 0);
		mfc_get(out, (unsigned int) (param.bs_out_addr + offset), param.bitset_size, tag_2, 0, 0);
		mfc_get(use, (unsigned int) (param.bs_use_addr + offset), param.bitset_size, tag_3, 0, 0);
		mfc_get(def, (unsigned int) (param.bs_def_addr + offset), param.bitset_size, tag_4, 0, 0);
		mfc_write_tag_mask(1 << tag_1 | 1 << tag_2 | 1 << tag_3 | 1 << tag_4);
		mfc_read_tag_status_all();

D(printf("SPU[%d] index: %u  bitset_subsets: %u  offset: %u\n", param.proc, inbox, param.bitset_subsets, offset);
printf("SPU[%d]\t&use: %p\n\t&def: %p\n\t&out: %p\n\t&in:  %p\n", param.proc, (void*)param.bs_use_addr, (void*)param.bs_def_addr, (void*)param.bs_out_addr, (void*)param.bs_in_addr);
void *tmp_ptr = (void*) (param.bs_use_addr  + offset);
printf("SPU[%d] read\t\t&%p = use(%p)={", param.proc, (void*)use, tmp_ptr);
	for (int i = 0; i < 100; ++i){
	if ( bitset_get_bit(use, i) ) {
			printf("%d ", i);
		}
	}
printf("}\n");
tmp_ptr = (void*) (param.bs_def_addr  + offset);
printf("SPU[%d] read\t\t&%p = def(%p)={", param.proc, (void*)def, tmp_ptr);
	for (int i = 0; i < 100; ++i){
	if ( bitset_get_bit(def, i) ) {
			printf("%d ", i);
		}
	}
printf("}\n");
tmp_ptr = (void*) (param.bs_out_addr  + offset);
printf("SPU[%d] read\t\t&%p = out(%p)={", param.proc, (void*)out, tmp_ptr);
	for (int i = 0; i < 100; ++i){
	if ( bitset_get_bit(out, i) ) {
			printf("%d ", i);
		}
	}
printf("}\n");
tmp_ptr = (void*) (param.bs_in_addr  + offset);
printf("SPU[%d] read\t\t&%p = in (%p)={", param.proc, (void*)in, tmp_ptr);
	for (int i = 0; i < 100; ++i){
	if ( bitset_get_bit(in, i) ) {
			printf("%d ", i);
		}
	}
printf("}\n"));
		bitset_megaop(param, in, out, use, def);		

D(printf("SPU[%d] calculated\tin={", param.proc);
	for (int i = 0; i < 100; ++i){
	if ( bitset_get_bit(in, i) ) {
			printf("%d ", i);
		}
	}
printf("}\n");)

		mfc_put(in, (unsigned int)  (param.bs_in_addr  +  offset), param.bitset_size, tag_1, 0, 0);
		mfc_write_tag_mask(1 << tag_1);
		mfc_read_tag_status_all();

		spu_write_out_intr_mbox(inbox);
	}