1 /* drmstat.c -- DRM device status and testing program
2 * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
27 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
34 #include <sys/types.h>
46 static double usec(struct timeval
*end
, struct timeval
*start
)
48 double e
= end
->tv_sec
* 1000000 + end
->tv_usec
;
49 double s
= start
->tv_sec
* 1000000 + start
->tv_usec
;
54 static void getversion(int fd
)
56 drmVersionPtr version
;
58 version
= drmGetVersion(fd
);
60 printf( "Name: %s\n", version
->name
? version
->name
: "?" );
61 printf( " Version: %d.%d.%d\n",
62 version
->version_major
,
63 version
->version_minor
,
64 version
->version_patchlevel
);
65 printf( " Date: %s\n", version
->date
? version
->date
: "?" );
66 printf( " Desc: %s\n", version
->desc
? version
->desc
: "?" );
67 drmFreeVersion(version
);
69 printf( "No driver available\n" );
73 void handler(int fd
, void *oldctx
, void *newctx
)
75 printf("Got fd %d\n", fd
);
78 void process_sigio(char *device
)
82 if ((fd
= open(device
, 0)) < 0) {
83 drmError(-errno
, __FUNCTION__
);
88 /* drmInstallSIGIOHandler(fd, handler); */
92 int main(int argc
, char **argv
)
101 unsigned long offset
;
103 drm_context_t context
;
112 while ((c
= getopt(argc
, argv
,
113 "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF
)
116 count
= strtoul(optarg
, NULL
, 0);
123 case 'v': getversion(fd
); break;
125 if ((r
= drmCreateContext(fd
, &context
))) {
126 drmError(r
, argv
[0]);
129 printf( "Got %d\n", context
);
132 process_sigio(optarg
);
135 if ((r
= drmSwitchToContext(fd
, strtoul(optarg
, NULL
, 0)))) {
136 drmError(r
, argv
[0]);
141 if ((r
= drmSetBusid(fd
,optarg
))) {
142 drmError(r
, argv
[0]);
147 if ((fd
= drmOpen(optarg
, NULL
)) < 0) {
148 drmError(fd
, argv
[0]);
153 if ((fd
= drmOpen(NULL
, optarg
)) < 0) {
154 drmError(fd
, argv
[0]);
158 case 'B': /* Test buffer allocation */
159 count
= strtoul(optarg
, &pt
, 0);
160 size
= strtoul(pt
+1, &pt
, 0);
161 secs
= strtoul(pt
+1, NULL
, 0);
164 int *indices
, *sizes
;
166 indices
= alloca(sizeof(*indices
) * count
);
167 sizes
= alloca(sizeof(*sizes
) * count
);
168 dma
.context
= context
;
170 dma
.request_count
= count
;
171 dma
.request_size
= size
;
172 dma
.request_list
= indices
;
173 dma
.request_sizes
= sizes
;
174 dma
.flags
= DRM_DMA_WAIT
;
175 if ((r
= drmDMA(fd
, &dma
))) {
176 drmError(r
, argv
[0]);
179 for (i
= 0; i
< dma
.granted_count
; i
++) {
180 printf("%5d: index = %d, size = %d\n",
181 i
, dma
.request_list
[i
], dma
.request_sizes
[i
]);
184 drmFreeBufs(fd
, dma
.granted_count
, indices
);
188 count
= strtoul(optarg
, &pt
, 0);
189 size
= strtoul(pt
+1, NULL
, 0);
190 if ((r
= drmAddBufs(fd
, count
, size
, 0, 65536)) < 0) {
191 drmError(r
, argv
[0]);
194 if (!(info
= drmGetBufInfo(fd
))) {
195 drmError(0, argv
[0]);
198 for (i
= 0; i
< info
->count
; i
++) {
199 printf("%5d buffers of size %6d (low = %d, high = %d)\n",
202 info
->list
[i
].low_mark
,
203 info
->list
[i
].high_mark
);
205 if ((r
= drmMarkBufs(fd
, 0.50, 0.80))) {
206 drmError(r
, argv
[0]);
209 if (!(info
= drmGetBufInfo(fd
))) {
210 drmError(0, argv
[0]);
213 for (i
= 0; i
< info
->count
; i
++) {
214 printf("%5d buffers of size %6d (low = %d, high = %d)\n",
217 info
->list
[i
].low_mark
,
218 info
->list
[i
].high_mark
);
220 printf("===== /proc/dri/0/mem =====\n");
221 sprintf(buf
, "cat /proc/dri/0/mem");
224 if (!(bufs
= drmMapBufs(fd
))) {
225 drmError(0, argv
[0]);
228 printf("===============================\n");
229 printf( "%d bufs\n", bufs
->count
);
230 for (i
= 0; i
< bufs
->count
; i
++) {
231 printf( " %4d: %8d bytes at %p\n",
234 bufs
->list
[i
].address
);
236 printf("===== /proc/dri/0/vma =====\n");
237 sprintf(buf
, "cat /proc/dri/0/vma");
242 offset
= strtoul(optarg
, &pt
, 0);
243 size
= strtoul(pt
+1, NULL
, 0);
245 if ((r
= drmAddMap(fd
, offset
, size
,
246 DRM_FRAME_BUFFER
, 0, &handle
))) {
247 drmError(r
, argv
[0]);
250 printf("0x%08lx:0x%04lx added\n", offset
, size
);
251 printf("===== /proc/dri/0/mem =====\n");
252 sprintf(buf
, "cat /proc/dri/0/mem");
257 offset
= strtoul(optarg
, &pt
, 0);
258 size
= strtoul(pt
+1, NULL
, 0);
260 if ((r
= drmAddMap(fd
, offset
, size
,
262 c
== 'R' ? DRM_READ_ONLY
: 0,
264 drmError(r
, argv
[0]);
267 printf("0x%08lx:0x%04lx added\n", offset
, size
);
268 printf("===== /proc/dri/0/mem =====\n");
269 sprintf(buf
, "cat /proc/dri/0/mem");
273 size
= strtoul(optarg
, &pt
, 0);
275 if ((r
= drmAddMap(fd
, 0, size
,
276 DRM_SHM
, DRM_CONTAINS_LOCK
,
278 drmError(r
, argv
[0]);
281 printf("0x%04lx byte shm added at 0x%08lx\n", size
, handle
);
282 sprintf(buf
, "cat /proc/dri/0/vm");
286 offset
= strtoul(optarg
, &pt
, 0);
287 size
= strtoul(pt
+1, NULL
, 0);
289 if ((r
= drmMap(fd
, offset
, size
, &address
))) {
290 drmError(r
, argv
[0]);
293 printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
294 offset
, size
, address
, getpid());
295 printf("===== /proc/dri/0/vma =====\n");
296 sprintf(buf
, "cat /proc/dri/0/vma");
298 mprotect((void *)offset
, size
, PROT_READ
);
299 printf("===== /proc/dri/0/vma =====\n");
300 sprintf(buf
, "cat /proc/dri/0/vma");
305 offset
= strtoul(optarg
, &pt
, 0);
306 size
= strtoul(pt
+1, NULL
, 0);
308 if ((r
= drmMap(fd
, offset
, size
, &address
))) {
309 drmError(r
, argv
[0]);
312 printf("0x%08lx:0x%04lx mapped at %p for pid %d\n",
313 offset
, size
, address
, getpid());
314 printf("===== /proc/%d/maps =====\n", getpid());
315 sprintf(buf
, "cat /proc/%d/maps", getpid());
317 printf("===== /proc/dri/0/mem =====\n");
318 sprintf(buf
, "cat /proc/dri/0/mem");
320 printf("===== /proc/dri/0/vma =====\n");
321 sprintf(buf
, "cat /proc/dri/0/vma");
323 printf("===== READING =====\n");
324 for (i
= 0; i
< 0x10; i
++)
325 printf("%02x ", (unsigned int)((unsigned char *)address
)[i
]);
328 printf("===== WRITING =====\n");
329 for (i
= 0; i
< size
; i
+=2) {
330 ((char *)address
)[i
] = i
& 0xff;
331 ((char *)address
)[i
+1] = i
& 0xff;
334 printf("===== READING =====\n");
335 for (i
= 0; i
< 0x10; i
++)
336 printf("%02x ", (unsigned int)((unsigned char *)address
)[i
]);
338 printf("===== /proc/dri/0/vma =====\n");
339 sprintf(buf
, "cat /proc/dri/0/vma");
343 context
= strtoul(optarg
, &pt
, 0);
344 offset
= strtoul(pt
+1, &pt
, 0);
345 size
= strtoul(pt
+1, &pt
, 0);
346 loops
= strtoul(pt
+1, NULL
, 0);
348 if ((r
= drmMap(fd
, offset
, size
, &address
))) {
349 drmError(r
, argv
[0]);
356 struct timeval loop_start
, loop_end
;
357 struct timeval lock_start
, lock_end
;
360 int histo
[HISTOSIZE
];
369 for (i
= 0; i
< HISTOSIZE
; i
++) histo
[i
] = 0;
371 gettimeofday(&loop_start
, NULL
);
372 for (i
= 0; i
< loops
; i
++) {
373 gettimeofday(&lock_start
, NULL
);
374 DRM_LIGHT_LOCK_COUNT(fd
,lock
,context
,fast
);
375 gettimeofday(&lock_end
, NULL
);
376 DRM_UNLOCK(fd
,lock
,context
);
378 wt
= usec(&lock_end
, &lock_start
);
379 if (wt
<= 2.5) ++histo
[8];
380 if (wt
< 5.0) ++histo
[0];
381 else if (wt
< 50.0) ++histo
[1];
382 else if (wt
< 500.0) ++histo
[2];
383 else if (wt
< 5000.0) ++histo
[3];
384 else if (wt
< 50000.0) ++histo
[4];
385 else if (wt
< 500000.0) ++histo
[5];
386 else if (wt
< 5000000.0) ++histo
[6];
388 if (output
) printf( "%.2f uSec, %d fast\n", wt
, fast
);
390 gettimeofday(&loop_end
, NULL
);
391 printf( "Average wait time = %.2f usec, %d fast\n",
392 usec(&loop_end
, &loop_start
) / counter
, fast
);
393 printf( "%9d <= 2.5 uS\n", histo
[8]);
394 printf( "%9d < 5 uS\n", histo
[0]);
395 printf( "%9d < 50 uS\n", histo
[1]);
396 printf( "%9d < 500 uS\n", histo
[2]);
397 printf( "%9d < 5000 uS\n", histo
[3]);
398 printf( "%9d < 50000 uS\n", histo
[4]);
399 printf( "%9d < 500000 uS\n", histo
[5]);
400 printf( "%9d < 5000000 uS\n", histo
[6]);
401 printf( "%9d >= 5000000 uS\n", histo
[7]);
404 printf( "before lock: 0x%08x\n", lock
->lock
);
405 printf( "lock: 0x%08x\n", lock
->lock
);
407 printf( "unlock: 0x%08x\n", lock
->lock
);
411 fprintf( stderr
, "Usage: drmstat [options]\n" );
419 xf86VDrvMsgVerb(int scrnIndex
, int type
, int verb
, const char *format
,
422 vfprintf(stderr
, format
, args
);
425 int xf86ConfigDRI
[10];