/* drmstat.c -- DRM device status and testing program * Created: Tue Jan 5 08:19:24 1999 by faith@precisioninsight.com * * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: Rickard E. (Rik) Faith * */ #include #include #include #include #include #include #include #include #include #include #include #include "xf86drm.h" int sigio_fd; static double usec(struct timeval *end, struct timeval *start) { double e = end->tv_sec * 1000000 + end->tv_usec; double s = start->tv_sec * 1000000 + start->tv_usec; return e - s; } static void getversion(int fd) { drmVersionPtr version; version = drmGetVersion(fd); if (version) { printf( "Name: %s\n", version->name ? version->name : "?" ); printf( " Version: %d.%d.%d\n", version->version_major, version->version_minor, version->version_patchlevel ); printf( " Date: %s\n", version->date ? version->date : "?" ); printf( " Desc: %s\n", version->desc ? version->desc : "?" ); drmFreeVersion(version); } else { printf( "No driver available\n" ); } } void handler(int fd, void *oldctx, void *newctx) { printf("Got fd %d\n", fd); } void process_sigio(char *device) { int fd; if ((fd = open(device, 0)) < 0) { drmError(-errno, __FUNCTION__); exit(1); } sigio_fd = fd; drmInstallSIGIOHandler(fd, handler); for (;;) sleep(60); } int main(int argc, char **argv) { int c; int r = 0; int fd = -1; drmHandle handle; void *address; char *pt; unsigned long count; unsigned long offset; unsigned long size; drmContext context; int loops; char buf[1024]; int i; drmBufInfoPtr info; drmBufMapPtr bufs; drmLockPtr lock; int secs; while ((c = getopt(argc, argv, "lc:vo:O:f:s:w:W:b:r:R:P:L:C:XS:B:F:")) != EOF) switch (c) { case 'F': count = strtoul(optarg, NULL, 0); if (!fork()) { dup(fd); sleep(count); } close(fd); break; case 'v': getversion(fd); break; case 'X': if ((r = drmCreateContext(fd, &context))) { drmError(r, argv[0]); return 1; } printf( "Got %d\n", context); break; case 'S': process_sigio(optarg); break; case 'C': if ((r = drmSwitchToContext(fd, strtoul(optarg, NULL, 0)))) { drmError(r, argv[0]); return 1; } break; case 'c': if ((r = drmSetBusid(fd,optarg))) { drmError(r, argv[0]); return 1; } break; case 'o': if ((fd = drmOpen(optarg, NULL)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'O': if ((fd = drmOpen(NULL, optarg)) < 0) { drmError(fd, argv[0]); return 1; } break; case 'B': /* Test buffer allocation */ count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, &pt, 0); secs = strtoul(pt+1, NULL, 0); { drmDMAReq dma; int *indices, *sizes; indices = alloca(sizeof(*indices) * count); sizes = alloca(sizeof(*sizes) * count); dma.context = context; dma.send_count = 0; dma.request_count = count; dma.request_size = size; dma.request_list = indices; dma.request_sizes = sizes; dma.flags = DRM_DMA_WAIT; if ((r = drmDMA(fd, &dma))) { drmError(r, argv[0]); return 1; } for (i = 0; i < dma.granted_count; i++) { printf("%5d: index = %d, size = %d\n", i, dma.request_list[i], dma.request_sizes[i]); } sleep(secs); drmFreeBufs(fd, dma.granted_count, indices); } break; case 'b': count = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); if ((r = drmAddBufs(fd, count, size, 0, 65536)) < 0) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } if ((r = drmMarkBufs(fd, 0.50, 0.80))) { drmError(r, argv[0]); return 1; } if (!(info = drmGetBufInfo(fd))) { drmError(0, argv[0]); return 1; } for (i = 0; i < info->count; i++) { printf("%5d buffers of size %6d (low = %d, high = %d)\n", info->list[i].count, info->list[i].size, info->list[i].low_mark, info->list[i].high_mark); } printf("===== /proc/dri/0/mem =====\n"); sprintf(buf, "cat /proc/dri/0/mem"); system(buf); #if 1 if (!(bufs = drmMapBufs(fd))) { drmError(0, argv[0]); return 1; } printf("===============================\n"); printf( "%d bufs\n", bufs->count); for (i = 0; i < bufs->count; i++) { printf( " %4d: %8d bytes at %p\n", i, bufs->list[i].total, bufs->list[i].address); } printf("===== /proc/dri/0/vma =====\n"); sprintf(buf, "cat /proc/dri/0/vma"); system(buf); #endif break; case 'f': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_FRAME_BUFFER, 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); sprintf(buf, "cat /proc/dri/0/mem"); system(buf); break; case 'r': case 'R': offset = strtoul(optarg, &pt, 0); size = strtoul(pt+1, NULL, 0); handle = 0; if ((r = drmAddMap(fd, offset, size, DRM_REGISTERS, c == 'R' ? DRM_READ_ONLY : 0, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%08lx:0x%04lx added\n", offset, size); printf("===== /proc/dri/0/mem =====\n"); sprintf(buf, "cat /proc/dri/0/mem"); system(buf); break; case 's': size = strtoul(optarg, &pt, 0); handle = 0; if ((r = drmAddMap(fd, 0, size, DRM_SHM, DRM_CONTAINS_LOCK, &handle))) { drmError(r, argv[0]); return 1; } printf("0x%04lx byte shm added at 0x%08lx\n", size, handle); sprintf(buf, "cat /proc/dri/0/vm"); /* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw */ /* * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Sung-Ching Lin <sclin@sis.com.tw> * */ #ifndef __SIS_DS_H__ #define __SIS_DS_H__ /* Set Data Structure */ #define SET_SIZE 5000 typedef unsigned long ITEM_TYPE; typedef struct { ITEM_TYPE val; int alloc_next, free_next; } list_item_t; typedef struct { int alloc; int free; int trace; list_item_t list[SET_SIZE]; } set_t; set_t *setInit(void); int setAdd(set_t * set, ITEM_TYPE item); int setDel(set_t * set, ITEM_TYPE item); int setFirst(set_t * set, ITEM_TYPE * item); int setNext(set_t * set, ITEM_TYPE * item); int setDestroy(set_t * set); /* * GLX Hardware Device Driver common code * Copyright (C) 1999 Wittawat Yamwong * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ struct mem_block_t { struct mem_block_t *next; struct mem_block_t *heap; int ofs, size; int align; unsigned int free:1; unsigned int reserved:1; }; typedef struct mem_block_t TMemBlock; typedef struct mem_block_t *PMemBlock; /* a heap is just the first block in a chain */ typedef struct mem_block_t memHeap_t; static __inline__ int mmBlockSize(PMemBlock b) { return b->size; } static __inline__ int mmOffset(PMemBlock b) { return b->ofs; } static __inline__ void mmMarkReserved(PMemBlock b) { b->reserved = 1; } /* * input: total size in bytes * return: a heap pointer if OK, NULL if error */ memHeap_t *mmInit(int ofs, int size); /* * Allocate 'size' bytes with 2^align2 bytes alignment, * restrict the search to free memory after 'startSearch' * depth and back buffers should be in different 4mb banks * to get better page hits if possible * input: size = size of block * align2 = 2^align2 bytes alignment * startSearch = linear offset from start of heap to begin search * return: pointer to the allocated block, 0 if error */ PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch); /* * Returns 1 if the block 'b' is part of the heap 'heap' */ int mmBlockInHeap(PMemBlock heap, PMemBlock b); /* * Free block starts at offset * input: pointer to a block * return: 0 if OK, -1 if error */ int mmFreeMem(PMemBlock b); /* For debuging purpose. */ void mmDumpMemInfo(memHeap_t * mmInit); #endif /* __SIS_DS_H__ */