00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00044
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 ;
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],
00156 NULL,
00157 &cell_thread_function,
00158 &cell_global.inits[i]);
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
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 }