root complex in user space - MarekBykowski/readme GitHub Wiki

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <string.h>
#include <errno.h>

#include <linux/pci-doe.h>

#define DEV_PATH "/dev/avery_doe_chardev"

static const char *type_str(int t)
{
    switch (t) {
    case PCI_DOE_READ:  return "READ";
    case PCI_DOE_WRITE: return "WRITE";
    default:            return "UNKNOWN";
    }
}

int main(void)
{
    int fd;
    struct pollfd pfd;
    struct avery_pci_config_op op;

    fd = open(DEV_PATH, O_RDWR);
    if (fd < 0) {
        perror("open");
        return 1;
    }

    printf("Connected to %s\n", DEV_PATH);

    pfd.fd = fd;
    pfd.events = POLLIN;

    while (1) {
        int ret = poll(&pfd, 1, -1);
        if (ret < 0) {
            perror("poll");
            break;
        }

        if (pfd.revents & POLLIN) {

            ssize_t n = read(fd, &op, sizeof(op));
            if (n < 0) {
                perror("read");
                break;
            }

            printf("REQ: type=%s offset=0x%x value=0x%x\n",
                   type_str(op.type), op.offset, op.value);

            /* --- emulate remote root complex --- */

            if (op.type == PCI_DOE_READ) {
                op.value = 0x12345678;  /* fake read value */
                op.status = 0;
            }

            if (op.type == PCI_DOE_WRITE) {
                printf("WRITE received value=0x%x\n", op.value);
                op.status = 0;
            }

            if (write(fd, &op, sizeof(op)) < 0) {
                perror("write");
                break;
            }

            printf("RESP sent\n");
        }
    }

    close(fd);
    return 0;
}
⚠️ **GitHub.com Fallback** ⚠️