cell_spu.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028 
00034 #include <pthread.h>
00035 
00036 #include "cell_spu.h"
00037 #include "pipe/p_format.h"
00038 #include "pipe/p_state.h"
00039 #include "cell/common.h"
00040 
00041 
00042 /*
00043 helpful headers:
00044 /opt/ibm/cell-sdk/prototype/src/include/ppu/cbe_mfc.h
00045 */
00046 
00047 
00051 struct cell_global_info cell_global;
00052 
00053 
00057 void
00058 send_mbox_message(spe_context_ptr_t ctx, unsigned int msg)
00059 {
00060    spe_in_mbox_write(ctx, &msg, 1, SPE_MBOX_ALL_BLOCKING);
00061 }
00062 
00063 
00067 uint
00068 wait_mbox_message(spe_context_ptr_t ctx)
00069 {
00070    do {
00071       unsigned data;
00072       int count = spe_out_mbox_read(ctx, &data, 1);
00073 
00074       if (count == 1) {
00075          return data;
00076       }
00077       
00078       if (count < 0) {
00079          /* error */ ;
00080       }
00081    } while (1);
00082 }
00083 
00084 
00088 static void *
00089 cell_thread_function(void *arg)
00090 {
00091    struct cell_init_info *init = (struct cell_init_info *) arg;
00092    unsigned entry = SPE_DEFAULT_ENTRY;
00093 
00094    ASSERT_ALIGN16(init);
00095 
00096    if (spe_context_run(cell_global.spe_contexts[init->id], &entry, 0,
00097                        init, NULL, NULL) < 0) {
00098       fprintf(stderr, "spe_context_run() failed\n");
00099       exit(1);
00100    }
00101 
00102    pthread_exit(NULL);
00103 }
00104 
00105 
00112 void
00113 cell_start_spus(struct cell_context *cell)
00114 {
00115    static boolean one_time_init = FALSE;
00116    uint i, j;
00117 
00118    if (one_time_init) {
00119       fprintf(stderr, "PPU: Multiple rendering contexts not yet supported "
00120               "on Cell.\n");
00121       abort();
00122    }
00123 
00124    one_time_init = TRUE;
00125 
00126    assert(cell->num_spus <= MAX_SPUS);
00127 
00128    ASSERT_ALIGN16(&cell_global.command[0]);
00129    ASSERT_ALIGN16(&cell_global.command[1]);
00130 
00131    ASSERT_ALIGN16(&cell_global.inits[0]);
00132    ASSERT_ALIGN16(&cell_global.inits[1]);
00133 
00134    for (i = 0; i < cell->num_spus; i++) {
00135       cell_global.inits[i].id = i;
00136       cell_global.inits[i].num_spus = cell->num_spus;
00137       cell_global.inits[i].debug_flags = cell->debug_flags;
00138       cell_global.inits[i].cmd = &cell_global.command[i];
00139       for (j = 0; j < CELL_NUM_BUFFERS; j++) {
00140          cell_global.inits[i].buffers[j] = cell->buffer[j];
00141       }
00142       cell_global.inits[i].buffer_status = &cell->buffer_status[0][0][0];
00143 
00144       cell_global.spe_contexts[i] = spe_context_create(0, NULL);
00145       if (!cell_global.spe_contexts[i]) {
00146          fprintf(stderr, "spe_context_create() failed\n");
00147          exit(1);
00148       }
00149 
00150       if (spe_program_load(cell_global.spe_contexts[i], &g3d_spu)) {
00151          fprintf(stderr, "spe_program_load() failed\n");
00152          exit(1);
00153       }
00154       
00155       pthread_create(&cell_global.spe_threads[i], /* returned thread handle */
00156                      NULL,                        /* pthread attribs */
00157                      &cell_thread_function,       /* start routine */
00158                      &cell_global.inits[i]);      /* thread argument */
00159    }
00160 }
00161 
00162 
00167 void
00168 cell_spu_exit(struct cell_context *cell)
00169 {
00170    uint i;
00171 
00172    for (i = 0; i < cell->num_spus; i++) {
00173       send_mbox_message(cell_global.spe_contexts[i], CELL_CMD_EXIT);
00174    }
00175 
00176    /* wait for threads to exit */
00177    for (i = 0; i < cell->num_spus; i++) {
00178       void *value;
00179       pthread_join(cell_global.spe_threads[i], &value);
00180       cell_global.spe_threads[i] = 0;
00181       cell_global.spe_contexts[i] = 0;
00182    }
00183 }

Generated on Tue Sep 29 06:25:15 2009 for Gallium3D by  doxygen 1.5.4