head 1.1; access; symbols libdrm-1_0_4:1.1; locks; strict; comment @ * @; 1.1 date 2003.01.13.15.30.31; author jhartmann; state Exp; branches; next ; desc @@ 1.1 log @Add dri port of testagp application for public use @ text @#include #include #include #include #include "xf86drm.h" #include "xf86drmRandom.c" #include "xf86drmHash.c" #include "xf86drm.c" #include "agpgart.h" #include "agplib.h" int drmfd; unsigned char *gart; /* Call xchg and cpuid asm instructions to flush the write combining cache. * Could be replaced with sfence on some cpus or perhaps just the code * for mb() from the kernel */ void flushWriteCombining(void) { int xchangeDummy; __asm__ volatile(" push %%eax ; " " xchg %%eax, %0 ;" " pop %%eax" : : "m" (xchangeDummy)); __asm__ volatile(" push %%eax ; " " push %%ebx ; " " push %%ecx ; " " push %%edx ; " " movl $0,%%eax ; " " cpuid ; " " pop %%edx ; " " pop %%ecx ; " " pop %%ebx ; " " pop %%eax" : /* no outputs */ : /* no inputs */ ); } int bindMemory(unsigned long key, int page) { #if 0 printf("bind : 0x%08lx, page : %d\n", key, page); #endif if(drmAgpBind(drmfd, key, page << AGP_PAGE_SHIFT) < 0) { printf("agp bind failed\n"); perror(" "); exit(1); } return 0; } int unbindMemory(unsigned long key) { #if 0 printf("unbind : 0x%08lx\n", key); #endif if(drmAgpUnbind(drmfd, key) < 0) { printf("agp unbind failed\n"); exit(1); } return 0; } unsigned long allocMemory(int size) { int ret_val; drmHandle temp; ret_val = drmAgpAlloc(drmfd, size << AGP_PAGE_SHIFT, AGP_NORMAL_MEMORY, NULL, &temp); if(ret_val < 0) { printf("Agp alloc failed\n"); exit(1); } #if 0 printf("alloc : 0x%08lx, size : %d\n", temp, size); #endif return temp; } unsigned long allocAndBind(int page, int size) { unsigned long key = allocMemory(size); bindMemory(key, page); return key; } int freeMemory(unsigned long key) { return drmAgpFree(drmfd, key); } int getCurrentPages(void) { return drmAgpMemoryUsed(drmfd) >> AGP_PAGE_SHIFT; } int openAgpDevice(int flags, int argc, char **argv) { drmfd = drmOpenMinor(0, 1); if(!drmfd) { printf("open failed"); exit(1); } return 0; } size_t getApertureSize(void) { return drmAgpSize(drmfd) / 0x100000; } int supportsGetMap(void) { unsigned long ret_val; ret_val = drmAgpQueryHandleSize(drmfd, AGP_RESERVED_KEY); if(ret_val == (unsigned long)-1) return 0; return 1; } /* Always return true for now */ int checkPageAvailable(int page) { return 1; } int printReserved(void) { return 0; } void *agp_alloc_driver_info(int ctx) { return NULL; } int agp_copy_driver_info(int ctx, void *buffer) { return -1; } void agp_output_driver_info(void *ptr) { } /* For some reason my drm shell application won't let me map other types * of memory, need to compare what I'm doing different then the * Xserver. Bet it has to do with drmMagic and authentication. */ unsigned char *agp_map_memory(unsigned long key, off_t pg_ofs, size_t pages, unsigned long prot, unsigned long flags) { return NULL; } /* Drm doesn't really do this, so don't bother */ int agp_unmap_memory(int key, unsigned char *ptr) { return 0; } int agp_get_num_contexts(void) { return drmAgpGetNumContexts(drmfd); } int agp_change_context(int ctx) { return drmAgpChangeContext(drmfd, ctx);; } void agp_close_and_release(void) { close(drmfd); } drmHandle hSAREA; drmHandle hFRAME; drmAddress SAREA; static int fakeOutDri(void) { drmHandle hSAREA; unsigned long agp_base = drmAgpBase(drmfd); unsigned long agp_size = drmAgpSize(drmfd); printf("Using agp base : 0x%08lx\n", agp_base); if(drmSetBusid(drmfd, "0:0.0") < 0) { printf("set bus id failed\n"); exit(1); } if(drmAddMap(drmfd, 0, 4096, DRM_SHM, DRM_CONTAINS_LOCK, &hSAREA) < 0) { printf("SAREA create failed\n"); exit(1); } if(drmMap(drmfd, hSAREA, 4096, &SAREA) < 0) { printf("SAREA map failed\n"); exit(1); } if(drmAddMap(drmfd, agp_base, agp_size, DRM_FRAME_BUFFER, 0, &hFRAME) < 0) { printf("Adding fake framebuffer failed\n"); exit(1); } return 0; } /* do some add map stuff here, steal from Xserver code perhaps */ int initializeAgp(void) { int ret_val; unsigned long size; drmHandle agpSpace; drmAddress address; unsigned long mode; ret_val = drmAgpAcquire(drmfd); if(ret_val < 0) { printf("agp acquire failed\n"); exit(1); } size = drmAgpSize(drmfd); printf("Agp size : %dM\n", (int)(size / 0x100000)); /* Pretend to be the Xserver */ fakeOutDri(); /* setup gart to point to the agp aperture */ ret_val = drmAddMap(drmfd, 0, size, DRM_AGP, 0, &agpSpace); if(ret_val < 0) { printf("drm add map failed\n"); exit(1); } /* HACK HACK, map ourselves as a framebuffer, otherwise things won't work. */ ret_val = drmMap(drmfd, hFRAME, size, &address); if(ret_val < 0) { printf("drm map failed\n"); perror(" "); exit(1); } gart = (void *)address; /* Setup agp mode */ mode = drmAgpGetMode(drmfd); ret_val = drmAgpEnable(drmfd, mode); if(ret_val < 0) { printf("drm agp enable failed\n"); } /* Return aperture size */ return size / 0x100000; } static int getNumberOfPages(void) { unsigned long apertureSize = getApertureSize() * 0x100000; int numberPages = apertureSize / AGP_PAGE_SIZE; return numberPages; } /* Very stupid brute force approach to finding a slot of size, * if we want this to be fast we need to make a memory allocator of some * kind. This test code doesn't have to be terribly efficent so we * don't care. * This function only handles the reserved memory, nothing else at the * moment. Its all we need so don't worry. * * returns -1 if we can't find such a region. */ int findFirstRegionOfSize(int numberPages) { int pagesTotal = getNumberOfPages(); int i, k; for(i = 0; i < pagesTotal; i++) { if(checkPageAvailable(i) == TRUE) { /* We already know the first page is available */ for(k = 1; k < numberPages; k++) { if(checkPageAvailable(i + k) == FALSE) break; } /* Full region is available, return i as the index */ if(k == numberPages) return i; /* Okay we didn't get the full region and i + k is not available, * so we continue testing at i + k + 1 */ i = i + k + 1; } } return -1; } /* Agpgart specific tests which aren't important to us. */ void clientTest(int aper_size) { } void testMemoryFailures(int aper_size) { } void keyRecycleTest(void) { } @