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