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
00029
00030
00058 #define _ATFILE_SOURCE
00059
00060 #include "ctrump-libspe2.h"
00061 #include <stdint.h>
00062 #include <unistd.h>
00063 #include <string.h>
00064 #include <fcntl.h>
00065
00066 enum {
00067 COMMAND_NONE,
00068 COMMAND_RUN,
00069 COMMAND_QUIT
00070 };
00071
00072 struct ctrump_runtime_spe_context ctrump_runtime_spes[16];
00073 extern spe_program_handle_t ctrump_libspe2_boot;
00074 int ctrump_spe_num = 0;
00075
00076 static void *
00077 spe_thread(void *spe_ptr)
00078 {
00079 struct ctrump_runtime_spe_context *self = (struct ctrump_runtime_spe_context*)spe_ptr;
00080 spe_context_ptr_t spe = self->spe_context;
00081 unsigned int entry;
00082
00083 entry = SPE_DEFAULT_ENTRY;
00084 spe_program_load(spe, &ctrump_libspe2_boot);
00085 spe_context_run(spe, &entry, 0, 0, NULL, NULL);
00086
00087 return NULL;
00088 }
00089
00090 extern void __spe_context_update_event(void);
00091 void
00092 ctrump_runtime_spe_program_load(spe_context_ptr_t spe, const spe_program_handle_t *prog)
00093 {
00094 unsigned int mbox;
00095 int objfd;
00096 int i, n = ctrump_spe_num;
00097
00098 for (i=0; i<n; i++) {
00099 if (ctrump_runtime_spes[i].spe_context == spe)
00100 break;
00101 }
00102
00103 if (i == n)
00104 return;
00105
00106
00107
00108 if (ctrump_runtime_spes[i].enable_debugger) {
00109 objfd = openat(ctrump_runtime_spes[i].dir_fd, "object-id", O_RDWR);
00110 if (objfd >= 0) {
00111 char buf[100];
00112 sprintf(buf, "%p", prog->elf_image);
00113 write(objfd, buf, strlen(buf)+1);
00114 close(objfd);
00115 __spe_context_update_event();
00116 }
00117 }
00118
00119 mbox = (uint32_t)(uintptr_t)prog;
00120 spe_in_mbox_write(spe, &mbox, 1, SPE_MBOX_ALL_BLOCKING);
00121 mbox = ((uint64_t)(uintptr_t)prog)>>32;
00122 spe_in_mbox_write(spe, &mbox, 1, SPE_MBOX_ALL_BLOCKING);
00123
00124 }
00125
00126 void
00127 ctrump_runtime_spe_start(spe_context_ptr_t spe, void *param)
00128 {
00129 unsigned int mbox;
00130 mbox = (uint32_t)(uintptr_t)param;
00131 spe_in_mbox_write(spe, &mbox, 1, SPE_MBOX_ALL_BLOCKING);
00132 mbox = ((uint64_t)(uintptr_t)param)>>32;
00133 spe_in_mbox_write(spe, &mbox, 1, SPE_MBOX_ALL_BLOCKING);
00134 }
00135
00136 void
00137 ctrump_runtime_spe_wait(spe_context_ptr_t spe)
00138 {
00139 unsigned int data;
00140 spe_out_intr_mbox_read(spe, &data, 1, SPE_MBOX_ALL_BLOCKING);
00141 }
00142
00143 void
00144 ctrump_runtime_append_spe(spe_context_ptr_t spe, int enable_debugger)
00145 {
00146 int cur_spe = ctrump_spe_num;
00147 unsigned int mbox;
00148 char dir_buffer[256];
00149 int pid, dir_fd;
00150 struct ctrump_runtime_spe_context *s = &ctrump_runtime_spes[cur_spe];
00151
00152 pid = getpid();
00153 sprintf(dir_buffer, "/spu/spethread-%d-%lld", pid, (unsigned long long) (uintptr_t)spe);
00154 dir_fd = open(dir_buffer, O_RDONLY);
00155
00156 ctrump_spe_num = cur_spe+1;
00157
00158 s->spe_context = spe;
00159 s->dir_fd = dir_fd;
00160 s->enable_debugger = enable_debugger;
00161
00162 pthread_create(&s->thread, NULL, spe_thread, s);
00163 spe_out_intr_mbox_read(spe, &mbox, 1, SPE_MBOX_ALL_BLOCKING);
00164 }
00165
00166 void
00167 ctrump_runtime_remove_spe(spe_context_ptr_t spe)
00168 {
00169 int i;
00170 int n = ctrump_spe_num;
00171 unsigned int quit = 0xffffffffU;
00172
00173 for (i=0; i<n; i++) {
00174 if (ctrump_runtime_spes[i].spe_context == spe)
00175 break;
00176 }
00177
00178 if (i == n) {
00179
00180 return;
00181 }
00182
00183 ctrump_spe_num = n-1;
00184
00185 spe_in_mbox_write(spe, &quit, 1, SPE_MBOX_ALL_BLOCKING);
00186 pthread_join(ctrump_runtime_spes[i].thread, NULL);
00187 close(ctrump_runtime_spes[i].dir_fd);
00188 for (; i<n-1; i++) {
00189 ctrump_runtime_spes[i] = ctrump_runtime_spes[i+1];
00190 }
00191 }
00192
00193 void
00194 ctrump_runtime_initialize(int num_spe)
00195 {
00196 int i;
00197 for (i=0; i<num_spe; i++) {
00198 ctrump_runtime_append_spe(spe_context_create(SPE_MAP_PS,0), 1);
00199 }
00200 }
00201
00202 void
00203 ctrump_runtime_finalize(void)
00204 {
00205 while (ctrump_spe_num) {
00206 ctrump_runtime_remove_spe(ctrump_runtime_spes[0].spe_context);
00207 }
00208 }