SPU_RUN - Linux手册页

时间:2019-08-20 17:59:27  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-06-09

名称

spu_run-执行SPU上下文

语法

#include <sys/spu.h>

int spu_run(int fd, unsigned int *npc, unsigned int *event);

注意:此系统调用没有glibc包装器。请参阅注释。

说明

spu_run()系统调用在实现单元宽带引擎体系结构的PowerPC机器上使用,以便访问协同处理器单元(SPU)。 fd参数是spu_create(2)返回的文件描述符,它引用特定的SPU上下文。当上下文被调度到物理SPU时,它将在npc中传递的指令指针处开始执行。

SPU代码的执行是同步发生的,这意味着spu_run()在SPU仍在运行时会阻塞。如果需要在主CPU或其他SPU上与其他代码并行执行SPU代码,则必须首先创建一个新的执行线程(例如,使用pthread_create(3))。

spu_run()返回时,SPU程序计数器的当前值被写入npc,因此对spu_run()的后续调用可以使用相同的npc指针。

事件参数提供了扩展状态代码的缓冲区。如果SPU上下文是使用SPU_CREATE_EVENTS_ENABLED标志创建的,则在spu_run()返回之前,Linux内核将填充此缓冲区。

状态码可以是以下常量之一(或多个):

SPE_EVENT_DMA_ALIGNMENT
发生DMA对齐错误。
SPE_EVENT_INVALID_DMA
尝试了无效的MFC DMA命令。
SPE_EVENT_SPE_DATA_STORAGE
发生DMA存储错误。
SPE_EVENT_SPE_ERROR
执行了非法指令。

NULL是事件参数的有效值。在这种情况下,事件将不会报告给调用过程。

返回值

成功时,spu_run()返回spu_status寄存器的值。错误时,它返回-1并将errno设置为下面列出的错误代码之一。

spu_status寄存器的值是状态代码的位掩码,还可以是从SPU上的停止和信号指令返回的14位代码(可选)。状态码的位掩码为:

0x02
SPU由停止和信号指令停止。
0x04
SPU由暂停指令停止。
0x08
SPU正在等待通道。
0x10
SPU处于单步模式。
0x20
SPU试图执行无效指令。
0x40
SPU尝试访问无效通道。
0x3fff0000
用该值屏蔽的位包含从停止和信号指令返回的代码。仅当设置了0x02位时,这些位才有效。

如果spu_run()没有返回错误,则始终设置低八位中的一个或多个位。

错误说明

EBADF
fd不是有效的文件描述符。
EFAULT
npc不是有效的指针,或者event为非NULL且无效的指针。
EINTR
spu_run()进行时发生信号;参见signal(7)。如有必要,npc值已更新为新的程序计数器值。
EINVAL
fd不是从spu_create(2)返回的有效文件描述符。
ENOMEM
没有足够的可用内存来处理由于内存流控制器(MFC)直接内存访问而导致的页面错误。
ENOSYS
当前功能未提供该功能,因为硬件不提供SPU或未加载spufs模块。

版本

spu_run()系统调用已添加到内核2.6.16中的Linux中。

遵循规范

此调用特定于Linux,并且仅由PowerPC架构实现。使用此系统调用的程序不可移植。

备注

Glibc不为该系统调用提供包装器;使用syscall(2)调用它。但是请注意,spu_run()是从实现SPU的抽象接口的库中使用的,而不是从常规应用程序中使用的。请参阅以获取推荐的库。

示例

以下是使用spu_run()系统调用运行简单的单指令SPU程序的示例。

#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>

#define handle_error(msg) \
    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 0x1234aq instruction to the SPUaqs
     * 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: 0x%08x\n", spu_status);

    exit(EXIT_SUCCESS);
}

另外参见

close(2),spu_create(2),capabilities(7),spufs(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/