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; }
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; }
/* * 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; } }