diff --git a/.gitignore b/.gitignore index 8acabb0..1543317 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ gddr6 +build/ +*.o +*.a diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..341e2b2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +# CMakeLists.txt +cmake_minimum_required(VERSION 3.10) + +project(gddr6_project) + +add_subdirectory(lib) +add_subdirectory(app) + +install(TARGETS gddr6 + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin +) + +install(TARGETS gddr6_lib + ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib +) diff --git a/Makefile b/Makefile deleted file mode 100644 index f7d1f61..0000000 --- a/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -all: - gcc -std=c11 -O3 -Wall -Werror -Wextra -Wshadow -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wvla -o gddr6 gddr6.c -lpci -clean: - rm -f gddr6 -install: - cp gddr6 /usr/local/bin/ diff --git a/README.md b/README.md index 79f21db..2ddcc97 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,12 @@ sudo update-grub sudo reboot ``` -## Clone & Run +## Installation (cmake) ``` git clone https://github.com/olealgoritme/gddr6 -cd gddr6 && make && sudo ./gddr6 +cd gddr6 +./build_install.sh +sudo gddr6 ``` ## Supported GPUs diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 0000000..9af7611 --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,13 @@ +# ./app/CMakeLists.txt +cmake_minimum_required(VERSION 3.10) + +project(gddr6_app) +set(APP_SOURCES src/app.c) +add_executable(gddr6 ${APP_SOURCES}) + +target_link_libraries(gddr6 PRIVATE gddr6_lib) +target_link_libraries(gddr6 PRIVATE pci) + +set_target_properties(gddr6 PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) diff --git a/app/src/app.c b/app/src/app.c new file mode 100644 index 0000000..b2cece7 --- /dev/null +++ b/app/src/app.c @@ -0,0 +1,26 @@ +// app.c +#include "gddr6.h" +#include +#include + +int main(int argc, char **argv) { + struct device devices[32]; + int num_devs = gddr6_detect_compatible_gpus(devices, 32); + + if (num_devs == 0) { + printf("No compatible GPU found.\n"); + return 1; + } + + for (int i = 0; i < num_devs; i++) { + struct device *device = &devices[i]; + printf("Device: %s %s (%s / 0x%04x) pci=%x:%x:%x\n", device->name, device->vram, + device->arch, device->dev_id, device->bus, device->dev, device->func); + } + + gddr6_initialize(); + gddr6_monitor_temperatures(devices, num_devs); + gddr6_cleanup(0); + + return 0; +} diff --git a/build_install.sh b/build_install.sh new file mode 100755 index 0000000..ea1923d --- /dev/null +++ b/build_install.sh @@ -0,0 +1,30 @@ +# build_install.sh + +#!/bin/sh + +echo "Creating build directory..." +mkdir -p build && cd build + +echo "Running cmake..." +cmake .. + +echo "Building..." +cmake --build . --config Release + +echo "" +read -p "Do you want to SUDO CMAKE INSTALL libgddr6.a and gddr6 binary to /usr/local? (y/n) " answer + +case $answer in +[Yy]*) + sudo cmake --install . --prefix /usr/local + echo "Installing..." + ;; +[Nn]*) + echo "Skipping installation." + ;; +*) + echo "Please answer y or n." + ;; +esac + +cd .. diff --git a/gddr6_use.gif b/gddr6_use.gif deleted file mode 100644 index 7ef2a86..0000000 Binary files a/gddr6_use.gif and /dev/null differ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..7d8437b --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,13 @@ +# ./lib/CMakeLists.txt +cmake_minimum_required(VERSION 3.10) +project(gddr6_lib) +set(LIB_SOURCES src/gddr6.c) + +# Static library (libgddr6) +add_library(gddr6_lib STATIC ${LIB_SOURCES}) +target_include_directories(gddr6_lib PUBLIC include) + +set_target_properties(gddr6_lib PROPERTIES + OUTPUT_NAME "gddr6" # rename libgddr6_lib.a to libgddr6.a + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" +) diff --git a/lib/include/gddr6.h b/lib/include/gddr6.h new file mode 100644 index 0000000..c76e3be --- /dev/null +++ b/lib/include/gddr6.h @@ -0,0 +1,22 @@ +// gddr6.h +#ifndef GDDR6_H +#define GDDR6_H + +#include + +struct device { + uint32_t bar0; + uint8_t bus, dev, func; + uint32_t offset; + uint16_t dev_id; + const char *vram; + const char *arch; + const char *name; +}; + +void gddr6_initialize(void); +void gddr6_cleanup(int signal); +void gddr6_monitor_temperatures(const struct device *devices, int num_devices); +int gddr6_detect_compatible_gpus(struct device *devices, int max_devices); + +#endif // GDDR6_H diff --git a/gddr6.c b/lib/src/gddr6.c similarity index 67% rename from gddr6.c rename to lib/src/gddr6.c index b494365..f570586 100644 --- a/gddr6.c +++ b/lib/src/gddr6.c @@ -1,5 +1,7 @@ +// gddr6.c #define _GNU_SOURCE +#include "gddr6.h" #include #include #include @@ -12,33 +14,16 @@ #include #define PG_SZ sysconf(_SC_PAGE_SIZE) -#define PRINT_ERROR() \ +#define PRINT_ERROR() \ do { \ fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ __LINE__, __FILE__, errno, strerror(errno)); exit(1); \ } while(0) +static int fd = -1; +static void *map_base = MAP_FAILED; +static struct device devices[32]; -// device struct -struct device -{ - uint32_t bar0; - uint8_t bus, dev, func; - uint32_t offset; - uint16_t dev_id; - const char *vram; - const char *arch; - const char *name; -}; - - -// variables -int fd; -void *map_base; -struct device devices[32]; - - -// device table struct device dev_table[] = { { .offset = 0x0000E2A8, .dev_id = 0x2684, .vram = "GDDR6X", .arch = "AD102", .name = "RTX 4090" }, @@ -62,47 +47,15 @@ struct device dev_table[] = }; -// prototypes -void cleanup(int signal); -void cleanup_sig_handler(void); -int pci_detect_dev(void); - - -// cleanup -void cleanup(int signal) +void gddr6_initialize(void) { - if (signal == SIGHUP || signal == SIGINT || signal == SIGTERM) - { - if (map_base != (void *) -1) - munmap(map_base, PG_SZ); - if (fd != -1) - close(fd); - exit(0); + const char *MEM = "/dev/mem"; + if ((fd = open(MEM, O_RDONLY)) == -1) { + PRINT_ERROR(); } } - -// cleanup signal handler -void cleanup_sig_handler(void) -{ - struct sigaction sa; - sa.sa_handler = &cleanup; - sa.sa_flags = 0; - sigfillset(&sa.sa_mask); - - if (sigaction(SIGINT, &sa, NULL) < 0) - perror("Cannot handle SIGINT"); - - if (sigaction(SIGHUP, &sa, NULL) < 0) - perror("Cannot handle SIGHUP"); - - if (sigaction(SIGTERM, &sa, NULL) < 0) - perror("Cannot handle SIGTERM"); -} - - -// pci device detection -int pci_detect_dev(void) +int gddr6_detect_compatible_gpus(struct device *devices, int max_devices) { struct pci_access *pacc = NULL; struct pci_dev *pci_dev = NULL; @@ -135,57 +88,46 @@ int pci_detect_dev(void) return num_devs; } - -int main(int argc, char **argv) +void gddr6_cleanup(int signal) +{ + if (map_base != MAP_FAILED) + { + munmap(map_base, PG_SZ); + map_base = MAP_FAILED; + } + + if (fd != -1) + { + close(fd); + fd = -1; + } + + exit(signal); +} + +void gddr6_monitor_temperatures(const struct device *devices, int num_devices) { - (void) argc; - (void) argv; void *virt_addr; uint32_t temp; uint32_t phys_addr; uint32_t read_result; uint32_t base_offset; - int num_devs; - char *MEM = "\x2f\x64\x65\x76\x2f\x6d\x65\x6d"; - - num_devs = pci_detect_dev(); - - if (num_devs == 0) - { - printf("No compatible GPU found\n."); - exit(-1); - } - - for (int i = 0; i < num_devs; i++) { - struct device *device = &devices[i]; - printf("Device: %s %s (%s / 0x%04x) pci=%x:%x:%x\n", device->name, device->vram, - device->arch, device->dev_id, device->bus, device->dev, device->func); - } - - if ((fd = open(MEM, O_RDONLY)) == -1) - { - printf("Can't read memory. If you are root, enable kernel parameter iomem=relaxed\n"); - PRINT_ERROR(); - } - - cleanup_sig_handler(); - - - while (1) + while (1) { printf("\rVRAM Temps: |"); - for (int i = 0; i < num_devs; i++) { - struct device *device = &devices[i]; - + for (int i = 0; i < num_devices; i++) + { + const struct device *device = &devices[i]; phys_addr = (device->bar0 + device->offset); base_offset = phys_addr & ~(PG_SZ-1); map_base = mmap(0, PG_SZ, PROT_READ, MAP_SHARED, fd, base_offset); - - if(map_base == (void *) -1) + if(map_base == (void *) MAP_FAILED) { if (fd != -1) + { close(fd); + } printf("Can't read memory. If you are root, enable kernel parameter iomem=relaxed\n"); PRINT_ERROR(); } @@ -198,6 +140,4 @@ int main(int argc, char **argv) fflush(stdout); sleep(1); } - - return 0; }