mirror of https://github.com/mkerrisk/man-pages
273 lines
6.7 KiB
Groff
273 lines
6.7 KiB
Groff
.\" Copyright (c) International Business Machines Corp., 2006
|
|
.\"
|
|
.\" %%%LICENSE_START(GPLv2+_SW_3_PARA)
|
|
.\" This program is free software; you can redistribute it and/or
|
|
.\" modify it under the terms of the GNU General Public License as
|
|
.\" published by the Free Software Foundation; either version 2 of
|
|
.\" the License, or (at your option) any later version.
|
|
.\"
|
|
.\" This program is distributed in the hope that it will be useful,
|
|
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
|
.\" the GNU General Public License for more details.
|
|
.\"
|
|
.\" You should have received a copy of the GNU General Public
|
|
.\" License along with this manual; if not, see
|
|
.\" <http://www.gnu.org/licenses/>.
|
|
.\" %%%LICENSE_END
|
|
.\"
|
|
.\" HISTORY:
|
|
.\" 2005-09-28, created by Arnd Bergmann <arndb@de.ibm.com>
|
|
.\" 2006-06-16, revised by Eduardo M. Fleury <efleury@br.ibm.com>
|
|
.\" 2007-07-10, some polishing by mtk
|
|
.\" 2007-09-28, updates for newer kernels, added example
|
|
.\" by Jeremy Kerr <jk@ozlabs.org>
|
|
.\"
|
|
.TH SPU_RUN 2 2021-03-22 Linux "Linux Programmer's Manual"
|
|
.SH NAME
|
|
spu_run \- execute an SPU context
|
|
.SH SYNOPSIS
|
|
.nf
|
|
.B #include <sys/spu.h>
|
|
.PP
|
|
.BI "int spu_run(int " fd ", uint32_t *" npc ", uint32_t *" event );
|
|
.fi
|
|
.PP
|
|
.IR Note :
|
|
There is no glibc wrapper for this system call; see NOTES.
|
|
.SH DESCRIPTION
|
|
The
|
|
.BR spu_run ()
|
|
system call is used on PowerPC machines that implement the
|
|
Cell Broadband Engine Architecture in order to access Synergistic
|
|
Processor Units (SPUs).
|
|
The
|
|
.I fd
|
|
argument is a file descriptor returned by
|
|
.BR spu_create (2)
|
|
that refers to a specific SPU context.
|
|
When the context gets scheduled to a physical SPU,
|
|
it starts execution at the instruction pointer passed in
|
|
.IR npc .
|
|
.PP
|
|
Execution of SPU code happens synchronously, meaning that
|
|
.BR spu_run ()
|
|
blocks while the SPU is still running.
|
|
If there is a need
|
|
to execute SPU code in parallel with other code on either the
|
|
main CPU or other SPUs, a new thread of execution must be created
|
|
first (e.g., using
|
|
.BR pthread_create (3)).
|
|
.PP
|
|
When
|
|
.BR spu_run ()
|
|
returns, the current value of the SPU program counter is written to
|
|
.IR npc ,
|
|
so successive calls to
|
|
.BR spu_run ()
|
|
can use the same
|
|
.I npc
|
|
pointer.
|
|
.PP
|
|
The
|
|
.I event
|
|
argument provides a buffer for an extended status code.
|
|
If the SPU
|
|
context was created with the
|
|
.B SPU_CREATE_EVENTS_ENABLED
|
|
flag, then this buffer is populated by the Linux kernel before
|
|
.BR spu_run ()
|
|
returns.
|
|
.PP
|
|
The status code may be one (or more) of the following constants:
|
|
.TP
|
|
.B SPE_EVENT_DMA_ALIGNMENT
|
|
A DMA alignment error occurred.
|
|
.TP
|
|
.B SPE_EVENT_INVALID_DMA
|
|
An invalid MFC DMA command was attempted.
|
|
.\" SPE_EVENT_SPE_DATA_SEGMENT is defined, but does not seem to be generated
|
|
.\" at any point (in Linux 5.9 sources).
|
|
.TP
|
|
.B SPE_EVENT_SPE_DATA_STORAGE
|
|
A DMA storage error occurred.
|
|
.TP
|
|
.B SPE_EVENT_SPE_ERROR
|
|
An illegal instruction was executed.
|
|
.PP
|
|
NULL
|
|
is a valid value for the
|
|
.I event
|
|
argument.
|
|
In this case, the events will not be reported to the calling process.
|
|
.SH RETURN VALUE
|
|
On success,
|
|
.BR spu_run ()
|
|
returns the value of the
|
|
.I spu_status
|
|
register.
|
|
On failure, it returns \-1 and sets
|
|
.I errno
|
|
is set to indicate the error.
|
|
.PP
|
|
The
|
|
.I spu_status
|
|
register value is a bit mask of status codes and
|
|
optionally a 14-bit code returned from the
|
|
.BR stop-and-signal
|
|
instruction on the SPU.
|
|
The bit masks for the status codes
|
|
are:
|
|
.TP
|
|
.B 0x02
|
|
SPU was stopped by a
|
|
.BR stop-and-signal
|
|
instruction.
|
|
.TP
|
|
.B 0x04
|
|
SPU was stopped by a
|
|
.BR halt
|
|
instruction.
|
|
.TP
|
|
.B 0x08
|
|
SPU is waiting for a channel.
|
|
.TP
|
|
.B 0x10
|
|
SPU is in single-step mode.
|
|
.TP
|
|
.B 0x20
|
|
SPU has tried to execute an invalid instruction.
|
|
.TP
|
|
.B 0x40
|
|
SPU has tried to access an invalid channel.
|
|
.TP
|
|
.B 0x3fff0000
|
|
The bits masked with this value contain the code returned from a
|
|
.BR stop-and-signal
|
|
instruction.
|
|
These bits are valid only if the 0x02 bit is set.
|
|
.PP
|
|
If
|
|
.BR spu_run ()
|
|
has not returned an error, one or more bits among the lower eight
|
|
ones are always set.
|
|
.SH ERRORS
|
|
.TP
|
|
.B EBADF
|
|
.I fd
|
|
is not a valid file descriptor.
|
|
.TP
|
|
.B EFAULT
|
|
.I npc
|
|
is not a valid pointer, or
|
|
.I event
|
|
is non-NULL and an invalid pointer.
|
|
.TP
|
|
.B EINTR
|
|
A signal occurred while
|
|
.BR spu_run ()
|
|
was in progress; see
|
|
.BR signal (7).
|
|
The
|
|
.I npc
|
|
value has been updated to the new program counter value if
|
|
necessary.
|
|
.TP
|
|
.B EINVAL
|
|
.I fd
|
|
is not a valid file descriptor returned from
|
|
.BR spu_create (2).
|
|
.TP
|
|
.B ENOMEM
|
|
There was not enough memory available to handle a page fault
|
|
resulting from a Memory Flow Controller (MFC) direct memory access.
|
|
.TP
|
|
.B ENOSYS
|
|
The functionality is not provided by the current system, because
|
|
either the hardware does not provide SPUs or the spufs module is not
|
|
loaded.
|
|
.SH VERSIONS
|
|
The
|
|
.BR spu_run ()
|
|
system call was added to Linux in kernel 2.6.16.
|
|
.SH CONFORMING TO
|
|
This call is Linux-specific and implemented only by the PowerPC
|
|
architecture.
|
|
Programs using this system call are not portable.
|
|
.SH NOTES
|
|
Glibc does not provide a wrapper for this system call; call it using
|
|
.BR syscall (2).
|
|
Note however, that
|
|
.BR spu_run ()
|
|
is meant to be used from libraries that implement a more abstract
|
|
interface to SPUs, not to be used from regular applications.
|
|
See
|
|
.UR http://www.bsc.es\:/projects\:/deepcomputing\:/linuxoncell/
|
|
.UE
|
|
for the recommended libraries.
|
|
.SH EXAMPLES
|
|
The following is an example of running a simple, one-instruction SPU
|
|
program with the
|
|
.BR spu_run ()
|
|
system call.
|
|
.PP
|
|
.EX
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <fcntl.h>
|
|
|
|
#define handle_error(msg) \e
|
|
do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
|
|
|
int main(void)
|
|
{
|
|
int context, fd, spu_status;
|
|
uint32_t instruction, npc;
|
|
|
|
context = spu_create("/spu/example\-context", 0, 0755);
|
|
if (context == \-1)
|
|
handle_error("spu_create");
|
|
|
|
/*
|
|
* Write a \(aqstop 0x1234\(aq instruction to the SPU\(aqs
|
|
* local store memory.
|
|
*/
|
|
instruction = 0x00001234;
|
|
|
|
fd = open("/spu/example\-context/mem", O_RDWR);
|
|
if (fd == \-1)
|
|
handle_error("open");
|
|
write(fd, &instruction, sizeof(instruction));
|
|
|
|
/*
|
|
* set npc to the starting instruction address of the
|
|
* SPU program. Since we wrote the instruction at the
|
|
* start of the mem file, the entry point will be 0x0.
|
|
*/
|
|
npc = 0;
|
|
|
|
spu_status = spu_run(context, &npc, NULL);
|
|
if (spu_status == \-1)
|
|
handle_error("open");
|
|
|
|
/*
|
|
* We should see a status code of 0x1234002:
|
|
* 0x00000002 (spu was stopped due to stop\-and\-signal)
|
|
* | 0x12340000 (the stop\-and\-signal code)
|
|
*/
|
|
printf("SPU Status: %#08x\en", spu_status);
|
|
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
.EE
|
|
.\" .SH AUTHORS
|
|
.\" Arnd Bergmann <arndb@de.ibm.com>, Jeremy Kerr <jk@ozlabs.org>
|
|
.SH SEE ALSO
|
|
.BR close (2),
|
|
.BR spu_create (2),
|
|
.BR capabilities (7),
|
|
.BR spufs (7)
|