Example #1
0
int main(uint64_t sync_ea, uint64_t response_ea, uint64_t arg3, uint64_t arg4) {
	/* get input value from ppu via signal notification register 1 (blocking read) */
	uint32_t x = spu_read_signal1();

	/* return the value multiplied by 3 to response variable with sync via dma */
	send_response(sync_ea, response_ea, x*3);
	wait_for_completion();

	/* properly exit the thread */
	spu_thread_exit(0);
	return 0;
}
Example #2
0
int main(uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) {
    /* get data structure */
    spu_ea = arg1;
    mfc_get(&spu, spu_ea, sizeof(spustr_t), TAG, 0, 0);
    wait_for_completion(TAG);

    /* main loop: wait for screen address or 0 to end */
    uint32_t buffer_ea;
    while ((buffer_ea = spu_read_signal1()) != 0) {
        mfc_get(&spu, spu_ea, sizeof(spustr_t), TAG, 0, 0);
        wait_for_completion(TAG);

        draw_frame(buffer_ea);
        send_response(1);
        wait_for_completion(TAG);
    }

    /* properly exit the thread */
    spu_thread_exit(0);
    return 0;
}
Example #3
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;
    }
}