#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
#include "create.h"
#include "mbox.h"
Go to the source code of this file.
Functions | |
int | _base_spe_out_mbox_read (spe_context_ptr_t spectx, unsigned int mbox_data[], int count) |
int | _base_spe_in_mbox_write (spe_context_ptr_t spectx, unsigned int *mbox_data, int count, int behavior_flag) |
int | _base_spe_in_mbox_status (spe_context_ptr_t spectx) |
int | _base_spe_out_mbox_status (spe_context_ptr_t spectx) |
int | _base_spe_out_intr_mbox_status (spe_context_ptr_t spectx) |
int | _base_spe_out_intr_mbox_read (spe_context_ptr_t spectx, unsigned int mbox_data[], int count, int behavior_flag) |
int | _base_spe_signal_write (spe_context_ptr_t spectx, unsigned int signal_reg, unsigned int data) |
int _base_spe_in_mbox_status | ( | spe_context_ptr_t | spectx | ) |
The _base_spe_in_mbox_status function fetches the status of the SPU inbound mailbox for the SPE thread specified by the speid parameter. A 0 value is return if the mailbox is full. A non-zero value specifies the number of available (32-bit) mailbox entries.
spectx | Specifies the SPE context whose mailbox status is to be read. |
Definition at line 202 of file mbox.c.
References _base_spe_open_if_closed(), spe_context::base_private, spe_context_base_priv::cntl_mmap_base, FD_WBOX_STAT, spe_context_base_priv::flags, SPE_MAP_PS, and spe_spu_control_area::SPU_Mbox_Stat.
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 }
int _base_spe_in_mbox_write | ( | spe_context_ptr_t | spectx, | |
unsigned int * | mbox_data, | |||
int | count, | |||
int | behavior_flag | |||
) |
Definition at line 112 of file mbox.c.
References _base_spe_open_if_closed(), spe_context::base_private, FD_WBOX, FD_WBOX_NB, spe_context_base_priv::flags, SPE_MAP_PS, SPE_MBOX_ALL_BLOCKING, SPE_MBOX_ANY_BLOCKING, and SPE_MBOX_ANY_NONBLOCKING.
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: // write all, even if 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) { // we could not write everything, wait for space 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: // write at least one, even if 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) { // we could not anything, wait for space 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: // only write, if non blocking 00175 total = rc = 0; 00176 // write directly if we map the PS else write via spufs 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 }
int _base_spe_out_intr_mbox_read | ( | spe_context_ptr_t | spectx, | |
unsigned int | mbox_data[], | |||
int | count, | |||
int | behavior_flag | |||
) |
The _base_spe_out_intr_mbox_read function reads the contents of the SPE outbound interrupting mailbox for the SPE context.
Definition at line 255 of file mbox.c.
References _base_spe_open_if_closed(), FD_IBOX, FD_IBOX_NB, SPE_MBOX_ALL_BLOCKING, SPE_MBOX_ANY_BLOCKING, and SPE_MBOX_ANY_NONBLOCKING.
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: // read all, even if 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: // read at least one, even if 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: // only reaad, if non blocking 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 }
int _base_spe_out_intr_mbox_status | ( | spe_context_ptr_t | spectx | ) |
The _base_spe_out_intr_mbox_status function fetches the status of the SPU outbound interrupt mailbox for the SPE thread specified by the speid parameter. A 0 value is return if the mailbox is empty. A non-zero value specifies the number of 32-bit unread mailbox entries.
spectx | Specifies the SPE context whose mailbox status is to be read. |
Definition at line 238 of file mbox.c.
References _base_spe_open_if_closed(), spe_context::base_private, spe_context_base_priv::cntl_mmap_base, FD_IBOX_STAT, spe_context_base_priv::flags, SPE_MAP_PS, and spe_spu_control_area::SPU_Mbox_Stat.
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 }
int _base_spe_out_mbox_read | ( | spe_context_ptr_t | spectx, | |
unsigned int | mbox_data[], | |||
int | count | |||
) |
The _base_spe_out_mbox_read function reads the contents of the SPE outbound interrupting mailbox for the SPE thread speid.
The call will not block until the read request is satisfied, but instead return up to count currently available mailbox entries.
spe_stat_out_intr_mbox can be called to ensure that data is available prior to reading the outbound interrupting mailbox.
spectx | Specifies the SPE thread whose outbound mailbox is to be read. | |
mbox_data | ||
count |
>0 | the number of 32-bit mailbox messages read | |
=0 | no data available | |
-1 | error condition and errno is set Possible values for errno: EINVAL speid is invalid Exxxx what else do we need here?? |
Definition at line 58 of file mbox.c.
References _base_spe_open_if_closed(), spe_context::base_private, DEBUG_PRINTF, FD_MBOX, spe_context_base_priv::flags, and SPE_MAP_PS.
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 ) { // no data ready to be read 00078 errno = 0; 00079 rc = 0; 00080 } 00081 } 00082 } 00083 return rc; 00084 }
int _base_spe_out_mbox_status | ( | spe_context_ptr_t | spectx | ) |
The _base_spe_out_mbox_status function fetches the status of the SPU outbound mailbox for the SPE thread specified by the speid parameter. A 0 value is return if the mailbox is empty. A non-zero value specifies the number of 32-bit unread mailbox entries.
spectx | Specifies the SPE context whose mailbox status is to be read. |
Definition at line 220 of file mbox.c.
References _base_spe_open_if_closed(), spe_context::base_private, spe_context_base_priv::cntl_mmap_base, FD_MBOX_STAT, spe_context_base_priv::flags, SPE_MAP_PS, and spe_spu_control_area::SPU_Mbox_Stat.
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 }
int _base_spe_signal_write | ( | spe_context_ptr_t | spectx, | |
unsigned int | signal_reg, | |||
unsigned int | data | |||
) |
The _base_spe_signal_write function writes data to the signal notification register specified by signal_reg for the SPE thread specified by the speid parameter.
spectx | Specifies the SPE context whose signal register is to be written to. | |
signal_reg | Specified the signal notification register to be written. Valid signal notification registers are: SPE_SIG_NOTIFY_REG_1 SPE signal notification register 1 SPE_SIG_NOTIFY_REG_2 SPE signal notification register 2 | |
data | The 32-bit data to be written to the specified signal notification register. |
Definition at line 307 of file mbox.c.
References _base_spe_close_if_open(), _base_spe_open_if_closed(), spe_context::base_private, FD_SIG1, FD_SIG2, spe_context_base_priv::flags, spe_context_base_priv::signal1_mmap_base, spe_context_base_priv::signal2_mmap_base, SPE_MAP_PS, SPE_SIG_NOTIFY_REG_1, SPE_SIG_NOTIFY_REG_2, spe_sig_notify_1_area::SPU_Sig_Notify_1, and spe_sig_notify_2_area::SPU_Sig_Notify_2.
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 }