123 lines
3.1 KiB
Bash
123 lines
3.1 KiB
Bash
#!/bin/bash
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
# Copyright (C) 2026 David (Corey) Herrera
|
|
# bar1_setpci_probe.sh — Read GK210 BAR config via setpci while die is acquired
|
|
# Run as root on server with bar_swap loaded
|
|
|
|
set -e
|
|
|
|
BDF="03:00.0" # Die 0
|
|
|
|
echo "=== BAR1 Size Probe via setpci ==="
|
|
echo ""
|
|
|
|
# Step 1: Acquire die 0 using the test binary (we'll hold it with a backgrounded process)
|
|
# Instead, use a simple C program that acquires, sleeps, then releases
|
|
|
|
cat > /tmp/hold_die.c << 'CEOF'
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/ioctl.h>
|
|
#include <stdint.h>
|
|
|
|
/* Inline the ioctl definitions */
|
|
#define BAR_SWAP_MAGIC 'B'
|
|
struct bs_acquire_req {
|
|
uint32_t die_id;
|
|
uint32_t flags;
|
|
uint64_t bar0_addr;
|
|
uint64_t bar1_addr;
|
|
uint64_t bar1_size;
|
|
uint64_t bar3_addr;
|
|
};
|
|
struct bs_release_req {
|
|
uint32_t die_id;
|
|
uint32_t flags;
|
|
};
|
|
#define BAR_SWAP_ACQUIRE _IOWR(BAR_SWAP_MAGIC, 4, struct bs_acquire_req)
|
|
#define BAR_SWAP_RELEASE _IOW(BAR_SWAP_MAGIC, 5, struct bs_release_req)
|
|
|
|
int main(int argc, char **argv) {
|
|
int fd = open("/dev/bar_swap", O_RDWR);
|
|
if (fd < 0) { perror("open"); return 1; }
|
|
|
|
struct bs_acquire_req aq = { .die_id = 0, .flags = 0 };
|
|
if (ioctl(fd, BAR_SWAP_ACQUIRE, &aq) < 0) { perror("acquire"); close(fd); return 1; }
|
|
printf("ACQUIRED bar0=0x%lx bar1=0x%lx\n", (unsigned long)aq.bar0_addr, (unsigned long)aq.bar1_addr);
|
|
fflush(stdout);
|
|
|
|
/* Wait for signal */
|
|
pause();
|
|
|
|
struct bs_release_req rr = { .die_id = 0, .flags = 0 };
|
|
ioctl(fd, BAR_SWAP_RELEASE, &rr);
|
|
printf("RELEASED\n");
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
CEOF
|
|
|
|
gcc -o /tmp/hold_die /tmp/hold_die.c
|
|
echo "Compiled hold_die"
|
|
|
|
# Acquire die 0 in background
|
|
/tmp/hold_die &
|
|
HOLD_PID=$!
|
|
sleep 1
|
|
echo "Die 0 acquired (PID $HOLD_PID)"
|
|
echo ""
|
|
|
|
# Step 2: Read current state via setpci
|
|
echo "--- Current Config Space ---"
|
|
echo "Vendor/Device: $(setpci -s $BDF 00.L)"
|
|
echo "CMD register: $(setpci -s $BDF 04.W)"
|
|
echo ""
|
|
for i in 0 1 2 3 4 5; do
|
|
OFF=$(printf "%02x" $((0x10 + i * 4)))
|
|
echo "BAR$i (0x$OFF): $(setpci -s $BDF $OFF.L)"
|
|
done
|
|
echo ""
|
|
|
|
# Step 3: Disable memory decode
|
|
ORIG_CMD=$(setpci -s $BDF 04.W)
|
|
setpci -s $BDF 04.W=0000
|
|
echo "Decode disabled (CMD was 0x$ORIG_CMD, now 0x$(setpci -s $BDF 04.W))"
|
|
echo ""
|
|
|
|
# Step 4: Save original BAR1 values (BAR1 = offset 0x14, BAR2 = offset 0x18 for 64-bit)
|
|
# First figure out which BAR is the 64-bit prefetchable one
|
|
echo "--- Probing BAR sizes ---"
|
|
echo "Writing 0xFFFFFFFF to each BAR, reading back size mask..."
|
|
echo ""
|
|
|
|
for i in 0 1 2 3 4 5; do
|
|
OFF=$(printf "%02x" $((0x10 + i * 4)))
|
|
ORIG=$(setpci -s $BDF $OFF.L)
|
|
|
|
# Write all-ones
|
|
setpci -s $BDF $OFF.L=FFFFFFFF
|
|
|
|
# Read back mask
|
|
MASK=$(setpci -s $BDF $OFF.L)
|
|
|
|
# Restore
|
|
setpci -s $BDF $OFF.L=$ORIG
|
|
|
|
echo "BAR$i: orig=0x$ORIG mask=0x$MASK"
|
|
done
|
|
echo ""
|
|
|
|
# Step 5: Restore CMD
|
|
setpci -s $BDF 04.W=$ORIG_CMD
|
|
echo "Decode restored (CMD=0x$(setpci -s $BDF 04.W))"
|
|
|
|
# Step 6: Release die
|
|
kill $HOLD_PID 2>/dev/null
|
|
wait $HOLD_PID 2>/dev/null
|
|
echo ""
|
|
echo "Die released."
|
|
echo ""
|
|
echo "=== Done ==="
|