spebase.h File Reference
`#include <pthread.h>`
`#include "libspe2-types.h"`
Include dependency graph for spebase.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

## Data Structures

struct | spe_context_base_priv
struct | spe_gang_context_base_priv

## Macros

#define | __PRINTF(fmt, args...) { fprintf(stderr,fmt , ## args); }
#define | DEBUG_PRINTF(fmt, args...)
#define | LS_SIZE 0x40000 /* 256K (in bytes) */
#define | PSMAP_SIZE 0x20000 /* 128K (in bytes) */
#define | MFC_SIZE 0x1000
#define | MSS_SIZE 0x1000
#define | CNTL_SIZE 0x1000
#define | SIGNAL_SIZE 0x1000
#define | MSSYNC_OFFSET 0x00000
#define | MFC_OFFSET 0x03000
#define | CNTL_OFFSET 0x04000
#define | SIGNAL1_OFFSET 0x14000
#define | SIGNAL2_OFFSET 0x1c000
#define | SPE_EMULATE_PARAM_BUFFER 0x3e000
#define | SPE_PROGRAM_NORMAL_END 0x2000
#define | SPE_PROGRAM_LIBRARY_CALL 0x2100
#define | SPE_PROGRAM_ISOLATED_STOP 0x2200
#define | SPE_PROGRAM_ISO_LOAD_COMPLETE 0x2206

## Enumerations

enum | fd_name { FD_MBOX, FD_MBOX_STAT, FD_IBOX, FD_IBOX_NB, FD_IBOX_STAT, FD_WBOX, FD_WBOX_NB, FD_WBOX_STAT, FD_SIG1, FD_SIG2, FD_MFC, FD_MSS, NUM_MBOX_FDS }

## Functions

spe_context_ptr_t | _base_spe_context_create (unsigned int flags, spe_gang_context_ptr_t gctx, spe_context_ptr_t aff_spe)
spe_gang_context_ptr_t | _base_spe_gang_context_create (unsigned int flags)
int | _base_spe_program_load (spe_context_ptr_t spectx, spe_program_handle_t *program)
void | _base_spe_program_load_complete (spe_context_ptr_t spectx)
int | _base_spe_emulated_loader_present (void)
int | _base_spe_context_destroy (spe_context_ptr_t spectx)
int | _base_spe_gang_context_destroy (spe_gang_context_ptr_t gctx)
int | _base_spe_context_run (spe_context_ptr_t spe, unsigned int *entry, unsigned int runflags, void *argp, void *envp, spe_stop_info_t *stopinfo)
int | _base_spe_image_close (spe_program_handle_t *handle)
spe_program_handle_t * | _base_spe_image_open (const char *filename)
int | _base_spe_mfcio_put (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int | _base_spe_mfcio_putb (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int | _base_spe_mfcio_putf (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int | _base_spe_mfcio_get (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int | _base_spe_mfcio_getb (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
int | _base_spe_mfcio_getf (spe_context_ptr_t spectx, unsigned int ls, void *ea, unsigned int size, unsigned int tag, unsigned int tid, unsigned int rid)
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_callback_handler_register (void *handler, unsigned int callnum, unsigned int mode)
int | _base_spe_callback_handler_deregister (unsigned int callnum)
void * | _base_spe_callback_handler_query (unsigned int callnum)
int | _base_spe_stop_reason_get (spe_context_ptr_t spectx)
int | _base_spe_mfcio_tag_status_read (spe_context_ptr_t spectx, unsigned int mask, unsigned int behavior, unsigned int *tag_status)
int | __base_spe_stop_event_source_get (spe_context_ptr_t spectx)
int | __base_spe_stop_event_target_get (spe_context_ptr_t spectx)
int | _base_spe_stop_status_get (spe_context_ptr_t spectx)
int | __base_spe_event_source_acquire (struct spe_context *spectx, enum fd_name fdesc)
void | __base_spe_event_source_release (struct spe_context *spectx, enum fd_name fdesc)
void * | _base_spe_ps_area_get (struct spe_context *spectx, enum ps_area area)
int | __base_spe_spe_dir_get (struct spe_context *spectx)
void * | _base_spe_ls_area_get (struct spe_context *spectx)
int | _base_spe_ls_size_get (spe_context_ptr_t spe)
void | _base_spe_context_lock (spe_context_ptr_t spe, enum fd_name fd)
void | _base_spe_context_unlock (spe_context_ptr_t spe, enum fd_name fd)
int | _base_spe_cpu_info_get (int info_requested, int cpu_node)
void | __spe_context_update_event (void)
int | _base_spe_mssync_start (spe_context_ptr_t spectx)
int | _base_spe_mssync_status (spe_context_ptr_t spectx)

## Detailed Description

spebase.h contains the public API funtions

Definition in file spebase.h.

## Macro Definition Documentation

#define __PRINTF | ( |  | fmt,
|  |  | args...
| ) |  | { fprintf(stderr,fmt , ## args); }

Definition at line 34 of file spebase.h.

#define CNTL_OFFSET 0x04000

Definition at line 124 of file spebase.h.

Referenced by _base_spe_context_create().

#define CNTL_SIZE 0x1000

Definition at line 119 of file spebase.h.

Referenced by _base_spe_context_create().

#define DEBUG_PRINTF | ( |  | fmt,
|  |  | args...
| ) |  |

Definition at line 38 of file spebase.h.

#define LS_SIZE 0x40000 /* 256K (in bytes) */

Definition at line 115 of file spebase.h.

#define MFC_OFFSET 0x03000

Definition at line 123 of file spebase.h.

Referenced by _base_spe_context_create().

#define MFC_SIZE 0x1000

Definition at line 117 of file spebase.h.

Referenced by _base_spe_context_create().

#define MSS_SIZE 0x1000

Definition at line 118 of file spebase.h.

Referenced by _base_spe_context_create().

#define MSSYNC_OFFSET 0x00000

Definition at line 122 of file spebase.h.

Referenced by _base_spe_context_create().

#define PSMAP_SIZE 0x20000 /* 128K (in bytes) */

Definition at line 116 of file spebase.h.

Referenced by _base_spe_context_create().

#define SIGNAL1_OFFSET 0x14000

Definition at line 125 of file spebase.h.

Referenced by _base_spe_context_create().

#define SIGNAL2_OFFSET 0x1c000

Definition at line 126 of file spebase.h.

Referenced by _base_spe_context_create().

#define SIGNAL_SIZE 0x1000

Definition at line 120 of file spebase.h.

Referenced by _base_spe_context_create().

#define SPE_EMULATE_PARAM_BUFFER 0x3e000

Location of the PPE-assisted library call buffer for emulated isolation contexts.

Definition at line 132 of file spebase.h.

Referenced by _base_spe_handle_library_callback().

#define SPE_PROGRAM_ISO_LOAD_COMPLETE 0x2206

Definition at line 143 of file spebase.h.

Referenced by _base_spe_context_run().

#define SPE_PROGRAM_ISOLATED_STOP 0x2200

Isolated exit codes: 0x220x

Definition at line 142 of file spebase.h.

Referenced by _base_spe_context_run().

#define SPE_PROGRAM_LIBRARY_CALL 0x2100

Definition at line 137 of file spebase.h.

Referenced by _base_spe_context_run().

#define SPE_PROGRAM_NORMAL_END 0x2000

Definition at line 136 of file spebase.h.

Referenced by _base_spe_context_run().

## Enumeration Type Documentation

enum fd_name

NOTE: NUM_MBOX_FDS must always be the last element in the enumeration

Enumerator
FD_MBOX |
FD_MBOX_STAT |
FD_IBOX |
FD_IBOX_NB |
FD_IBOX_STAT |
FD_WBOX |
FD_WBOX_NB |
FD_WBOX_STAT |
FD_SIG1 |
FD_SIG2 |
FD_MFC |
FD_MSS |
NUM_MBOX_FDS |

Definition at line 42 of file spebase.h.

{
FD_MBOX,
FD_MBOX_STAT,
FD_IBOX,
FD_IBOX_NB,
FD_IBOX_STAT,
FD_WBOX,
FD_WBOX_NB,
FD_WBOX_STAT,
FD_SIG1,
FD_SIG2,
FD_MFC,
FD_MSS,
NUM_MBOX_FDS
};

## Function Documentation

int __base_spe_event_source_acquire | ( | struct spe_context * | spectx,
|  | enum fd_name | fdesc
| ) |  |

__base_spe_event_source_acquire opens a file descriptor to the specified event source

Parameters

  spectx | Specifies the SPE context
  fdesc | Specifies the event source

void __base_spe_event_source_release | ( | struct spe_context * | spectx,
|  | enum fd_name | fdesc
| ) |  |

__base_spe_event_source_release releases the file descriptor to the specified event source

Parameters

  spectx | Specifies the SPE context
  fdesc | Specifies the event source

Definition at line 79 of file accessors.c.

References _base_spe_close_if_open().

{
_base_spe_close_if_open(spe, fdesc);
}

Here is the call graph for this function:

int __base_spe_spe_dir_get | ( | struct spe_context * | spectx) |  |

__base_spe_spe_dir_get return the file descriptor of the SPE directory in spufs

Parameters

  spectx | Specifies the SPE context

int __base_spe_stop_event_source_get | ( | spe_context_ptr_t | spe) |  |

__base_spe_stop_event_source_get

Parameters

  spectx | Specifies the SPE context

speevent users read from this end

Definition at line 92 of file accessors.c.

References spe_context::base_private, and spe_context_base_priv::ev_pipe.

{
return spe->base_private->ev_pipe[1];
}

int __base_spe_stop_event_target_get | ( | spe_context_ptr_t | spe) |  |

__base_spe_stop_event_target_get

Parameters

  spectx | Specifies the SPE context

speevent writes to this end

Definition at line 100 of file accessors.c.

References spe_context::base_private, and spe_context_base_priv::ev_pipe.

{
return spe->base_private->ev_pipe[0];
}

void __spe_context_update_event | ( | void | ) |  |

__spe_context_update_event internal function for gdb notification.

Referenced by _base_spe_context_destroy(), and _base_spe_program_load_complete().

int _base_spe_callback_handler_deregister | ( | unsigned int | callnum) |  |

unregister a handler function for the specified number NOTE: unregistering a handler from call zero and one is ignored.

Definition at line 78 of file lib_builtin.c.

References MAX_CALLNUM, and RESERVED.

{
errno = 0;
if (callnum > MAX_CALLNUM) {
errno = EINVAL;
return -1;
}
if (callnum < RESERVED) {
errno = EACCES;
return -1;
}
if (handlers[callnum] == NULL) {
errno = ESRCH;
return -1;
}
handlers[callnum] = NULL;
return 0;
}

void* _base_spe_callback_handler_query | ( | unsigned int | callnum) |  |

query a handler function for the specified number

Definition at line 98 of file lib_builtin.c.

References MAX_CALLNUM.

{
errno = 0;
if (callnum > MAX_CALLNUM) {
errno = EINVAL;
return NULL;
}
if (handlers[callnum] == NULL) {
errno = ESRCH;
return NULL;
}
return handlers[callnum];
}

int _base_spe_callback_handler_register | ( | void * | handler,
|  | unsigned int | callnum,
|  | unsigned int | mode
| ) |  |

register a handler function for the specified number NOTE: registering a handler to call zero and one is ignored.

Definition at line 40 of file lib_builtin.c.

References MAX_CALLNUM, RESERVED, SPE_CALLBACK_NEW, and SPE_CALLBACK_UPDATE.

{
errno = 0;
if (callnum > MAX_CALLNUM) {
errno = EINVAL;
return -1;
}
switch(mode){
case SPE_CALLBACK_NEW:
if (callnum < RESERVED) {
errno = EACCES;
return -1;
}
if (handlers[callnum] != NULL) {
errno = EACCES;
return -1;
}
handlers[callnum] = handler;
break;
case SPE_CALLBACK_UPDATE:
if (handlers[callnum] == NULL) {
errno = ESRCH;
return -1;
}
handlers[callnum] = handler;
break;
default:
errno = EINVAL;
return -1;
break;
}
return 0;
}

spe_context_ptr_t _base_spe_context_create | ( | unsigned int | flags,
|  | spe_gang_context_ptr_t | gctx,
|  | spe_context_ptr_t | aff_spe
| ) |  |

_base_spe_context_create creates a single SPE context, i.e., the corresponding directory is created in SPUFS either as a subdirectory of a gang or individually (maybe this is best considered a gang of one)

Parameters

  flags |
  gctx | specify NULL if not belonging to a gang
  aff_spe | specify NULL to skip affinity information

Definition at line 183 of file create.c.

References _base_spe_emulated_loader_present(), spe_context::base_private, spe_gang_context::base_private, spe_context_base_priv::cntl_mmap_base, CNTL_OFFSET, CNTL_SIZE, DEBUG_PRINTF, spe_context_base_priv::fd_lock, spe_context_base_priv::fd_spe_dir, spe_context_base_priv::flags, spe_gang_context_base_priv::gangname, spe_context_base_priv::loaded_program, LS_SIZE, spe_context_base_priv::mem_mmap_base, spe_context_base_priv::mfc_mmap_base, MFC_OFFSET, MFC_SIZE, MSS_SIZE, spe_context_base_priv::mssync_mmap_base, MSSYNC_OFFSET, NUM_MBOX_FDS, spe_context_base_priv::psmap_mmap_base, PSMAP_SIZE, spe_context_base_priv::signal1_mmap_base, SIGNAL1_OFFSET, spe_context_base_priv::signal2_mmap_base, SIGNAL2_OFFSET, SIGNAL_SIZE, SPE_AFFINITY_MEMORY, SPE_CFG_SIGNOTIFY1_OR, SPE_CFG_SIGNOTIFY2_OR, SPE_EVENTS_ENABLE, spe_context_base_priv::spe_fds_array, SPE_ISOLATE, SPE_ISOLATE_EMULATE, and SPE_MAP_PS.

{
char pathname[256];
int i, aff_spe_fd = 0;
unsigned int spu_createflags = 0;
struct spe_context *spe = NULL;
struct spe_context_base_priv *priv;
/* We need a loader present to run in emulated isolated mode */
if (flags & SPE_ISOLATE_EMULATE
&& !_base_spe_emulated_loader_present()) {
errno = EINVAL;
return NULL;
}
/* Put some sane defaults into the SPE context */
spe = malloc(sizeof(*spe));
if (!spe) {
DEBUG_PRINTF("ERROR: Could not allocate spe context.\n");
return NULL;
}
memset(spe, 0, sizeof(*spe));
spe->base_private = malloc(sizeof(*spe->base_private));
if (!spe->base_private) {
DEBUG_PRINTF("ERROR: Could not allocate "
"spe->base_private context.\n");
free(spe);
return NULL;
}
/* just a convenience variable */
priv = spe->base_private;
priv->fd_spe_dir = -1;
priv->mem_mmap_base = MAP_FAILED;
priv->psmap_mmap_base = MAP_FAILED;
priv->mssync_mmap_base = MAP_FAILED;
priv->mfc_mmap_base = MAP_FAILED;
priv->cntl_mmap_base = MAP_FAILED;
priv->signal1_mmap_base = MAP_FAILED;
priv->signal2_mmap_base = MAP_FAILED;
priv->loaded_program = NULL;
for (i = 0; i < NUM_MBOX_FDS; i++) {
priv->spe_fds_array[i] = -1;
pthread_mutex_init(&priv->fd_lock[i], NULL);
}
/* initialise spu_createflags */
if (flags & SPE_ISOLATE) {
flags |= SPE_MAP_PS;
spu_createflags |= SPU_CREATE_ISOLATE | SPU_CREATE_NOSCHED;
}
if (flags & SPE_EVENTS_ENABLE)
spu_createflags |= SPU_CREATE_EVENTS_ENABLED;
if (aff_spe)
spu_createflags |= SPU_CREATE_AFFINITY_SPU;
if (flags & SPE_AFFINITY_MEMORY)
spu_createflags |= SPU_CREATE_AFFINITY_MEM;
/* Make the SPUFS directory for the SPE */
if (gctx == NULL)
sprintf(pathname, "/spu/spethread-%i-%lu",
getpid(), (unsigned long)spe);
else
sprintf(pathname, "/spu/%s/spethread-%i-%lu",
gctx->base_private->gangname, getpid(),
(unsigned long)spe);
if (aff_spe)
aff_spe_fd = aff_spe->base_private->fd_spe_dir;
priv->fd_spe_dir = spu_create(pathname, spu_createflags,
S_IRUSR | S_IWUSR | S_IXUSR, aff_spe_fd);
if (priv->fd_spe_dir < 0) {
int errno_saved = errno; /* save errno to prevent being overwritten */
DEBUG_PRINTF("ERROR: Could not create SPE %s\n", pathname);
perror("spu_create()");
free_spe_context(spe);
/* we mask most errors, but leave ENODEV, etc */
switch (errno_saved) {
case ENOTSUP:
case EEXIST:
case EINVAL:
case EBUSY:
case EPERM:
case ENODEV:
errno = errno_saved; /* restore errno */
break;
default:
errno = EFAULT;
break;
}
return NULL;
}
priv->flags = flags;
/* Map the required areas into process memory */
priv->mem_mmap_base = mapfileat(priv->fd_spe_dir, "mem", LS_SIZE);
if (priv->mem_mmap_base == MAP_FAILED) {
DEBUG_PRINTF("ERROR: Could not map SPE memory.\n");
free_spe_context(spe);
errno = ENOMEM;
return NULL;
}
if (flags & SPE_MAP_PS) {
/* It's possible to map the entire problem state area with
* one mmap - try this first */
priv->psmap_mmap_base = mapfileat(priv->fd_spe_dir,
"psmap", PSMAP_SIZE);
if (priv->psmap_mmap_base != MAP_FAILED) {
priv->mssync_mmap_base =
priv->psmap_mmap_base + MSSYNC_OFFSET;
priv->mfc_mmap_base =
priv->psmap_mmap_base + MFC_OFFSET;
priv->cntl_mmap_base =
priv->psmap_mmap_base + CNTL_OFFSET;
priv->signal1_mmap_base =
priv->psmap_mmap_base + SIGNAL1_OFFSET;
priv->signal2_mmap_base =
priv->psmap_mmap_base + SIGNAL2_OFFSET;
} else {
/* map each region separately */
priv->mfc_mmap_base =
mapfileat(priv->fd_spe_dir, "mfc", MFC_SIZE);
priv->mssync_mmap_base =
mapfileat(priv->fd_spe_dir, "mss", MSS_SIZE);
priv->cntl_mmap_base =
mapfileat(priv->fd_spe_dir, "cntl", CNTL_SIZE);
priv->signal1_mmap_base =
mapfileat(priv->fd_spe_dir, "signal1",
SIGNAL_SIZE);
priv->signal2_mmap_base =
mapfileat(priv->fd_spe_dir, "signal2",
SIGNAL_SIZE);
if (priv->mfc_mmap_base == MAP_FAILED ||
priv->cntl_mmap_base == MAP_FAILED ||
priv->signal1_mmap_base == MAP_FAILED ||
priv->signal2_mmap_base == MAP_FAILED) {
DEBUG_PRINTF("ERROR: Could not map SPE "
"PS memory.\n");
free_spe_context(spe);
errno = ENOMEM;
return NULL;
}
}
}
if (flags & SPE_CFG_SIGNOTIFY1_OR) {
if (setsignotify(priv->fd_spe_dir, "signal1_type")) {
DEBUG_PRINTF("ERROR: Could not open SPE "
"signal1_type file.\n");
free_spe_context(spe);
errno = EFAULT;
return NULL;
}
}
if (flags & SPE_CFG_SIGNOTIFY2_OR) {
if (setsignotify(priv->fd_spe_dir, "signal2_type")) {
DEBUG_PRINTF("ERROR: Could not open SPE "
"signal2_type file.\n");
free_spe_context(spe);
errno = EFAULT;
return NULL;
}
}
return spe;
}

Here is the call graph for this function:

int _base_spe_context_destroy | ( | spe_context_ptr_t | spectx) |  |

_base_spe_context_destroy cleans up what is left when an SPE executable has exited. Closes open file handles and unmaps memory areas.

Parameters

  spectx | Specifies the SPE context

Definition at line 418 of file create.c.

References __spe_context_update_event().

{
int ret = free_spe_context(spe);
__spe_context_update_event();
return ret;
}

Here is the call graph for this function:

void _base_spe_context_lock | ( | spe_context_ptr_t | spe,
|  | enum fd_name | fd
| ) |  |

_base_spe_context_lock locks members of the SPE context

Parameters

  spectx | Specifies the SPE context
  fd | Specifies the file

Definition at line 91 of file create.c.

References spe_context::base_private, and spe_context_base_priv::fd_lock.

Referenced by _base_spe_close_if_open(), and _base_spe_open_if_closed().

{
pthread_mutex_lock(&spe->base_private->fd_lock[fdesc]);
}

int _base_spe_context_run | ( | spe_context_ptr_t | spe,
|  | unsigned int * | entry,
|  | unsigned int | runflags,
|  | void * | argp,
|  | void * | envp,
|  | spe_stop_info_t * | stopinfo
| ) |  |

_base_spe_context_run starts execution of an SPE context with a loaded image

Parameters

  spectx | Specifies the SPE context
  entry | entry point for the SPE programm. If set to 0, entry point is determined by the ELF loader.
  runflags | valid values are: SPE_RUN_USER_REGS Specifies that the SPE setup registers r3, r4, and r5 are initialized with the 48 bytes pointed to by argp. SPE_NO_CALLBACKS do not use built in library functions.
  argp | An (optional) pointer to application specific data, and is passed as the second parameter to the SPE program.
  envp | An (optional) pointer to environment specific data, and is passed as the third parameter to the SPE program.

Definition at line 99 of file run.c.

References __spe_current_active_context, _base_spe_handle_library_callback(), _base_spe_program_load_complete(), spe_context::base_private, DEBUG_PRINTF, spe_context_base_priv::emulated_entry, spe_context_base_priv::entry, spe_context_base_priv::fd_spe_dir, spe_context_base_priv::flags, LS_SIZE, spe_context_base_priv::mem_mmap_base, spe_context_info::npc, spe_context_info::prev, spe_stop_info::result, spe_stop_info::spe_callback_error, SPE_CALLBACK_ERROR, SPE_DEFAULT_ENTRY, SPE_EVENTS_ENABLE, SPE_EXIT, spe_stop_info::spe_exit_code, spe_context_info::spe_id, SPE_ISOLATE, SPE_ISOLATE_EMULATE, spe_stop_info::spe_isolation_error, SPE_ISOLATION_ERROR, SPE_NO_CALLBACKS, SPE_PROGRAM_ISO_LOAD_COMPLETE, SPE_PROGRAM_ISOLATED_STOP, SPE_PROGRAM_LIBRARY_CALL, SPE_PROGRAM_NORMAL_END, SPE_RUN_USER_REGS, spe_stop_info::spe_runtime_error, SPE_RUNTIME_ERROR, spe_stop_info::spe_runtime_exception, SPE_RUNTIME_EXCEPTION, spe_stop_info::spe_runtime_fatal, SPE_RUNTIME_FATAL, spe_stop_info::spe_signal_code, SPE_SPU_HALT, SPE_SPU_INVALID_CHANNEL, SPE_SPU_INVALID_INSTR, SPE_SPU_STOPPED_BY_STOP, SPE_SPU_WAITING_ON_CHANNEL, SPE_STOP_AND_SIGNAL, spe_stop_info::spu_status, spe_context_info::status, spe_stop_info::stop_reason, addr64::ui, and addr64::ull.

Referenced by _event_spe_context_run().

{
int retval = 0, run_rc;
unsigned int run_status, tmp_entry;
spe_stop_info_t stopinfo_buf;
struct spe_context_info this_context_info __attribute__((cleanup(cleanupspeinfo)));
/* If the caller hasn't set a stopinfo buffer, provide a buffer on the
* stack instead. */
if (!stopinfo)
stopinfo = &stopinfo_buf;
/* In emulated isolated mode, the npc will always return as zero.
* use our private entry point instead */
if (spe->base_private->flags & SPE_ISOLATE_EMULATE)
tmp_entry = spe->base_private->emulated_entry;
else if (*entry == SPE_DEFAULT_ENTRY)
tmp_entry = spe->base_private->entry;
else
tmp_entry = *entry;
/* If we're starting the SPE binary from its original entry point,
* setup the arguments to main() */
if (tmp_entry == spe->base_private->entry &&
!(spe->base_private->flags &
(SPE_ISOLATE | SPE_ISOLATE_EMULATE))) {
addr64 argp64, envp64, tid64, ls64;
unsigned int regs[128][4];
/* setup parameters */
argp64.ull = (uint64_t)(unsigned long)argp;
envp64.ull = (uint64_t)(unsigned long)envp;
tid64.ull = (uint64_t)(unsigned long)spe;
/* make sure the register values are 0 */
memset(regs, 0, sizeof(regs));
/* set sensible values for stack_ptr and stack_size */
regs[1][0] = (unsigned int) LS_SIZE - 16; /* stack_ptr */
regs[2][0] = 0; /* stack_size ( 0 = default ) */
if (runflags & SPE_RUN_USER_REGS) {
/* When SPE_USER_REGS is set, argp points to an array
* of 3x128b registers to be passed directly to the SPE
* program.
*/
memcpy(regs[3], argp, sizeof(unsigned int) * 12);
} else {
regs[3][0] = tid64.ui[0];
regs[3][1] = tid64.ui[1];
regs[4][0] = argp64.ui[0];
regs[4][1] = argp64.ui[1];
regs[5][0] = envp64.ui[0];
regs[5][1] = envp64.ui[1];
}
/* Store the LS base address in R6 */
ls64.ull = (uint64_t)(unsigned long)spe->base_private->mem_mmap_base;
regs[6][0] = ls64.ui[0];
regs[6][1] = ls64.ui[1];
if (set_regs(spe, regs))
return -1;
}
/*Leave a trail of breadcrumbs for the debugger to follow */
if (!__spe_current_active_context) {
__spe_current_active_context = &this_context_info;
if (!__spe_current_active_context)
return -1;
__spe_current_active_context->prev = NULL;
} else {
struct spe_context_info *newinfo;
newinfo = &this_context_info;
if (!newinfo)
return -1;
newinfo->prev = __spe_current_active_context;
__spe_current_active_context = newinfo;
}
/*remember the ls-addr*/
__spe_current_active_context->spe_id = spe->base_private->fd_spe_dir;
do_run:
/*Remember the npc value*/
__spe_current_active_context->npc = tmp_entry;
/* run SPE context */
run_rc = spu_run(spe->base_private->fd_spe_dir,
&tmp_entry, &run_status);
/*Remember the npc value*/
__spe_current_active_context->npc = tmp_entry;
__spe_current_active_context->status = run_status;
DEBUG_PRINTF("spu_run returned run_rc=0x%08x, entry=0x%04x, "
"ext_status=0x%04x.\n", run_rc, tmp_entry, run_status);
/* set up return values and stopinfo according to spu_run exit
* conditions. This is overwritten on error.
*/
stopinfo->spu_status = run_rc;
if (spe->base_private->flags & SPE_ISOLATE_EMULATE) {
/* save the entry point, and pretend that the npc is zero */
spe->base_private->emulated_entry = tmp_entry;
*entry = 0;
} else {
*entry = tmp_entry;
}
/* Return with stopinfo set on syscall error paths */
if (run_rc == -1) {
DEBUG_PRINTF("spu_run returned error %d, errno=%d\n",
run_rc, errno);
stopinfo->stop_reason = SPE_RUNTIME_FATAL;
stopinfo->result.spe_runtime_fatal = errno;
retval = -1;
/* For isolated contexts, pass EPERM up to the
* caller.
*/
if (!(spe->base_private->flags & SPE_ISOLATE
&& errno == EPERM))
errno = EFAULT;
} else if (run_rc & SPE_SPU_INVALID_INSTR) {
DEBUG_PRINTF("SPU has tried to execute an invalid "
"instruction. %d\n", run_rc);
stopinfo->stop_reason = SPE_RUNTIME_ERROR;
stopinfo->result.spe_runtime_error = SPE_SPU_INVALID_INSTR;
errno = EFAULT;
retval = -1;
} else if ((spe->base_private->flags & SPE_EVENTS_ENABLE) && run_status) {
/* Report asynchronous error if return val are set and
* SPU events are enabled.
*/
stopinfo->stop_reason = SPE_RUNTIME_EXCEPTION;
stopinfo->result.spe_runtime_exception = run_status;
stopinfo->spu_status = -1;
errno = EIO;
retval = -1;
} else if (run_rc & SPE_SPU_STOPPED_BY_STOP) {
/* Stop & signals are broken down into three groups
* 1. SPE library call
* 2. SPE user defined stop & signal
* 3. SPE program end.
*
* These groups are signified by the 14-bit stop code:
*/
int stopcode = (run_rc >> 16) & 0x3fff;
/* Check if this is a library callback, and callbacks are
* allowed (ie, running without SPE_NO_CALLBACKS)
*/
if ((stopcode & 0xff00) == SPE_PROGRAM_LIBRARY_CALL
&& !(runflags & SPE_NO_CALLBACKS)) {
int callback_rc, callback_number = stopcode & 0xff;
/* execute library callback */
DEBUG_PRINTF("SPE library call: %d\n", callback_number);
callback_rc = _base_spe_handle_library_callback(spe,
callback_number, *entry);
if (callback_rc) {
/* library callback failed; set errno and
* return immediately */
DEBUG_PRINTF("SPE library call failed: %d\n",
callback_rc);
stopinfo->stop_reason = SPE_CALLBACK_ERROR;
stopinfo->result.spe_callback_error =
callback_rc;
errno = EFAULT;
retval = -1;
} else {
/* successful library callback - restart the SPE
* program at the next instruction */
tmp_entry += 4;
goto do_run;
}
} else if ((stopcode & 0xff00) == SPE_PROGRAM_NORMAL_END) {
/* The SPE program has exited by exit(X) */
stopinfo->stop_reason = SPE_EXIT;
stopinfo->result.spe_exit_code = stopcode & 0xff;
if (spe->base_private->flags & SPE_ISOLATE) {
/* Issue an isolated exit, and re-run the SPE.
* We should see a return value without the
* 0x80 bit set. */
if (!issue_isolated_exit(spe))
goto do_run;
retval = -1;
}
} else if ((stopcode & 0xfff0) == SPE_PROGRAM_ISOLATED_STOP) {
/* 0x2206: isolated app has been loaded by loader;
* provide a hook for the debugger to catch this,
* and restart
*/
if (stopcode == SPE_PROGRAM_ISO_LOAD_COMPLETE) {
_base_spe_program_load_complete(spe);
goto do_run;
} else {
stopinfo->stop_reason = SPE_ISOLATION_ERROR;
stopinfo->result.spe_isolation_error =
stopcode & 0xf;
}
} else if (spe->base_private->flags & SPE_ISOLATE &&
!(run_rc & 0x80)) {
/* We've successfully exited isolated mode */
retval = 0;
} else {
/* User defined stop & signal, including
* callbacks when disabled */
stopinfo->stop_reason = SPE_STOP_AND_SIGNAL;
stopinfo->result.spe_signal_code = stopcode;
retval = stopcode;
}
} else if (run_rc & SPE_SPU_HALT) {
DEBUG_PRINTF("SPU was stopped by halt. %d\n", run_rc);
stopinfo->stop_reason = SPE_RUNTIME_ERROR;
stopinfo->result.spe_runtime_error = SPE_SPU_HALT;
errno = EFAULT;
retval = -1;
} else if (run_rc & SPE_SPU_WAITING_ON_CHANNEL) {
DEBUG_PRINTF("SPU is waiting on channel. %d\n", run_rc);
stopinfo->stop_reason = SPE_RUNTIME_EXCEPTION;
stopinfo->result.spe_runtime_exception = run_status;
stopinfo->spu_status = -1;
errno = EIO;
retval = -1;
} else if (run_rc & SPE_SPU_INVALID_CHANNEL) {
DEBUG_PRINTF("SPU has tried to access an invalid "
"channel. %d\n", run_rc);
stopinfo->stop_reason = SPE_RUNTIME_ERROR;
stopinfo->result.spe_runtime_error = SPE_SPU_INVALID_CHANNEL;
errno = EFAULT;
retval = -1;
} else {
DEBUG_PRINTF("spu_run returned invalid data: 0x%04x\n", run_rc);
stopinfo->stop_reason = SPE_RUNTIME_FATAL;
stopinfo->result.spe_runtime_fatal = -1;
stopinfo->spu_status = -1;
errno = EFAULT;
retval = -1;
}
freespeinfo();
return retval;
}

Here is the call graph for this function:

void _base_spe_context_unlock | ( | spe_context_ptr_t | spe,
|  | enum fd_name | fd
| ) |  |

_base_spe_context_unlock unlocks members of the SPE context

Parameters

  spectx | Specifies the SPE context
  fd | Specifies the file

Definition at line 96 of file create.c.

References spe_context::base_private, and spe_context_base_priv::fd_lock.

Referenced by _base_spe_close_if_open(), and _base_spe_open_if_closed().

{
pthread_mutex_unlock(&spe->base_private->fd_lock[fdesc]);
}

int _base_spe_cpu_info_get | ( | int | info_requested,
|  | int | cpu_node
| ) |  |

_base_spe_info_get

Definition at line 105 of file info.c.

References _base_spe_count_physical_cpus(), _base_spe_count_physical_spes(), _base_spe_count_usable_spes(), SPE_COUNT_PHYSICAL_CPU_NODES, SPE_COUNT_PHYSICAL_SPES, and SPE_COUNT_USABLE_SPES.

{
int ret = 0;
errno = 0;
switch (info_requested) {
case SPE_COUNT_PHYSICAL_CPU_NODES:
ret = _base_spe_count_physical_cpus(cpu_node);
break;
case SPE_COUNT_PHYSICAL_SPES:
ret = _base_spe_count_physical_spes(cpu_node);
break;
case SPE_COUNT_USABLE_SPES:
ret = _base_spe_count_usable_spes(cpu_node);
break;
default:
errno = EINVAL;
ret = -1;
}
return ret;
}

Here is the call graph for this function:

int _base_spe_emulated_loader_present | ( | void | ) |  |

Check if the emulated loader is present in the filesystem

Returns
  Non-zero if the loader is available, otherwise zero.

Definition at line 159 of file load.c.

References _base_spe_verify_spe_elf_image().

Referenced by _base_spe_context_create().

{
spe_program_handle_t *loader = emulated_loader_program();
if (!loader)
return 0;
return !_base_spe_verify_spe_elf_image(loader);
}

Here is the call graph for this function:

spe_gang_context_ptr_t _base_spe_gang_context_create | ( | unsigned int | flags) |  |

creates the directory in SPUFS that will contain all SPEs that are considered a gang Note: I would like to generalize this to a "group" or "set" Additional attributes maintained at the group level should be used to define scheduling constraints such "temporal" (e.g., scheduled all at the same time, i.e., a gang) "topology" (e.g., "closeness" of SPEs for optimal communication)

Definition at line 376 of file create.c.

References spe_gang_context::base_private, DEBUG_PRINTF, and spe_gang_context_base_priv::gangname.

{
char pathname[256];
struct spe_gang_context_base_priv *pgctx = NULL;
struct spe_gang_context *gctx = NULL;
gctx = malloc(sizeof(*gctx));
if (!gctx) {
DEBUG_PRINTF("ERROR: Could not allocate spe context.\n");
return NULL;
}
memset(gctx, 0, sizeof(*gctx));
pgctx = malloc(sizeof(*pgctx));
if (!pgctx) {
DEBUG_PRINTF("ERROR: Could not allocate spe context.\n");
free(gctx);
return NULL;
}
memset(pgctx, 0, sizeof(*pgctx));
gctx->base_private = pgctx;
sprintf(gctx->base_private->gangname, "gang-%i-%lu", getpid(),
(unsigned long)gctx);
sprintf(pathname, "/spu/%s", gctx->base_private->gangname);
gctx->base_private->fd_gang_dir = spu_create(pathname, SPU_CREATE_GANG,
S_IRUSR | S_IWUSR | S_IXUSR);
if (gctx->base_private->fd_gang_dir < 0) {
DEBUG_PRINTF("ERROR: Could not create Gang %s\n", pathname);
free_spe_gang_context(gctx);
errno = EFAULT;
return NULL;
}
gctx->base_private->flags = flags;
return gctx;
}

int _base_spe_gang_context_destroy | ( | spe_gang_context_ptr_t | gctx) |  |

_base_spe_gang_context_destroy destroys a gang context and frees associated resources

Parameters

  gctx | Specifies the SPE gang context

Definition at line 427 of file create.c.

{
return free_spe_gang_context(gctx);
}

int _base_spe_image_close | ( | spe_program_handle_t * | handle) |  |

_base_spe_image_close unmaps an SPE ELF object that was previously mapped using spe_open_image.

Parameters

  handle | handle to open file

Return values

  0 | On success, spe_close_image returns 0.
  -1 | On failure, -1 is returned and errno is set appropriately. Possible values for errno: EINVAL From spe_close_image, this indicates that the file, specified by filename, was not previously mapped by a call to spe_open_image.

Definition at line 96 of file image.c.

References spe_program_handle::elf_image, image_handle::map_size, image_handle::speh, and spe_program_handle::toe_shadow.

{
int ret = 0;
struct image_handle *ih;
if (!handle) {
errno = EINVAL;
return -1;
}
ih = (struct image_handle *)handle;
if (!ih->speh.elf_image || !ih->map_size) {
errno = EINVAL;
return -1;
}
if (ih->speh.toe_shadow)
free(ih->speh.toe_shadow);
ret = munmap(ih->speh.elf_image, ih->map_size );
free(handle);
return ret;
}

spe_program_handle_t* _base_spe_image_open | ( | const char * | filename) |  |

_base_spe_image_open maps an SPE ELF executable indicated by filename into system memory and returns the mapped address appropriate for use by the spe_create_thread API. It is often more convenient/appropriate to use the loading methodologies where SPE ELF objects are converted to PPE static or shared libraries with symbols which point to the SPE ELF objects after these special libraries are loaded. These libraries are then linked with the associated PPE code to provide a direct symbol reference to the SPE ELF object. The symbols in this scheme are equivalent to the address returned from the spe_open_image function. SPE ELF objects loaded using this function are not shared with other processes, but SPE ELF objects loaded using the other scheme, mentioned above, can be shared if so desired.

Parameters

  filename | Specifies the filename of an SPE ELF executable to be loaded and mapped into system memory.

Returns
  On success, spe_open_image returns the address at which the specified SPE ELF object has been mapped. On failure, NULL is returned and errno is set appropriately.
  Possible values for errno include:
  EACCES The calling process does not have permission to access the specified file.
  EFAULT The filename parameter points to an address that was not contained in the calling process`s address space.

A number of other errno values could be returned by the open(2), fstat(2), mmap(2), munmap(2), or close(2) system calls which may be utilized by the spe_open_image or spe_close_image functions.

See Also
  spe_create_thread

Definition at line 37 of file image.c.

References _base_spe_toe_ear(), _base_spe_verify_spe_elf_image(), spe_program_handle::elf_image, spe_program_handle::handle_size, image_handle::map_size, image_handle::speh, and spe_program_handle::toe_shadow.

{
/* allocate an extra integer in the spe handle to keep the mapped size information */
struct image_handle *ret;
int binfd = -1, f_stat;
struct stat statbuf;
size_t ps = getpagesize ();
ret = malloc(sizeof(struct image_handle));
if (!ret)
return NULL;
ret->speh.handle_size = sizeof(spe_program_handle_t);
ret->speh.toe_shadow = NULL;
binfd = open(filename, O_RDONLY);
if (binfd < 0)
goto ret_err;
f_stat = fstat(binfd, &statbuf);
if (f_stat < 0)
goto ret_err;
/* Sanity: is it executable ?
*/
if(!(statbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
errno=EACCES;
goto ret_err;
}
/* now store the size at the extra allocated space */
ret->map_size = (statbuf.st_size + ps - 1) & ~(ps - 1);
ret->speh.elf_image = mmap(NULL, ret->map_size,
PROT_WRITE | PROT_READ,
MAP_PRIVATE, binfd, 0);
if (ret->speh.elf_image == MAP_FAILED)
goto ret_err;
/*Verify that this is a valid SPE ELF object*/
if((_base_spe_verify_spe_elf_image((spe_program_handle_t *)ret)))
goto ret_err;
if (_base_spe_toe_ear(&ret->speh))
goto ret_err;
/* ok */
close(binfd);
return (spe_program_handle_t *)ret;
/* err & cleanup */
ret_err:
if (binfd >= 0)
close(binfd);
free(ret);
return NULL;
}

Here is the call graph for this function:

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

       The _base_spe_in_mbox_write function writes mbox_data to the SPE inbound
       mailbox for the SPE thread speid.

       If the behavior flag indicates ALL_BLOCKING the call will try to write exactly count mailbox entries
       and block until the write request is satisfied, i.e., exactly count mailbox entries
       have been written.
       If the behavior flag indicates ANY_BLOCKING the call will try to write up to count mailbox entries,
       and block until the write request is satisfied, i.e., at least 1 mailbox entry has been written.
       If the behavior flag indicates ANY_NON_BLOCKING the call will not block until the write request is satisfied,
       but instead write whatever is immediately possible and return the number of mailbox entries written.
       spe_stat_in_mbox can be called to ensure that data can be written prior
       to calling the function.

Parameters

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

Return values

  >=0 | the number of 32-bit mailbox messages written
  -1 | error condition and errno is set Possible values for errno: EINVAL spectx is invalid Exxxx what else do we need here??

void* _base_spe_ls_area_get | ( | struct spe_context * | spectx) |  |

_base_spe_ls_area_get returns a pointer to the start of the memory mapped local store area

Parameters

  spectx | Specifies the SPE context

int _base_spe_ls_size_get | ( | spe_context_ptr_t | spe) |  |

_base_spe_ls_size_get returns the size of the local store area

Parameters

  spectx | Specifies the SPE context

Definition at line 105 of file accessors.c.

References LS_SIZE.

{
return LS_SIZE;
}

int _base_spe_mfcio_get | ( | spe_context_ptr_t | spectx,
|  | unsigned int | ls,
|  | void * | ea,
|  | unsigned int | size,
|  | unsigned int | tag,
|  | unsigned int | tid,
|  | unsigned int | rid
| ) |  |

The _base_spe_mfcio_get function places a get DMA command on the proxy command queue of the SPE thread specified by speid. The get command transfers size bytes of data starting at the effective address specified by ea to the local store address specified by ls. The DMA is identified by the tag id specified by tag and performed according to the transfer class and replacement class specified by tid and rid respectively.

Parameters

  spectx | Specifies the SPE context
  ls | Specifies the starting local store destination address.
  ea | Specifies the starting effective address source address.
  size | Specifies the size, in bytes, to be transferred.
  tag | Specifies the tag id used to identify the DMA command.
  tid | Specifies the transfer class identifier of the DMA command.
  rid | Specifies the replacement class identifier of the DMA command.

Returns
  On success, return 0. On failure, -1 is returned.

Definition at line 160 of file dma.c.

References MFC_CMD_GET.

{
return spe_do_mfc_get(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_GET);
}

int _base_spe_mfcio_getb | ( | spe_context_ptr_t | spectx,
|  | unsigned int | ls,
|  | void * | ea,
|  | unsigned int | size,
|  | unsigned int | tag,
|  | unsigned int | tid,
|  | unsigned int | rid
| ) |  |

The _base_spe_mfcio_getb function is identical to _base_spe_mfcio_get except that it places a getb (get with barrier) DMA command on the proxy command queue. The barrier form ensures that this command and all sequence commands with the same tag identifier as this command are locally ordered with respect to all previously issued commands with the same tag group and command queue.

Parameters

  spectx | Specifies the SPE context
  ls | Specifies the starting local store destination address.
  ea | Specifies the starting effective address source address.
  size | Specifies the size, in bytes, to be transferred.
  tag | Specifies the tag id used to identify the DMA command.
  tid | Specifies the transfer class identifier of the DMA command.
  rid | Specifies the replacement class identifier of the DMA command.

Returns
  On success, return 0. On failure, -1 is returned.

Definition at line 171 of file dma.c.

References MFC_CMD_GETB.

{
return spe_do_mfc_get(spectx, ls, ea, size, tag, rid, rid, MFC_CMD_GETB);
}

int _base_spe_mfcio_getf | ( | spe_context_ptr_t | spectx,
|  | unsigned int | ls,
|  | void * | ea,
|  | unsigned int | size,
|  | unsigned int | tag,
|  | unsigned int | tid,
|  | unsigned int | rid
| ) |  |

The _base_spe_mfcio_getf function is identical to _base_spe_mfcio_get except that it places a getf (get with fence) DMA command on the proxy command queue. The fence form ensure that this command is locally ordered with respect to all previously issued commands with the same tag group and command queue.

Parameters

  spectx | Specifies the SPE context
  ls | Specifies the starting local store destination address.
  ea | Specifies the starting effective address source address.
  size | Specifies the size, in bytes, to be transferred.
  tag | Specifies the tag id used to identify the DMA command.
  tid | Specifies the transfer class identifier of the DMA command.
  rid | Specifies the replacement class identifier of the DMA command.

Returns
  On success, return 0. On failure, -1 is returned.

Definition at line 182 of file dma.c.

References MFC_CMD_GETF.

{
return spe_do_mfc_get(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_GETF);
}

int _base_spe_mfcio_put | ( | spe_context_ptr_t | spectx,
|  | unsigned int | ls,
|  | void * | ea,
|  | unsigned int | size,
|  | unsigned int | tag,
|  | unsigned int | tid,
|  | unsigned int | rid
| ) |  |

The _base_spe_mfcio_put function places a put DMA command on the proxy command queue of the SPE thread specified by speid. The put command transfers size bytes of data starting at the local store address specified by ls to the effective address specified by ea. The DMA is identified by the tag id specified by tag and performed according transfer class and replacement class specified by tid and rid respectively.

Parameters

  spectx | Specifies the SPE context
  ls | Specifies the starting local store destination address.
  ea | Specifies the starting effective address source address.
  size | Specifies the size, in bytes, to be transferred.
  tag | Specifies the tag id used to identify the DMA command.
  tid | Specifies the transfer class identifier of the DMA command.
  rid | Specifies the replacement class identifier of the DMA command.

Returns
  On success, return 0. On failure, -1 is returned.

Definition at line 126 of file dma.c.

References MFC_CMD_PUT.

{
return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUT);
}

int _base_spe_mfcio_putb | ( | spe_context_ptr_t | spectx,
|  | unsigned int | ls,
|  | void * | ea,
|  | unsigned int | size,
|  | unsigned int | tag,
|  | unsigned int | tid,
|  | unsigned int | rid
| ) |  |

The _base_spe_mfcio_putb function is identical to _base_spe_mfcio_put except that it places a putb (put with barrier) DMA command on the proxy command queue. The barrier form ensures that this command and all sequence commands with the same tag identifier as this command are locally ordered with respect to all previously i ssued commands with the same tag group and command queue.

Parameters

  spectx | Specifies the SPE context
  ls | Specifies the starting local store destination address.
  ea | Specifies the starting effective address source address.
  size | Specifies the size, in bytes, to be transferred.
  tag | Specifies the tag id used to identify the DMA command.
  tid | Specifies the transfer class identifier of the DMA command.
  rid | Specifies the replacement class identifier of the DMA command.

Returns
  On success, return 0. On failure, -1 is returned.

Definition at line 137 of file dma.c.

References MFC_CMD_PUTB.

{
return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUTB);
}

int _base_spe_mfcio_putf | ( | spe_context_ptr_t | spectx,
|  | unsigned int | ls,
|  | void * | ea,
|  | unsigned int | size,
|  | unsigned int | tag,
|  | unsigned int | tid,
|  | unsigned int | rid
| ) |  |

The _base_spe_mfcio_putf function is identical to _base_spe_mfcio_put except that it places a putf (put with fence) DMA command on the proxy command queue. The fence form ensures that this command is locally ordered with respect to all previously issued commands with the same tag group and command queue.

Parameters

  spectx | Specifies the SPE context
  ls | Specifies the starting local store destination address.
  ea | Specifies the starting effective address source address.
  size | Specifies the size, in bytes, to be transferred.
  tag | Specifies the tag id used to identify the DMA command.
  tid | Specifies the transfer class identifier of the DMA command.
  rid | Specifies the replacement class identifier of the DMA command.

Returns
  On success, return 0. On failure, -1 is returned.

Definition at line 148 of file dma.c.

References MFC_CMD_PUTF.

{
return spe_do_mfc_put(spectx, ls, ea, size, tag, tid, rid, MFC_CMD_PUTF);
}

int _base_spe_mfcio_tag_status_read | ( | spe_context_ptr_t | spectx,
|  | unsigned int | mask,
|  | unsigned int | behavior,
|  | unsigned int * | tag_status
| ) |  |

_base_spe_mfcio_tag_status_read

No Idea

Definition at line 307 of file dma.c.

References spe_context_base_priv::active_tagmask, spe_context::base_private, spe_context_base_priv::flags, SPE_MAP_PS, SPE_TAG_ALL, SPE_TAG_ANY, and SPE_TAG_IMMEDIATE.

{
if ( mask != 0 ) {
if (!(spectx->base_private->flags & SPE_MAP_PS))
mask = 0;
} else {
if ((spectx->base_private->flags & SPE_MAP_PS))
mask = spectx->base_private->active_tagmask;
}
if (!tag_status) {
errno = EINVAL;
return -1;
}
switch (behavior) {
case SPE_TAG_ALL:
return spe_mfcio_tag_status_read_all(spectx, mask, tag_status);
case SPE_TAG_ANY:
return spe_mfcio_tag_status_read_any(spectx, mask, tag_status);
case SPE_TAG_IMMEDIATE:
return spe_mfcio_tag_status_read_immediate(spectx, mask, tag_status);
default:
errno = EINVAL;
return -1;
}
}

int _base_spe_mssync_start | ( | spe_context_ptr_t | spectx) |  |

_base_spe_mssync_start starts Multisource Synchronisation

Parameters

  spectx | Specifies the SPE context

Definition at line 335 of file dma.c.

References _base_spe_open_if_closed(), spe_context::base_private, FD_MSS, spe_context_base_priv::flags, spe_mssync_area::MFC_MSSync, spe_context_base_priv::mssync_mmap_base, and SPE_MAP_PS.

{
int ret, fd;
unsigned int data = 1; /* Any value can be written here */
volatile struct spe_mssync_area *mss_area =
spectx->base_private->mssync_mmap_base;
if (spectx->base_private->flags & SPE_MAP_PS) {
mss_area->MFC_MSSync = data;
return 0;
} else {
fd = _base_spe_open_if_closed(spectx, FD_MSS, 0);
if (fd != -1) {
ret = write(fd, &data, sizeof (data));
if ((ret < 0) && (errno != EIO)) {
perror("spe_mssync_start: internal error");
}
return ret < 0 ? -1 : 0;
} else
return -1;
}
}

Here is the call graph for this function:

int _base_spe_mssync_status | ( | spe_context_ptr_t | spectx) |  |

_base_spe_mssync_status retrieves status of Multisource Synchronisation

Parameters

  spectx | Specifies the SPE context

Definition at line 359 of file dma.c.

References _base_spe_open_if_closed(), spe_context::base_private, FD_MSS, spe_context_base_priv::flags, spe_mssync_area::MFC_MSSync, spe_context_base_priv::mssync_mmap_base, and SPE_MAP_PS.

{
int ret, fd;
unsigned int data;
volatile struct spe_mssync_area *mss_area =
spectx->base_private->mssync_mmap_base;
if (spectx->base_private->flags & SPE_MAP_PS) {
return mss_area->MFC_MSSync;
} else {
fd = _base_spe_open_if_closed(spectx, FD_MSS, 0);
if (fd != -1) {
ret = read(fd, &data, sizeof (data));
if ((ret < 0) && (errno != EIO)) {
perror("spe_mssync_start: internal error");
}
return ret < 0 ? -1 : data;
} else
return -1;
}
}

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_program_load | ( | spe_context_ptr_t | spectx,
|  | spe_program_handle_t * | program
| ) |  |

_base_spe_program_load loads an ELF image into a context

Parameters

  spectx | Specifies the SPE context
  program | handle to the ELF image

Definition at line 203 of file load.c.

References _base_spe_load_spe_elf(), _base_spe_program_load_complete(), spe_context::base_private, DEBUG_PRINTF, spe_context_base_priv::emulated_entry, spe_ld_info::entry, spe_context_base_priv::entry, spe_context_base_priv::flags, spe_context_base_priv::loaded_program, spe_context_base_priv::mem_mmap_base, SPE_ISOLATE, and SPE_ISOLATE_EMULATE.

{
int rc = 0;
struct spe_ld_info ld_info;
spe->base_private->loaded_program = program;
if (spe->base_private->flags & SPE_ISOLATE) {
rc = spe_start_isolated_app(spe, program);
} else if (spe->base_private->flags & SPE_ISOLATE_EMULATE) {
rc = spe_start_emulated_isolated_app(spe, program, &ld_info);
} else {
rc = _base_spe_load_spe_elf(program,
spe->base_private->mem_mmap_base, &ld_info);
if (!rc)
_base_spe_program_load_complete(spe);
}
if (rc != 0) {
DEBUG_PRINTF ("Load SPE ELF failed..\n");
return -1;
}
spe->base_private->entry = ld_info.entry;
spe->base_private->emulated_entry = ld_info.entry;
return 0;
}

Here is the call graph for this function:

void _base_spe_program_load_complete | ( | spe_context_ptr_t | spectx) |  |

Signal that the program load has completed. For normal apps, this is called directly in the load path. For (emulated) isolated apps, the load is asynchronous, so this needs to be called when we know that the load has completed

Precondition
  spe->base_priv->loaded_program is a valid SPE program

Parameters

  spectx | The spe context that has been loaded.

Register the SPE program's start address with the oprofile and gdb, by writing to the object-id file.

Definition at line 38 of file load.c.

References __spe_context_update_event(), spe_context::base_private, DEBUG_PRINTF, spe_program_handle::elf_image, spe_context_base_priv::fd_spe_dir, and spe_context_base_priv::loaded_program.

Referenced by _base_spe_context_run(), and _base_spe_program_load().

{
int objfd, len;
char buf[20];
spe_program_handle_t *program;
program = spectx->base_private->loaded_program;
if (!program || !program->elf_image) {
DEBUG_PRINTF("%s called, but no program loaded\n", __func__);
return;
}
objfd = openat(spectx->base_private->fd_spe_dir, "object-id", O_RDWR);
if (objfd < 0)
return;
len = sprintf(buf, "%p", program->elf_image);
write(objfd, buf, len + 1);
close(objfd);
__spe_context_update_event();
}

Here is the call graph for this function:

void* _base_spe_ps_area_get | ( | struct spe_context * | spectx,
|  | enum ps_area | area
| ) |  |

_base_spe_ps_area_get returns a pointer to the start of memory mapped problem state area

Parameters

  spectx | Specifies the SPE context
  area | specifes the area to map

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:

int _base_spe_stop_reason_get | ( | spe_context_ptr_t | spectx) |  |

_base_spe_stop_reason_get

Parameters

  spectx | one thread for which to check why it was stopped

Return values

  0 | success - eventid and eventdata set appropriately
  1 | spe has not stopped after checking last, so no data was written to event
  -1 | an error has happened, event was not touched, errno gets set Possible vales for errno: EINVAL speid is invalid Exxxx what else do we need here??

int _base_spe_stop_status_get | ( | spe_context_ptr_t | spectx) |  |

_base_spe_stop_status_get

Parameters

  spectx | Specifies the SPE context