]>
Commit | Line | Data |
---|---|---|
d24596d5 | 1 | .\" Copyright (c) International Business Machines Corp., 2006 |
f9f7c042 | 2 | .\" |
e4a74ca8 | 3 | .\" SPDX-License-Identifier: GPL-2.0-or-later |
f9f7c042 MK |
4 | .\" |
5 | .\" HISTORY: | |
6 | .\" 2005-09-28, created by Arnd Bergmann <arndb@de.ibm.com> | |
7 | .\" 2006-06-16, revised by Eduardo M. Fleury <efleury@br.ibm.com> | |
8 | .\" 2007-07-10, some polishing by mtk | |
d24596d5 MK |
9 | .\" 2007-09-28, updates for newer kernels, added example |
10 | .\" by Jeremy Kerr <jk@ozlabs.org> | |
f9f7c042 | 11 | .\" |
1d767b55 | 12 | .TH SPU_RUN 2 2021-03-22 Linux "Linux Programmer's Manual" |
f9f7c042 | 13 | .SH NAME |
763f0e47 | 14 | spu_run \- execute an SPU context |
a55818ff AC |
15 | .SH LIBRARY |
16 | Standard C library | |
8fc3b2cf | 17 | .RI ( libc ", " \-lc ) |
f9f7c042 MK |
18 | .SH SYNOPSIS |
19 | .nf | |
841f16a2 AC |
20 | .BR "#include <sys/spu.h>" " /* Definition of " SPU_* " constants */" |
21 | .BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */" | |
22 | .B #include <unistd.h> | |
dbfe9c70 | 23 | .PP |
beb7a3c1 | 24 | .BI "int spu_run(int " fd ", uint32_t *" npc ", uint32_t *" event ); |
f9f7c042 | 25 | .fi |
dbfe9c70 | 26 | .PP |
45c99e3e | 27 | .IR Note : |
841f16a2 AC |
28 | glibc provides no wrapper for |
29 | .BR spu_run (), | |
30 | necessitating the use of | |
31 | .BR syscall (2). | |
f9f7c042 | 32 | .SH DESCRIPTION |
e0bf9127 | 33 | The |
f9f7c042 | 34 | .BR spu_run () |
e0bf9127 MK |
35 | system call is used on PowerPC machines that implement the |
36 | Cell Broadband Engine Architecture in order to access Synergistic | |
f9f7c042 MK |
37 | Processor Units (SPUs). |
38 | The | |
39 | .I fd | |
e0bf9127 | 40 | argument is a file descriptor returned by |
f9f7c042 | 41 | .BR spu_create (2) |
d24596d5 MK |
42 | that refers to a specific SPU context. |
43 | When the context gets scheduled to a physical SPU, | |
44 | it starts execution at the instruction pointer passed in | |
f9f7c042 | 45 | .IR npc . |
efeece04 | 46 | .PP |
e0bf9127 | 47 | Execution of SPU code happens synchronously, meaning that |
f9f7c042 | 48 | .BR spu_run () |
d24596d5 | 49 | blocks while the SPU is still running. |
f9f7c042 | 50 | If there is a need |
e0bf9127 | 51 | to execute SPU code in parallel with other code on either the |
f9f7c042 | 52 | main CPU or other SPUs, a new thread of execution must be created |
d24596d5 MK |
53 | first (e.g., using |
54 | .BR pthread_create (3)). | |
efeece04 | 55 | .PP |
f9f7c042 MK |
56 | When |
57 | .BR spu_run () | |
d24596d5 | 58 | returns, the current value of the SPU program counter is written to |
f9f7c042 | 59 | .IR npc , |
d24596d5 | 60 | so successive calls to |
f9f7c042 | 61 | .BR spu_run () |
d24596d5 MK |
62 | can use the same |
63 | .I npc | |
64 | pointer. | |
efeece04 | 65 | .PP |
d24596d5 | 66 | The |
f9f7c042 | 67 | .I event |
d24596d5 MK |
68 | argument provides a buffer for an extended status code. |
69 | If the SPU | |
70 | context was created with the | |
71 | .B SPU_CREATE_EVENTS_ENABLED | |
72 | flag, then this buffer is populated by the Linux kernel before | |
f9f7c042 | 73 | .BR spu_run () |
d24596d5 | 74 | returns. |
efeece04 | 75 | .PP |
d24596d5 | 76 | The status code may be one (or more) of the following constants: |
f9f7c042 MK |
77 | .TP |
78 | .B SPE_EVENT_DMA_ALIGNMENT | |
d24596d5 | 79 | A DMA alignment error occurred. |
f9f7c042 MK |
80 | .TP |
81 | .B SPE_EVENT_INVALID_DMA | |
d24596d5 | 82 | An invalid MFC DMA command was attempted. |
7be45add MK |
83 | .\" SPE_EVENT_SPE_DATA_SEGMENT is defined, but does not seem to be generated |
84 | .\" at any point (in Linux 5.9 sources). | |
f9f7c042 MK |
85 | .TP |
86 | .B SPE_EVENT_SPE_DATA_STORAGE | |
d24596d5 | 87 | A DMA storage error occurred. |
f9f7c042 MK |
88 | .TP |
89 | .B SPE_EVENT_SPE_ERROR | |
d24596d5 | 90 | An illegal instruction was executed. |
f9f7c042 | 91 | .PP |
d24596d5 MK |
92 | NULL |
93 | is a valid value for the | |
f9f7c042 | 94 | .I event |
d24596d5 MK |
95 | argument. |
96 | In this case, the events will not be reported to the calling process. | |
f9f7c042 | 97 | .SH RETURN VALUE |
d24596d5 | 98 | On success, |
f9f7c042 MK |
99 | .BR spu_run () |
100 | returns the value of the | |
101 | .I spu_status | |
102 | register. | |
7a6227d3 | 103 | On failure, it returns \-1 and sets |
f9f7c042 | 104 | .I errno |
7a6227d3 | 105 | is set to indicate the error. |
efeece04 | 106 | .PP |
e0bf9127 | 107 | The |
f9f7c042 MK |
108 | .I spu_status |
109 | register value is a bit mask of status codes and | |
d24596d5 | 110 | optionally a 14-bit code returned from the |
1ae6b2c7 | 111 | .B stop-and-signal |
f9f7c042 MK |
112 | instruction on the SPU. |
113 | The bit masks for the status codes | |
114 | are: | |
115 | .TP | |
116 | .B 0x02 | |
d24596d5 | 117 | SPU was stopped by a |
1ae6b2c7 | 118 | .B stop-and-signal |
d24596d5 | 119 | instruction. |
f9f7c042 MK |
120 | .TP |
121 | .B 0x04 | |
d24596d5 | 122 | SPU was stopped by a |
1ae6b2c7 | 123 | .B halt |
d24596d5 | 124 | instruction. |
f9f7c042 MK |
125 | .TP |
126 | .B 0x08 | |
127 | SPU is waiting for a channel. | |
128 | .TP | |
129 | .B 0x10 | |
130 | SPU is in single-step mode. | |
131 | .TP | |
132 | .B 0x20 | |
133 | SPU has tried to execute an invalid instruction. | |
134 | .TP | |
135 | .B 0x40 | |
136 | SPU has tried to access an invalid channel. | |
d24596d5 MK |
137 | .TP |
138 | .B 0x3fff0000 | |
139 | The bits masked with this value contain the code returned from a | |
1ae6b2c7 | 140 | .B stop-and-signal |
d24596d5 | 141 | instruction. |
33a0ccb2 | 142 | These bits are valid only if the 0x02 bit is set. |
f9f7c042 MK |
143 | .PP |
144 | If | |
145 | .BR spu_run () | |
146 | has not returned an error, one or more bits among the lower eight | |
147 | ones are always set. | |
148 | .SH ERRORS | |
149 | .TP | |
f9f7c042 MK |
150 | .B EBADF |
151 | .I fd | |
152 | is not a valid file descriptor. | |
153 | .TP | |
154 | .B EFAULT | |
155 | .I npc | |
d24596d5 MK |
156 | is not a valid pointer, or |
157 | .I event | |
158 | is non-NULL and an invalid pointer. | |
f9f7c042 MK |
159 | .TP |
160 | .B EINTR | |
161 | A signal occurred while | |
162 | .BR spu_run () | |
76e533c4 MK |
163 | was in progress; see |
164 | .BR signal (7). | |
f9f7c042 MK |
165 | The |
166 | .I npc | |
167 | value has been updated to the new program counter value if | |
168 | necessary. | |
169 | .TP | |
170 | .B EINVAL | |
171 | .I fd | |
d24596d5 | 172 | is not a valid file descriptor returned from |
f9f7c042 MK |
173 | .BR spu_create (2). |
174 | .TP | |
175 | .B ENOMEM | |
176 | There was not enough memory available to handle a page fault | |
177 | resulting from a Memory Flow Controller (MFC) direct memory access. | |
178 | .TP | |
179 | .B ENOSYS | |
180 | The functionality is not provided by the current system, because | |
181 | either the hardware does not provide SPUs or the spufs module is not | |
182 | loaded. | |
183 | .SH VERSIONS | |
184 | The | |
2777b1ca | 185 | .BR spu_run () |
f9f7c042 MK |
186 | system call was added to Linux in kernel 2.6.16. |
187 | .SH CONFORMING TO | |
33a0ccb2 | 188 | This call is Linux-specific and implemented only by the PowerPC |
f9f7c042 MK |
189 | architecture. |
190 | Programs using this system call are not portable. | |
191 | .SH NOTES | |
f9f7c042 MK |
192 | .BR spu_run () |
193 | is meant to be used from libraries that implement a more abstract | |
194 | interface to SPUs, not to be used from regular applications. | |
e0bf9127 | 195 | See |
608bf950 SK |
196 | .UR http://www.bsc.es\:/projects\:/deepcomputing\:/linuxoncell/ |
197 | .UE | |
f9f7c042 | 198 | for the recommended libraries. |
a14af333 | 199 | .SH EXAMPLES |
d24596d5 MK |
200 | The following is an example of running a simple, one-instruction SPU |
201 | program with the | |
202 | .BR spu_run () | |
203 | system call. | |
efeece04 | 204 | .PP |
408731d4 | 205 | .EX |
d24596d5 MK |
206 | #include <stdlib.h> |
207 | #include <stdint.h> | |
208 | #include <unistd.h> | |
209 | #include <stdio.h> | |
210 | #include <sys/types.h> | |
211 | #include <fcntl.h> | |
212 | ||
d1a71985 | 213 | #define handle_error(msg) \e |
d24596d5 MK |
214 | do { perror(msg); exit(EXIT_FAILURE); } while (0) |
215 | ||
216 | int main(void) | |
217 | { | |
218 | int context, fd, spu_status; | |
219 | uint32_t instruction, npc; | |
220 | ||
221 | context = spu_create("/spu/example\-context", 0, 0755); | |
c3074d70 | 222 | if (context == \-1) |
d24596d5 MK |
223 | handle_error("spu_create"); |
224 | ||
d5d83905 MK |
225 | /* |
226 | * Write a \(aqstop 0x1234\(aq instruction to the SPU\(aqs | |
227 | * local store memory. | |
d24596d5 MK |
228 | */ |
229 | instruction = 0x00001234; | |
230 | ||
231 | fd = open("/spu/example\-context/mem", O_RDWR); | |
c3074d70 | 232 | if (fd == \-1) |
d24596d5 MK |
233 | handle_error("open"); |
234 | write(fd, &instruction, sizeof(instruction)); | |
235 | ||
d5d83905 MK |
236 | /* |
237 | * set npc to the starting instruction address of the | |
d24596d5 | 238 | * SPU program. Since we wrote the instruction at the |
d5d83905 | 239 | * start of the mem file, the entry point will be 0x0. |
d24596d5 MK |
240 | */ |
241 | npc = 0; | |
242 | ||
243 | spu_status = spu_run(context, &npc, NULL); | |
c3074d70 | 244 | if (spu_status == \-1) |
d24596d5 MK |
245 | handle_error("open"); |
246 | ||
d5d83905 MK |
247 | /* |
248 | * We should see a status code of 0x1234002: | |
d24596d5 MK |
249 | * 0x00000002 (spu was stopped due to stop\-and\-signal) |
250 | * | 0x12340000 (the stop\-and\-signal code) | |
251 | */ | |
dc97703b | 252 | printf("SPU Status: %#08x\en", spu_status); |
d24596d5 MK |
253 | |
254 | exit(EXIT_SUCCESS); | |
255 | } | |
408731d4 | 256 | .EE |
d24596d5 MK |
257 | .\" .SH AUTHORS |
258 | .\" Arnd Bergmann <arndb@de.ibm.com>, Jeremy Kerr <jk@ozlabs.org> | |
f9f7c042 MK |
259 | .SH SEE ALSO |
260 | .BR close (2), | |
261 | .BR spu_create (2), | |
d24596d5 | 262 | .BR capabilities (7), |
f9f7c042 | 263 | .BR spufs (7) |