* configure.ac: Switch license to GPLv3.
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.arch / spu-info.c
CommitLineData
23d964e7
UW
1/* Copyright 2007 Free Software Foundation, Inc.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place - Suite 330,
16 Boston, MA 02111-1307, USA.
17
18 This file is part of the gdb testsuite.
19
20 Contributed by Markus Deuling <deuling@de.ibm.com>.
21 Tests for 'info spu' commands. */
22
23#include <stdio.h>
24#include <string.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <fcntl.h>
28#include <spu_mfcio.h>
29
30
31/* PPE-assisted call interface. */
32void
33send_to_ppe (unsigned int signalcode, unsigned int opcode, void *data)
34{
35 __vector unsigned int stopfunc =
36 {
37 signalcode, /* stop */
38 (opcode << 24) | (unsigned int) data,
39 0x4020007f, /* nop */
40 0x35000000 /* bi $0 */
41 };
42
43 void (*f) (void) = (void *) &stopfunc;
44 asm ("sync");
45 f ();
46}
47
48/* PPE-assisted call to mmap from SPU. */
49unsigned long long
50mmap_ea (unsigned long long start, size_t length,
51 int prot, int flags, int fd, off_t offset)
52{
53 struct mmap_args
54 {
55 unsigned long long start __attribute__ ((aligned (16)));
56 size_t length __attribute__ ((aligned (16)));
57 int prot __attribute__ ((aligned (16)));
58 int flags __attribute__ ((aligned (16)));
59 int fd __attribute__ ((aligned (16)));
60 off_t offset __attribute__ ((aligned (16)));
61 } args;
62
63 args.start = start;
64 args.length = length;
65 args.prot = prot;
66 args.flags = flags;
67 args.fd = fd;
68 args.offset = offset;
69
70 send_to_ppe (0x2101, 11, &args);
71 return args.start;
72}
73
74/* This works only in a Linux environment with <= 1024 open
75 file descriptors for one process. Result is the file
76 descriptor for the current context if available. */
77int
78find_context_fd (void)
79{
80 int dir_fd = -1;
81 int i;
82
83 for (i = 0; i < 1024; i++)
84 {
85 struct stat stat;
86
87 if (fstat (i, &stat) < 0)
88 break;
89 if (S_ISDIR (stat.st_mode))
90 dir_fd = dir_fd == -1 ? i : -2;
91 }
92 return dir_fd < 0 ? -1 : dir_fd;
93}
94
95/* Open the context file and return the file handler. */
96int
97open_context_file (int context_fd, char *name, int flags)
98{
99 char buf[128];
100
101 if (context_fd < 0)
102 return -1;
103
104 sprintf (buf, "/proc/self/fd/%d/%s", context_fd, name);
105 return open (buf, flags);
106}
107
108
109int
110do_event_test ()
111{
112 spu_write_event_mask (MFC_MULTI_SRC_SYNC_EVENT); /* 0x1000 */ /* Marker Event */
113 spu_write_event_mask (MFC_PRIV_ATTN_EVENT); /* 0x0800 */
114 spu_write_event_mask (MFC_LLR_LOST_EVENT); /* 0x0400 */
115 spu_write_event_mask (MFC_SIGNAL_NOTIFY_1_EVENT); /* 0x0200 */
116 spu_write_event_mask (MFC_SIGNAL_NOTIFY_2_EVENT); /* 0x0100 */
117 spu_write_event_mask (MFC_OUT_MBOX_AVAILABLE_EVENT); /* 0x0080 */
118 spu_write_event_mask (MFC_OUT_INTR_MBOX_AVAILABLE_EVENT); /* 0x0040 */
119 spu_write_event_mask (MFC_DECREMENTER_EVENT); /* 0x0020 */
120 spu_write_event_mask (MFC_IN_MBOX_AVAILABLE_EVENT); /* 0x0010 */
121 spu_write_event_mask (MFC_COMMAND_QUEUE_AVAILABLE_EVENT); /* 0x0008 */
122 spu_write_event_mask (MFC_LIST_STALL_NOTIFY_EVENT); /* 0x0002 */
123 spu_write_event_mask (MFC_TAG_STATUS_UPDATE_EVENT); /* 0x0001 */
124
125 return 0;
126}
127
128int
129do_dma_test ()
130{
131 #define MAP_FAILED (-1ULL)
132 #define PROT_READ 0x1
133 #define MAP_PRIVATE 0x002
134 #define BSIZE 128
135 static char buf[BSIZE] __attribute__ ((aligned (128)));
136 char *file = "/var/tmp/tmp_buf";
137 struct stat fdstat;
138 int fd, cnt;
139 unsigned long long src;
140
141 /* Create a file and fill it with some bytes. */
142 fd = open (file, O_CREAT | O_RDWR | O_TRUNC, 0777);
143 if (fd == -1)
144 return -1;
145 memset ((void *)buf, '1', BSIZE);
146 write (fd, buf, BSIZE);
147 write (fd, buf, BSIZE);
148 memset ((void *)buf, 0, BSIZE);
149
150 if (fstat (fd, &fdstat) != 0
151 || !fdstat.st_size)
152 return -2;
153
154 src = mmap_ea(0ULL, fdstat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
155 if (src == MAP_FAILED)
156 return -3;
157
158 /* Copy some data via DMA. */
159 mfc_get (&buf, src, BSIZE, 5, 0, 0); /* Marker DMA */
160 mfc_write_tag_mask (1<<5); /* Marker DMAWait */
161 spu_mfcstat (MFC_TAG_UPDATE_ALL);
162
163 /* Close the file. */
164 close (fd);
165
166 return cnt;
167}
168
169int
170do_mailbox_test ()
171{
172 /* Write to SPU Outbound Mailbox. */
173 if (spu_stat_out_mbox ()) /* Marker Mbox */
174 spu_write_out_mbox (0x12345678);
175
176 /* Write to SPU Outbound Interrupt Mailbox. */
177 if (spu_stat_out_intr_mbox ())
178 spu_write_out_intr_mbox (0x12345678);
179
180 return 0; /* Marker MboxEnd */
181}
182
183int
184do_signal_test ()
185{
186 struct stat fdstat;
187 int context_fd = find_context_fd ();
188 int ret, buf, fd;
189
190 buf = 23; /* Marker Signal */
191 /* Write to signal1. */
192 fd = open_context_file (context_fd, "signal1", O_RDWR);
193 if (fstat (fd, &fdstat) != 0)
194 return -1;
195 ret = write (fd, buf, sizeof (int));
196 close (fd); /* Marker Signal1 */
197
198 /* Write to signal2. */
199 fd = open_context_file (context_fd, "signal2", O_RDWR);
200 if (fstat (fd, &fdstat) != 0)
201 return -1;
202 ret = write (fd, buf, sizeof (int));
203 close (fd); /* Marker Signal2 */
204
205 /* Read signal1. */
206 if (spu_stat_signal1 ())
207 ret = spu_read_signal1 ();
208
209 /* Read signal2. */
210 if (spu_stat_signal2 ())
211 ret = spu_read_signal2 (); /* Marker SignalRead */
212
213 return 0;
214}
215
216int
217main (unsigned long long speid, unsigned long long argp,
218 unsigned long long envp)
219{
220 int res;
221
222 /* info spu event */
223 res = do_event_test ();
224
225 /* info spu dma */
226 res = do_dma_test ();
227
228 /* info spu mailbox */
229 res = do_mailbox_test ();
230
231 /* info spu signal */
232 res = do_signal_test ();
233
234 return 0;
235}
236
This page took 0.047494 seconds and 4 git commands to generate.