Untitled
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <errno.h> #include <string.h> #include <stdint.h> #include <libdrm/drm.h> #include <xf86drm.h> #include <stdbool.h> #include "/usr/include/libdrm/drm.h" #include "/usr/include/xf86drm.h" #include <stdbool.h> // DRM formats for testing #define DRM_FORMAT_ARGB8888 0x34325241 #define DRM_FORMAT_XRGB8888 0x34325258 struct udmabuf_create { uint32_t memfd; uint32_t offset; uint32_t size; uint32_t flags; }; #define UDMABUF_CREATE _IOW('u', 0x42, struct udmabuf_create) static bool test_basic_memory(int fd, size_t size) { printf("\nTesting basic memory operations...\n"); void *buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (buffer == MAP_FAILED) { printf("Failed to mmap: %s\n", strerror(errno)); return false; } // Write pattern uint32_t *ptr = buffer; for (size_t i = 0; i < size/4; i++) { ptr[i] = i; } // Read and verify bool success = true; for (size_t i = 0; i < size/4; i++) { if (ptr[i] != i) { printf("Data mismatch at offset %zu: expected %zu, got %u\n", i, i, ptr[i]); success = false; break; } } munmap(buffer, size); return success; } static bool test_gpu_access(int dma_buf_fd) { printf("\nTesting GPU accessibility...\n"); // Try to open the render node int drm_fd = open("/dev/dri/renderD128", O_RDWR); if (drm_fd < 0) { printf("Failed to open render node: %s\n", strerror(errno)); return false; } // Get DRM version to verify it's a GPU device drmVersionPtr version = drmGetVersion(drm_fd); if (!version) { printf("Failed to get DRM version: %s\n", strerror(errno)); close(drm_fd); return false; } printf("DRM Device: %s\n", version->name); drmFreeVersion(version); // Try to import the buffer struct drm_prime_handle prime; memset(&prime, 0, sizeof(prime)); prime.fd = dma_buf_fd; prime.flags = DRM_CLOEXEC; if (ioctl(drm_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime) == -1) { printf("Failed to import buffer to GPU: %s\n", strerror(errno)); close(drm_fd); return false; } printf("Successfully imported buffer to GPU (handle: %u)\n", prime.handle); // Clean up struct drm_gem_close close_arg; memset(&close_arg, 0, sizeof(close_arg)); close_arg.handle = prime.handle; ioctl(drm_fd, DRM_IOCTL_GEM_CLOSE, &close_arg); close(drm_fd); return true; } static bool test_sync_operations(int fd) { printf("\nTesting sync operations...\n"); // Try to read sync mode char sync_mode[32]; FILE *fp = fopen("/sys/class/u-dma-buf/udmabuf0/sync_mode", "r"); if (fp) { fgets(sync_mode, sizeof(sync_mode), fp); printf("Current sync mode: %s", sync_mode); fclose(fp); } else { printf("Cannot read sync mode: %s\n", strerror(errno)); } // Try sync for device access fp = fopen("/sys/class/u-dma-buf/udmabuf0/sync_for_device", "w"); if (fp) { fprintf(fp, "1"); fclose(fp); printf("sync_for_device successful\n"); } else { printf("sync_for_device failed: %s\n", strerror(errno)); return false; } // Try sync for CPU access fp = fopen("/sys/class/u-dma-buf/udmabuf0/sync_for_cpu", "w"); if (fp) { fprintf(fp, "1"); fclose(fp); printf("sync_for_cpu successful\n"); } else { printf("sync_for_cpu failed: %s\n", strerror(errno)); return false; } return true; } static void print_buffer_info(int fd) { printf("\nBuffer Information:\n"); FILE *fp; char buf[256]; // Read phys_addr fp = fopen("/sys/class/u-dma-buf/udmabuf0/phys_addr", "r"); if (fp) { fgets(buf, sizeof(buf), fp); printf("Physical address: %s", buf); fclose(fp); } // Read size fp = fopen("/sys/class/u-dma-buf/udmabuf0/size", "r"); if (fp) { fgets(buf, sizeof(buf), fp); printf("Buffer size: %s", buf); fclose(fp); } // Read driver version fp = fopen("/sys/class/u-dma-buf/udmabuf0/driver_version", "r"); if (fp) { fgets(buf, sizeof(buf), fp); printf("Driver version: %s", buf); fclose(fp); } } int main() { int fd; bool all_tests_passed = true; const size_t test_size = 4194304; // 4MB printf("Starting comprehensive DMA buffer tests...\n"); // Open the DMA buffer device fd = open("/dev/udmabuf0", O_RDWR); if (fd < 0) { printf("Failed to open /dev/udmabuf0: %s\n", strerror(errno)); return 1; } // Print initial buffer information print_buffer_info(fd); // Test 1: Basic memory operations if (!test_basic_memory(fd, test_size)) { printf("Basic memory test FAILED\n"); all_tests_passed = false; } else { printf("Basic memory test PASSED\n"); } // Test 2: GPU accessibility if (!test_gpu_access(fd)) { printf("GPU accessibility test FAILED\n"); all_tests_passed = false; } else { printf("GPU accessibility test PASSED\n"); } // Test 3: Sync operations if (!test_sync_operations(fd)) { printf("Sync operations test FAILED\n"); all_tests_passed = false; } else { printf("Sync operations test PASSED\n"); } // Cleanup close(fd); printf("\nTest Summary:\n"); printf("Overall result: %s\n", all_tests_passed ? "PASSED" : "FAILED"); return all_tests_passed ? 0 : 1; }
Leave a Comment