📄 spu-info.c
字号:
/* Copyright 2007, 2008 Free Software Foundation, Inc. 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 3 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 program. If not, see <http://www.gnu.org/licenses/>. This file is part of the gdb testsuite. Contributed by Markus Deuling <deuling@de.ibm.com>. Tests for 'info spu' commands. */#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <spu_mfcio.h>/* PPE-assisted call interface. */voidsend_to_ppe (unsigned int signalcode, unsigned int opcode, void *data){ __vector unsigned int stopfunc = { signalcode, /* stop */ (opcode << 24) | (unsigned int) data, 0x4020007f, /* nop */ 0x35000000 /* bi $0 */ }; void (*f) (void) = (void *) &stopfunc; asm ("sync"); f ();}/* PPE-assisted call to mmap from SPU. */unsigned long longmmap_ea (unsigned long long start, size_t length, int prot, int flags, int fd, off_t offset){ struct mmap_args { unsigned long long start __attribute__ ((aligned (16))); size_t length __attribute__ ((aligned (16))); int prot __attribute__ ((aligned (16))); int flags __attribute__ ((aligned (16))); int fd __attribute__ ((aligned (16))); off_t offset __attribute__ ((aligned (16))); } args; args.start = start; args.length = length; args.prot = prot; args.flags = flags; args.fd = fd; args.offset = offset; send_to_ppe (0x2101, 11, &args); return args.start;}/* This works only in a Linux environment with <= 1024 open file descriptors for one process. Result is the file descriptor for the current context if available. */intfind_context_fd (void){ int dir_fd = -1; int i; for (i = 0; i < 1024; i++) { struct stat stat; if (fstat (i, &stat) < 0) break; if (S_ISDIR (stat.st_mode)) dir_fd = dir_fd == -1 ? i : -2; } return dir_fd < 0 ? -1 : dir_fd;}/* Open the context file and return the file handler. */intopen_context_file (int context_fd, char *name, int flags){ char buf[128]; if (context_fd < 0) return -1; sprintf (buf, "/proc/self/fd/%d/%s", context_fd, name); return open (buf, flags);}intdo_event_test (){ spu_write_event_mask (MFC_MULTI_SRC_SYNC_EVENT); /* 0x1000 */ /* Marker Event */ spu_write_event_mask (MFC_PRIV_ATTN_EVENT); /* 0x0800 */ spu_write_event_mask (MFC_LLR_LOST_EVENT); /* 0x0400 */ spu_write_event_mask (MFC_SIGNAL_NOTIFY_1_EVENT); /* 0x0200 */ spu_write_event_mask (MFC_SIGNAL_NOTIFY_2_EVENT); /* 0x0100 */ spu_write_event_mask (MFC_OUT_MBOX_AVAILABLE_EVENT); /* 0x0080 */ spu_write_event_mask (MFC_OUT_INTR_MBOX_AVAILABLE_EVENT); /* 0x0040 */ spu_write_event_mask (MFC_DECREMENTER_EVENT); /* 0x0020 */ spu_write_event_mask (MFC_IN_MBOX_AVAILABLE_EVENT); /* 0x0010 */ spu_write_event_mask (MFC_COMMAND_QUEUE_AVAILABLE_EVENT); /* 0x0008 */ spu_write_event_mask (MFC_LIST_STALL_NOTIFY_EVENT); /* 0x0002 */ spu_write_event_mask (MFC_TAG_STATUS_UPDATE_EVENT); /* 0x0001 */ return 0;}intdo_dma_test (){ #define MAP_FAILED (-1ULL) #define PROT_READ 0x1 #define MAP_PRIVATE 0x002 #define BSIZE 128 static char buf[BSIZE] __attribute__ ((aligned (128))); char *file = "/var/tmp/tmp_buf"; struct stat fdstat; int fd, cnt; unsigned long long src; /* Create a file and fill it with some bytes. */ fd = open (file, O_CREAT | O_RDWR | O_TRUNC, 0777); if (fd == -1) return -1; memset ((void *)buf, '1', BSIZE); write (fd, buf, BSIZE); write (fd, buf, BSIZE); memset ((void *)buf, 0, BSIZE); if (fstat (fd, &fdstat) != 0 || !fdstat.st_size) return -2; src = mmap_ea(0ULL, fdstat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (src == MAP_FAILED) return -3; /* Copy some data via DMA. */ mfc_get (&buf, src, BSIZE, 5, 0, 0); /* Marker DMA */ mfc_write_tag_mask (1<<5); /* Marker DMAWait */ spu_mfcstat (MFC_TAG_UPDATE_ALL); /* Close the file. */ close (fd); return cnt;}intdo_mailbox_test (){ /* Write to SPU Outbound Mailbox. */ if (spu_stat_out_mbox ()) /* Marker Mbox */ spu_write_out_mbox (0x12345678); /* Write to SPU Outbound Interrupt Mailbox. */ if (spu_stat_out_intr_mbox ()) spu_write_out_intr_mbox (0x12345678); return 0; /* Marker MboxEnd */}intdo_signal_test (){ struct stat fdstat; int context_fd = find_context_fd (); int ret, buf, fd; buf = 23; /* Marker Signal */ /* Write to signal1. */ fd = open_context_file (context_fd, "signal1", O_RDWR); if (fstat (fd, &fdstat) != 0) return -1; ret = write (fd, buf, sizeof (int)); close (fd); /* Marker Signal1 */ /* Write to signal2. */ fd = open_context_file (context_fd, "signal2", O_RDWR); if (fstat (fd, &fdstat) != 0) return -1; ret = write (fd, buf, sizeof (int)); close (fd); /* Marker Signal2 */ /* Read signal1. */ if (spu_stat_signal1 ()) ret = spu_read_signal1 (); /* Read signal2. */ if (spu_stat_signal2 ()) ret = spu_read_signal2 (); /* Marker SignalRead */ return 0;}intmain (unsigned long long speid, unsigned long long argp, unsigned long long envp){ int res; /* info spu event */ res = do_event_test (); /* info spu dma */ res = do_dma_test (); /* info spu mailbox */ res = do_mailbox_test (); /* info spu signal */ res = do_signal_test (); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -