Created
July 30, 2025 15:58
-
-
Save chadbrewbaker/1872da5d8cc67ea020131892699ed41c to your computer and use it in GitHub Desktop.
Grok4 spike on egpu address mapping
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <IOKit/IOKitLib.h> | |
| #include <CoreFoundation/CoreFoundation.h> | |
| #include <stdio.h> | |
| #include <stdint.h> | |
| #include <mach/mach_port.h> | |
| typedef struct { | |
| uint32_t spaceType; | |
| uint32_t bitWidth; | |
| uint64_t options; | |
| union { | |
| uint64_t addr64; | |
| } address; | |
| uint64_t value; | |
| } IOPCIDiagnosticsParameters; | |
| enum { | |
| kIOPCIConfigSpace = 0, | |
| kIOPCI32BitMemorySpace = 1, | |
| kIOPCI64BitMemorySpace = 2, | |
| kIOPCIIOSpace = 3 | |
| }; | |
| enum { | |
| kIOPCIDiagnosticsMethodRead = 0, | |
| kIOPCIDiagnosticsMethodWrite = 1 | |
| }; | |
| kern_return_t write_config(io_connect_t conn, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t offset, uint32_t width, uint64_t value) { | |
| IOPCIDiagnosticsParameters param = {0}; | |
| param.spaceType = kIOPCIConfigSpace; | |
| param.bitWidth = width; | |
| param.options = 0; | |
| param.address.addr64 = ((uint64_t)bus << 24) | ((uint64_t)dev << 16) | ((uint64_t)fn << 8) | offset; | |
| param.value = value; | |
| size_t paramSize = sizeof(param); | |
| return IOConnectCallStructMethod(conn, kIOPCIDiagnosticsMethodWrite, ¶m, sizeof(param), ¶m, ¶mSize); | |
| } | |
| kern_return_t read_config(io_connect_t conn, uint8_t bus, uint8_t dev, uint8_t fn, uint16_t offset, uint32_t width, uint64_t *value) { | |
| IOPCIDiagnosticsParameters param = {0}; | |
| param.spaceType = kIOPCIConfigSpace; | |
| param.bitWidth = width; | |
| param.options = 0; | |
| param.address.addr64 = ((uint64_t)bus << 24) | ((uint64_t)dev << 16) | ((uint64_t)fn << 8) | offset; | |
| param.value = 0; | |
| size_t paramSize = sizeof(param); | |
| kern_return_t kr = IOConnectCallStructMethod(conn, kIOPCIDiagnosticsMethodRead, ¶m, sizeof(param), ¶m, ¶mSize); | |
| if (kr == kIOReturnSuccess) { | |
| *value = param.value; | |
| } | |
| return kr; | |
| } | |
| int main() { | |
| kern_return_t kr; | |
| io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOHIDevice")); | |
| if (!service) { | |
| printf("Failed to find IOHIDevice\n"); | |
| return 1; | |
| } | |
| kr = IORegistryEntrySetCFProperty(service, CFSTR("IOUserClientClass"), CFSTR("IOPCIDiagnosticsClient")); | |
| if (kr != kIOReturnSuccess) { | |
| printf("Failed to set IOUserClientClass: 0x%x\n", kr); | |
| IOObjectRelease(service); | |
| return 1; | |
| } | |
| io_connect_t conn; | |
| kr = IOServiceOpen(service, mach_task_self(), 0, &conn); | |
| IOObjectRelease(service); | |
| if (kr != kIOReturnSuccess) { | |
| printf("Failed to open service: 0x%x\n", kr); | |
| return 1; | |
| } | |
| // Assume Thunderbolt bridge PCI address: bus 0, device 7, function 0 (replace with actual from ioreg -l) | |
| uint8_t bus = 0; | |
| uint8_t dev = 7; | |
| uint8_t fn = 0; | |
| // Example: Enable memory decoding on the bridge | |
| uint64_t command; | |
| kr = read_config(conn, bus, dev, fn, 0x04, 32, &command); | |
| if (kr == kIOReturnSuccess) { | |
| command |= 0x6; // Enable memory and bus master | |
| kr = write_config(conn, bus, dev, fn, 0x04, 32, command); | |
| if (kr != kIOReturnSuccess) { | |
| printf("Failed to write command register: 0x%x\n", kr); | |
| } else { | |
| printf("Enabled memory on bridge\n"); | |
| } | |
| } else { | |
| printf("Failed to read command register: 0x%x\n", kr); | |
| } | |
| // Set large prefetch memory window (example values; adjust based on needs and available address space) | |
| // Prefetch base upper 32 bits: 0x00000001 (for base 0x100000000) | |
| kr = write_config(conn, bus, dev, fn, 0x28, 32, 0x00000001); | |
| // Prefetch limit upper 32 bits: 0x00000003 (for limit 0x3ffffffff) | |
| kr = write_config(conn, bus, dev, fn, 0x2C, 32, 0x00000003); | |
| // Prefetch base/ limit lower: base 0x0000, limit 0xFFF0, with 64bit indicator | |
| kr = write_config(conn, bus, dev, fn, 0x24, 32, 0xFFF00001); // base low 0x0001 (64bit), limit low 0xFFF0 | |
| if (kr == kIOReturnSuccess) { | |
| printf("Set large prefetch memory window on Thunderbolt bridge\n"); | |
| } else { | |
| printf("Failed to set memory window: 0x%x\n", kr); | |
| } | |
| IOServiceClose(conn); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment