mbox.c File Reference
`#include <errno.h>`
`#include <fcntl.h>`
`#include <poll.h>`
`#include <stdio.h>`
`#include <unistd.h>`
`#include "create.h"`
`#include "mbox.h"`
Include dependency graph for mbox.c:

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)

## Function Documentation

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.

Parameters

  spectx | Specifies the SPE context whose mailbox status is to be read.

Returns
  On success, returns the current status of the mailbox, respectively. On failure, -1 is returned.

See Also
  spe_read_out_mbox, spe_write_in_mbox, read (2)

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.

{
int rc, ret;
volatile struct spe_spu_control_area *cntl_area =
spectx->base_private->cntl_mmap_base;
if (spectx->base_private->flags & SPE_MAP_PS) {
ret = (cntl_area->SPU_Mbox_Stat >> 8) & 0xFF;
} else {
rc = read(_base_spe_open_if_closed(spectx,FD_WBOX_STAT, 0), &ret, 4);
if (rc != 4)
ret = -1;
}
return ret;
}

Here is the call graph for this function:

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.

{
int rc;
int total;
unsigned int *aux;
struct pollfd fds;
if (mbox_data == NULL || count < 1){
errno = EINVAL;
return -1;
}
switch (behavior_flag) {
case SPE_MBOX_ALL_BLOCKING: // write all, even if blocking
total = rc = 0;
if (spectx->base_private->flags & SPE_MAP_PS) {
do {
aux = mbox_data + total;
total += _base_spe_in_mbox_write_ps(spectx, aux, count - total);
if (total < count) { // we could not write everything, wait for space
fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
fds.events = POLLOUT;
rc = poll(&fds, 1, -1);
if (rc == -1 )
return -1;
}
} while (total < count);
} else {
while (total < 4*count) {
rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0),
(const char *)mbox_data + total, 4*count - total);
if (rc == -1) {
break;
}
total += rc;
}
total /=4;
}
break;
case SPE_MBOX_ANY_BLOCKING: // write at least one, even if blocking
total = rc = 0;
if (spectx->base_private->flags & SPE_MAP_PS) {
do {
total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
if (total == 0) { // we could not anything, wait for space
fds.fd = _base_spe_open_if_closed(spectx, FD_WBOX, 0);
fds.events = POLLOUT;
rc = poll(&fds, 1, -1);
if (rc == -1 )
return -1;
}
} while (total == 0);
} else {
rc = write(_base_spe_open_if_closed(spectx,FD_WBOX, 0), mbox_data, 4*count);
total = rc/4;
}
break;
case SPE_MBOX_ANY_NONBLOCKING: // only write, if non blocking
total = rc = 0;
// write directly if we map the PS else write via spufs
if (spectx->base_private->flags & SPE_MAP_PS) {
total = _base_spe_in_mbox_write_ps(spectx, mbox_data, count);
} else {
rc = write(_base_spe_open_if_closed(spectx,FD_WBOX_NB, 0), mbox_data, 4*count);
if (rc == -1 && errno == EAGAIN) {
rc = 0;
errno = 0;
}
total = rc/4;
}
break;
default:
errno = EINVAL;
return -1;
}
if (rc == -1) {
errno = EIO;
return -1;
}
return total;
}

Here is the call graph for this function:

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.

{
int rc;
int total;
if (mbox_data == NULL || count < 1){
errno = EINVAL;
return -1;
}
switch (behavior_flag) {
case SPE_MBOX_ALL_BLOCKING: // read all, even if blocking
total = rc = 0;
while (total < 4*count) {
rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0),
(char *)mbox_data + total, 4*count - total);
if (rc == -1) {
break;
}
total += rc;
}
break;
case SPE_MBOX_ANY_BLOCKING: // read at least one, even if blocking
total = rc = read(_base_spe_open_if_closed(spectx,FD_IBOX, 0), mbox_data, 4*count);
break;
case SPE_MBOX_ANY_NONBLOCKING: // only reaad, if non blocking
rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_NB, 0), mbox_data, 4*count);
if (rc == -1 && errno == EAGAIN) {
rc = 0;
errno = 0;
}
total = rc;
break;
default:
errno = EINVAL;
return -1;
}
if (rc == -1) {
errno = EIO;
return -1;
}
return rc / 4;
}

Here is the call graph for this function:

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.

Parameters

  spectx | Specifies the SPE context whose mailbox status is to be read.

Returns
  On success, returns the current status of the mailbox, respectively. On failure, -1 is returned.

See Also
  spe_read_out_mbox, spe_write_in_mbox, read (2)

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.

{
int rc, ret;
volatile struct spe_spu_control_area *cntl_area =
spectx->base_private->cntl_mmap_base;
if (spectx->base_private->flags & SPE_MAP_PS) {
ret = (cntl_area->SPU_Mbox_Stat >> 16) & 0xFF;
} else {
rc = read(_base_spe_open_if_closed(spectx,FD_IBOX_STAT, 0), &ret, 4);
if (rc != 4)
ret = -1;
}
return ret;
}

Here is the call graph for this function:

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.

Parameters

  spectx | Specifies the SPE thread whose outbound mailbox is to be read.
  mbox_data |
  count |

Return values

  >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.

{
int rc;
if (mbox_data == NULL || count < 1){
errno = EINVAL;
return -1;
}
if (spectx->base_private->flags & SPE_MAP_PS) {
rc = _base_spe_out_mbox_read_ps(spectx, mbox_data, count);
} else {
rc = read(_base_spe_open_if_closed(spectx,FD_MBOX, 0), mbox_data, count*4);
DEBUG_PRINTF("%s read rc: %d\n", __FUNCTION__, rc);
if (rc != -1) {
rc /= 4;
} else {
if (errno == EAGAIN ) { // no data ready to be read
errno = 0;
rc = 0;
}
}
}
return rc;
}

Here is the call graph for this function:

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.

Parameters

  spectx | Specifies the SPE context whose mailbox status is to be read.

Returns
  On success, returns the current status of the mailbox, respectively. On failure, -1 is returned.

See Also
  spe_read_out_mbox, spe_write_in_mbox, read (2)

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.

{
int rc, ret;
volatile struct spe_spu_control_area *cntl_area =
spectx->base_private->cntl_mmap_base;
if (spectx->base_private->flags & SPE_MAP_PS) {
ret = cntl_area->SPU_Mbox_Stat & 0xFF;
} else {
rc = read(_base_spe_open_if_closed(spectx,FD_MBOX_STAT, 0), &ret, 4);
if (rc != 4)
ret = -1;
}
return ret;
}

Here is the call graph for this function:

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.

Parameters

  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.

Returns
  On success, spe_write_signal returns 0. On failure, -1 is returned.

See Also
  spe_get_ps_area, spe_write_in_mbox

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.

{
int rc;
if (spectx->base_private->flags & SPE_MAP_PS) {
if (signal_reg == SPE_SIG_NOTIFY_REG_1) {
spe_sig_notify_1_area_t *sig = spectx->base_private->signal1_mmap_base;
sig->SPU_Sig_Notify_1 = data;
} else if (signal_reg == SPE_SIG_NOTIFY_REG_2) {
spe_sig_notify_2_area_t *sig = spectx->base_private->signal2_mmap_base;
sig->SPU_Sig_Notify_2 = data;
} else {
errno = EINVAL;
return -1;
}
rc = 0;
} else {
if (signal_reg == SPE_SIG_NOTIFY_REG_1)
rc = write(_base_spe_open_if_closed(spectx,FD_SIG1, 0), &data, 4);
else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
rc = write(_base_spe_open_if_closed(spectx,FD_SIG2, 0), &data, 4);
else {
errno = EINVAL;
return -1;
}
if (rc == 4)
rc = 0;
if (signal_reg == SPE_SIG_NOTIFY_REG_1)
_base_spe_close_if_open(spectx,FD_SIG1);
else if (signal_reg == SPE_SIG_NOTIFY_REG_2)
_base_spe_close_if_open(spectx,FD_SIG2);
}
return rc;
}

Here is the call graph for this function: