Untitled
unknown
plain_text
a year ago
6.0 kB
7
Indexable
#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;
}Editor is loading...
Leave a Comment