00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <errno.h>
00021 #include <fcntl.h>
00022 #include <poll.h>
00023 #include <stdio.h>
00024 #include <unistd.h>
00025
00026 #include "create.h"
00027 #include "mbox.h"
00028
00034 static __inline__ int _base_spe_out_mbox_read_ps(spe_context_ptr_t spectx,
00035 unsigned int mbox_data[],
00036 int count)
00037 {
00038 volatile struct spe_spu_control_area *cntl_area =
00039 spectx->base_private->cntl_mmap_base;
00040 int total;
00041 int entries;
00042
00043 _base_spe_context_lock(spectx, FD_MBOX);
00044 total = 0;
00045 while (total < count) {
00046 entries = cntl_area->SPU_Mbox_Stat & 0xFF;
00047 if (entries == 0) break;
00048 if (entries > count - total) entries = count - total;
00049 while(entries--) {
00050 mbox_data[total] = cntl_area->SPU_Out_Mbox;
00051 total ++;
00052 }
00053 }
00054 _base_spe_context_unlock(spectx, FD_MBOX);
00055 return total;
00056 }
00057
00058 int _base_spe_out_mbox_read(spe_context_ptr_t spectx,
00059 unsigned int mbox_data[],
00060 int count)
00061 {
00062 int rc;
00063
00064 if (mbox_data == NULL || count < 1){
00065 errno = EINVAL;
00066 return -1;
00067 }
00068
00069 if (spectx->base_private->flags & SPE_MAP_PS) {
00070 rc = _base_spe_out_mbox_read_ps(spectx, mbox_data, count);
00071 } else {
00072 rc = read(_base_spe_open_if_closed(spectx,FD_MBOX, 0), mbox_data, count*4);
00073 DEBUG_PRINTF("%s read rc: %d\n", __FUNCTION__, rc);
00074 if (rc != -1) {
00075 rc /= 4;
00076 } else {
00077 if (errno == EAGAIN ) {
00078 errno = 0;
00079 rc = 0;
00080 }
00081 }
00082 }
00083 return rc;
00084 }
00085
00086 static __inline__ int _base_spe_in_mbox_write_ps(spe_context_ptr_t spectx,
00087 unsigned int *mbox_data,
00088 int count)
00089 {
00090 volatile struct spe_spu_control_area *cntl_area =
00091 spectx->base_private->cntl_mmap_base;
00092 int total = 0;
00093 unsigned int *aux;
00094 int space;
00095
00096 _base_spe_context_lock(spectx, FD_WBOX);
00097 aux = mbox_data;
00098 while (total < count) {
00099 space = (cntl_area->SPU_Mbox_Stat >> 8) & 0xFF;
00100 if (space == 0) break;
00101 if (space > count - total) space = count - total;
00102 while (space --) {
00103 cntl_area->SPU_In_Mbox = *aux++;
00104 total++;
00105 }
00106 }
00107 _base_spe_context_unlock(spectx, FD_WBOX);
00108
00109 return total;
00110 }
00111
00112 int _base_spe_in_mbox_write(spe_context_ptr_t spectx,
00113 unsigned int *mbox_data,
00114 int count,
00115 int behavior_flag)
00116 {
00117 int rc;
00118 int total;
00119 unsigned int *aux;
00120 struct pollfd fds;
00121
00122 if (mbox_data == NULL || count < 1){
00123 errno = EINVAL;
00124 return -1;
00125 }
00126
00127 switch (behavior_flag) {
00128 case SPE_MBOX_ALL_BLOCKING:
00129 total = rc = 0;
00130 if (spectx->base_private->flags & SPE_MAP_PS) {
00131 do {
00132 aux = mbox_data + total;
00133 total += _base_spe_in_mbox_write_ps(spectx, aux, count - total);
00134 if (total < count) {
00135 fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
00136 fds.events = POLLOUT;
00137 rc = poll(&fds, 1, -1);
00138 if (rc == -1 )
00139 return -1;
00140 }
00141 } while (total < count);
00142 } else {
00143 while (total < 4*count) {
00144 rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0),
00145 (const char *)mbox_data + total, 4*count - total);
00146 if (rc == -1) {
00147 break;
00148 }
00149 total += rc;
00150 }
00151 total /=4;
00152 }
00153 break;
00154
00155 case SPE_MBOX_ANY_BLOCKING:
00156 total = rc = 0;
00157 if (spectx->base_private->flags & SPE_MAP_PS) {
00158 do {
00159 total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
00160 if (total == 0) {
00161 fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
00162 fds.events = POLLOUT;
00163 rc = poll(&fds, 1, -1);
00164 if (rc == -1 )
00165 return -1;
00166 }
00167 } while (total == 0);
00168 } else {
00169 rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0), mbox_data, 4*count);
00170 total = rc/4;
00171 }
00172 break;
00173
00174 case SPE_MBOX_ANY_NONBLOCKING:
00175 total = rc = 0;
00176
00177 if (spectx->base_private->flags & SPE_MAP_PS) {
00178 total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
00179 } else {
00180 rc = write(_base_spe_open_if_closed(spectx,FD_WBOX_NB, 0), mbox_data, 4*count);
00181 if (rc == -1 && errno == EAGAIN) {
00182 rc = 0;
00183 errno = 0;
00184 }
00185 total = rc/4;
00186 }
00187 break;
00188
00189 default:
00190 errno = EINVAL;
00191 return -1;
00192 }
00193
00194 if (rc == -1) {
00195 errno = EIO;
00196 return -1;
00197 }
00198
00199 return total;
00200 }
00201
00202 int _base_spe_in_mbox_status(spe_context_ptr_t spectx)
00203 {
00204 int rc, ret;
00205 volatile struct spe_spu_control_area *cntl_area =
00206 spectx->base_private->cntl_mmap_base;
00207
00208 if (spectx->base_private->flags & SPE_MAP_PS) {
00209 ret = (cntl_area->SPU_Mbox_Stat >> 8) & 0xFF;
00210 } else {
00211 rc = read(_base_spe_open_if_closed(spectx,FD_WBOX_STAT, 0), &ret, 4);
00212 if (rc != 4)
00213 ret = -1;
00214 }
00215
00216 return ret;
00217
00218 }
00219
00220 int _base_spe_out_mbox_status(spe_context_ptr_t spectx)
00221 {
00222 int rc, ret;
00223 volatile struct spe_spu_control_area *cntl_area =
00224 spectx->base_private->cntl_mmap_base;
00225
00226 if (spectx->base_private->flags & SPE_MAP_PS) {
00227 ret = cntl_area->SPU_Mbox_Stat & 0xFF;
00228 } else {
00229 rc = read(_base_spe_open_if_closed(spectx,FD_MBOX_STAT, 0), &ret, 4);
00230 if (rc != 4)
00231 ret = -1;
00232 }
00233
00234 return ret;
00235
00236 }
00237
00238 int _base_spe_out_intr_mbox_status(spe_context_ptr_t spectx)
00239 {
00240 int rc, ret;
00241 volatile struct spe_spu_control_area *cntl_area =
00242 spectx->base_private->cntl_mmap_base;
00243
00244 if (spectx->base_private->flags & SPE_MAP_PS) {
00245 ret = (cntl_area->SPU_Mbox_Stat >> 16) & 0xFF;
00246 } else {
00247 rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_STAT, 0), &ret, 4);
00248 if (rc != 4)
00249 ret = -1;
00250
00251 }
00252 return ret;
00253 }
00254
00255 int _base_spe_out_intr_mbox_read(spe_context_ptr_t spectx,
00256 unsigned int mbox_data[],
00257 int count,
00258 int behavior_flag)
00259 {
00260 int rc;
00261 int total;
00262
00263 if (mbox_data == NULL || count < 1){
00264 errno = EINVAL;
00265 return -1;
00266 }
00267
00268 switch (behavior_flag) {
00269 case SPE_MBOX_ALL_BLOCKING:
00270 total = rc = 0;
00271 while (total < 4*count) {
00272 rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0),
00273 (char *)mbox_data + total, 4*count - total);
00274 if (rc == -1) {
00275 break;
00276 }
00277 total += rc;
00278 }
00279 break;
00280
00281 case SPE_MBOX_ANY_BLOCKING:
00282 total = rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0), mbox_data, 4*count);
00283 break;
00284
00285 case SPE_MBOX_ANY_NONBLOCKING:
00286 rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_NB, 0), mbox_data, 4*count);
00287 if (rc == -1 && errno == EAGAIN) {
00288 rc = 0;
00289 errno = 0;
00290 }
00291 total = rc;
00292 break;
00293
00294 default:
00295 errno = EINVAL;
00296 return -1;
00297 }
00298
00299 if (rc == -1) {
00300 errno = EIO;
00301 return -1;
00302 }
00303
00304 return rc / 4;
00305 }
00306
00307 int _base_spe_signal_write(spe_context_ptr_t spectx,
00308 unsigned int signal_reg,
00309 unsigned int data )
00310 {
00311 int rc;
00312
00313 if (spectx->base_private->flags & SPE_MAP_PS) {
00314 if (signal_reg == SPE_SIG_NOTIFY_REG_1) {
00315 spe_sig_notify_1_area_t *sig = spectx->base_private->signal1_mmap_base;
00316
00317 sig->SPU_Sig_Notify_1 = data;
00318 } else if (signal_reg == SPE_SIG_NOTIFY_REG_2) {
00319 spe_sig_notify_2_area_t *sig = spectx->base_private->signal2_mmap_base;
00320
00321 sig->SPU_Sig_Notify_2 = data;
00322 } else {
00323 errno = EINVAL;
00324 return -1;
00325 }
00326 rc = 0;
00327 } else {
00328 if (signal_reg == SPE_SIG_NOTIFY_REG_1)
00329 rc = write(_base_spe_open_if_closed(spectx,FD_SIG1, 0), &data, 4);
00330 else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
00331 rc = write(_base_spe_open_if_closed(spectx,FD_SIG2, 0), &data, 4);
00332 else {
00333 errno = EINVAL;
00334 return -1;
00335 }
00336
00337 if (rc == 4)
00338 rc = 0;
00339
00340 if (signal_reg == SPE_SIG_NOTIFY_REG_1)
00341 _base_spe_close_if_open(spectx,FD_SIG1);
00342 else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
00343 _base_spe_close_if_open(spectx,FD_SIG2);
00344 }
00345
00346 return rc;
00347 }
00348
00349
00350