zoukankan      html  css  js  c++  java
  • dpdk uio

    root@gobgp:~# lspci | grep -i ether
    01:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
    07:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
    root@gobgp:~# lspci -s 07:00.0
    07:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
    root@gobgp:~# lspci -s 07:00.0 -v
    07:00.0 Ethernet controller: Red Hat, Inc. Virtio network device (rev 01)
            Subsystem: Red Hat, Inc. Virtio network device
            Physical Slot: 0-6
            Flags: bus master, fast devsel, latency 0, IRQ 38
            Memory at 10c40000 (32-bit, non-prefetchable) [size=4K]
            Memory at 8000c00000 (64-bit, prefetchable) [size=16K]
            Expansion ROM at 10c00000 [disabled] [size=256K]
            Capabilities: [dc] MSI-X: Enable- Count=3 Masked-
            Capabilities: [c8] Vendor Specific Information: VirtIO: <unknown>
            Capabilities: [b4] Vendor Specific Information: VirtIO: Notify
            Capabilities: [a4] Vendor Specific Information: VirtIO: DeviceCfg
            Capabilities: [94] Vendor Specific Information: VirtIO: ISR
            Capabilities: [84] Vendor Specific Information: VirtIO: CommonCfg
            Capabilities: [7c] Power Management version 3
            Capabilities: [40] Express Endpoint, MSI 00
            Kernel driver in use: uio_pci_generic
    
    root@gobgp:~# 
    root@gobgp:~# cat /sys/bus/pci/drivers/uio_pci_generic/bind
    cat: /sys/bus/pci/drivers/uio_pci_generic/bind: Permission denied
     
    root@gobgp:~# ls -l /sys/bus/pci/devices/0000:07:00.0
    lrwxrwxrwx 1 root root 0 Aug 24 14:20 /sys/bus/pci/devices/0000:07:00.0 -> ../../../devices/pci0000:00/0000:00:01.6/0000:07:00.0
    root@gobgp:~# ls -l /sys/bus/pci/devices/0000:07:00.0/driver 
    lrwxrwxrwx 1 root root 0 Aug 24 14:20 /sys/bus/pci/devices/0000:07:00.0/driver -> ../../../../bus/pci/drivers/uio_pci_generic
    root@gobgp:~#
    root@gobgp:~# cat /dev/uio0
    cat: /dev/uio0: Invalid argument
    root@gobgp:~# 
    Example code using uio_pci_generic
    Here is some sample userspace driver code using uio_pci_generic:
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    
    int main()
    {
        int uiofd;
        int configfd;
        int err;
        int i;
        unsigned icount;
        unsigned char command_high;
    
        uiofd = open("/dev/uio0", O_RDONLY);
        if (uiofd < 0) {
            perror("uio open:");
            return errno;
        }
        configfd = open("/sys/class/uio/uio0/device/config", O_RDWR);
        if (configfd < 0) {
            perror("config open:");
            return errno;
        }
    
        /* Read and cache command value */
        err = pread(configfd, &command_high, 1, 5);
        if (err != 1) {
            perror("command config read:");
            return errno;
        }
        command_high &= ~0x4;
    
        for(i = 0;; ++i) {
            /* Print out a message, for debugging. */
            if (i == 0)
                fprintf(stderr, "Started uio test driver.
    ");
            else
                fprintf(stderr, "Interrupts: %d
    ", icount);
    
            /****************************************/
            /* Here we got an interrupt from the
               device. Do something to it. */
            /****************************************/
    
            /* Re-enable interrupts. */
            err = pwrite(configfd, &command_high, 1, 5);
            if (err != 1) {
                perror("config write:");
                break;
            }
    
            /* Wait for next interrupt. */
            err = read(uiofd, &icount, 4);
            if (err != 4) {
                perror("uio read:");
                break;
            }
    
        }
        return errno;
    }

     

    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdint.h>
    #include <sys/mman.h>
    
    
    #define EDU_IO_SIZE 0x100
    #define EDU_CARD_VERSION_ADDR  0x0
    #define EDU_CARD_LIVENESS_ADDR 0x1
    #define EDU_RAISE_INT_ADDR 0x18
    #define EDU_CLEAR_INT_ADDR 0x19
    
    int main()
    {
        int uiofd;
        int configfd;
        int bar0fd;
        int resetfd;
        int err;
        int i;
        unsigned icount;
        unsigned char command_high;
        volatile uint32_t *bar0;
    
        uiofd = open("/dev/uio0", O_RDWR);
        if (uiofd < 0) {
            perror("uio open:");
            return errno;
        }
    
        configfd = open("/sys/class/uio/uio0/device/config", O_RDWR);
        if (configfd < 0) {
            perror("config open:");
            return errno;
        }
    
        /* Read and cache command value */
        err = pread(configfd, &command_high, 1, 5);
        if (err != 1) {
            perror("command config read:");
            return errno;
        }
        command_high &= ~0x4;
    
        /* Map edu's MMIO */
        bar0fd = open("/sys/class/uio/uio0/device/resource0", O_RDWR);
        if (bar0fd < 0) {
            perror("bar0fd open:");
            return errno;
        }
    
        /* mmap the device's BAR */
        bar0 = (volatile uint32_t *)mmap(NULL, EDU_IO_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, bar0fd, 0);
        if (bar0 == MAP_FAILED) {
            perror("Error mapping bar0!");
            return errno;
        }
        fprintf(stdout, "Version = %08X
    ", bar0[EDU_CARD_VERSION_ADDR]);
    
        /* Test the invertor function */
        i = 0x12345678;
        bar0[EDU_CARD_LIVENESS_ADDR] = i;
        fprintf(stdout, "Inversion: %08X --> %08X
    ", i, bar0[EDU_CARD_LIVENESS_ADDR]);
    
        /* Clear previous interrupt */
        bar0[EDU_CLEAR_INT_ADDR] = 0xABCDABCD;
    
        /* Raise an interrupt */
        bar0[EDU_RAISE_INT_ADDR] = 0xABCDABCD;
    
        for(i = 0;; ++i) {
            /* Print out a message, for debugging. */
            if (i == 0)
                fprintf(stderr, "Started uio test driver.
    ");
            else
                fprintf(stderr, "Interrupts: %d
    ", icount);
    
            /****************************************/
            /* Here we got an interrupt from the
               device. Do something to it. */
            /****************************************/
    
            /* Re-enable interrupts. */
            err = pwrite(configfd, &command_high, 1, 5);
            if (err != 1) {
                perror("config write:");
                break;
            }
    
            /* Clear previous interrupt */
            bar0[EDU_CLEAR_INT_ADDR] = 0xABCDABCD;
    
            /* Raise an interrupt */
            bar0[EDU_RAISE_INT_ADDR] = 0xABCDABCD;
    
            /* Wait for next interrupt. */
            err = read(uiofd, &icount, 4);
            if (err != 4) {
                perror("uio read:");
                break;
            }
    
        }
        return errno;
    }
    The result looks something like this:
    
    Version = 010000ED
    Inversion: 12345678 --> EDCBA987
    Started uio test driver.
    Interrupts: 3793548
    Interrupts: 3793549
    Interrupts: 3793550
    Interrupts: 3793551
    Interrupts: 3793552
    Interrupts: 3793553
    Interrupts: 3793554
    Interrupts: 3793555
    Interrupts: 3793556
    ...

    dpdk uio

    ./usertools/dpdk-devbind.py  --bind=igb_uio  0000:06:00.0
    [root@localhost dpdk-19.11]# ls /sys/bus/pci/devices/0000:06:00.0/u
    uevent  uio/    
    [root@localhost dpdk-19.11]# ls /sys/bus/pci/devices/0000:06:00.0/uio/
    uio0
    [root@localhost dpdk-19.11]# ls /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/
    map0  map1  map2
    [root@localhost dpdk-19.11]# 

     

    [root@localhost dpdk-19.11]# ls /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map0
    addr  name  offset  size
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map0/addr 
    0x0000080010400000
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map0/name
    BAR0
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map0/offset 
    0x0
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map0/size
    0x0000000000020000
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map1/addr 
    0x0000080011320000
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map2/addr 
    0x0000080008b00000
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map1/name
    BAR2
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/uio/uio0/maps/map2/name
    BAR4
    [root@localhost dpdk-19.11]# 
    [root@localhost dpdk-19.11]# lspci -s 0000:06:00.0 -v
    06:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (2*25GE) (rev 45)
            Subsystem: Huawei Technologies Co., Ltd. Device d139
            Flags: bus master, fast devsel, latency 0, NUMA node 0
            Memory at 80010400000 (64-bit, prefetchable) [size=128K]
            Memory at 80011320000 (64-bit, prefetchable) [size=32K]
            Memory at 80008b00000 (64-bit, prefetchable) [size=1M]
            Expansion ROM at e9300000 [disabled] [size=1M]
            Capabilities: [40] Express Endpoint, MSI 00
            Capabilities: [80] MSI: Enable- Count=1/32 Maskable+ 64bit+
            Capabilities: [a0] MSI-X: Enable- Count=32 Masked-
            Capabilities: [b0] Power Management version 3
            Capabilities: [c0] Vital Product Data
            Capabilities: [100] Advanced Error Reporting
            Capabilities: [150] Alternative Routing-ID Interpretation (ARI)
            Capabilities: [200] Single Root I/O Virtualization (SR-IOV)
            Capabilities: [310] #19
            Capabilities: [4e0] Device Serial Number 44-a1-91-ff-ff-a4-9b-ec
            Capabilities: [4f0] Transaction Processing Hints
            Capabilities: [600] Vendor Specific Information: ID=0000 Rev=0 Len=028 <?>
            Capabilities: [630] Access Control Services
            Kernel driver in use: igb_uio
            Kernel modules: hinic
    
    [root@localhost dpdk-19.11]# 
    [root@localhost dpdk-19.11]# cat /proc/iomem  | grep 0000:06:00.0
            e9300000-e93fffff : 0000:06:00.0
            80008b00000-80008bfffff : 0000:06:00.0
            80008c00000-800103fffff : 0000:06:00.0
            80010400000-8001041ffff : 0000:06:00.0
            80010420000-80010b9ffff : 0000:06:00.0
            80010ba0000-8001131ffff : 0000:06:00.0
            80011320000-80011327fff : 0000:06:00.0
    [root@localhost dpdk-19.11]# 
    [root@localhost dpdk-19.11]# ls  /sys/bus/pci/devices/0000:06:00.0/resource*
    /sys/bus/pci/devices/0000:06:00.0/resource   /sys/bus/pci/devices/0000:06:00.0/resource2
    /sys/bus/pci/devices/0000:06:00.0/resource0  /sys/bus/pci/devices/0000:06:00.0/resource4
    [root@localhost dpdk-19.11]# cat  /sys/bus/pci/devices/0000:06:00.0/resource*
    0x0000080010400000 0x000008001041ffff 0x000000000014220c
    0x0000000000000000 0x0000000000000000 0x0000000000000000
    0x0000080011320000 0x0000080011327fff 0x000000000014220c
    0x0000000000000000 0x0000000000000000 0x0000000000000000
    0x0000080008b00000 0x0000080008bfffff 0x000000000014220c
    0x0000000000000000 0x0000000000000000 0x0000000000000000
    0x00000000e9300000 0x00000000e93fffff 0x0000000000046200
    0x0000080010420000 0x0000080010b9ffff 0x000000000014220c
    0x0000000000000000 0x0000000000000000 0x0000000000000000
    0x0000080010ba0000 0x000008001131ffff 0x000000000014220c
    0x0000000000000000 0x0000000000000000 0x0000000000000000
    0x0000080008c00000 0x00000800103fffff 0x000000000014220c
    0x0000000000000000 0x0000000000000000 0x0000000000000000
    cat: /sys/bus/pci/devices/0000:06:00.0/resource0: Input/output error
    cat: /sys/bus/pci/devices/0000:06:00.0/resource2: Input/output error
    cat: /sys/bus/pci/devices/0000:06:00.0/resource4: Input/output error
    [root@localhost dpdk-19.11]#

     

    [root@localhost data1]# cat uio.c 
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <stdint.h>
    
    #define PAGE_SIZE 0x1000
    
    int main()
    {
        int fd;
        void *base;
        uint32_t *pmem;
    
        fd = open("/dev/uio0", O_RDWR);
        if (fd < 0) {
            fprintf(stderr, "Failed to open device
    ");
            exit(1);
        }
        base = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        if (base == MAP_FAILED) {
            fprintf(stderr, "Failed to mmap
    ");
            exit(1);
        }
    
        pmem = (uint32_t*)base;
    
        printf("pmem[0] = 0x%08x
    ", pmem[0]);
        printf("pmem[1] = 0x%08x
    ", pmem[1]);
    [root@localhost data1]# ./uio 
    pmem[0] = 0x01040080
    pmem[1] = 0x002250c1

     portio

    Since these ioport regions can not be mapped, they will not appear under /sys/class/uio/uioX/maps/ like the normal memory described above. Without information about the port regions a hardware has to offer, it becomes difficult for the userspace part of the driver to find out which ports belong to which UIO device.

    To address this situation, the new directory /sys/class/uio/uioX/portio/ was added. It only exists if the driver wants to pass information about one or more port regions to userspace. If that is the case, subdirectories named port0port1, and so on, will appear underneath /sys/class/uio/uioX/portio/.

    Each portX/ directory contains four read-only files that show name, start, size, and type of the port region:

    • name: A string identifier for this port region. The string is optional and can be empty. Drivers can set it to make it easier for userspace to find a certain port region.

    • start: The first port of this region.

    • size: The number of ports in this region.

    • porttype: A string describing the type of port.

    igb_uio & igb & ioremap & mmap

    igb_uio 驱动会遍历该 PCI 设备的 BAR 空间,对于类型为存储器空间 IORESOURCE_MEM 的 BAR(Memory BAR),将其物理地址、大小等信息保存到 uio_info 结构的 mem 数组中;将类型为寄存器空间 IORESOURCE_IO 的 BAR(IO BAR),将其物理地址、大小等信息保存到 uio_info 结构的 port 数组中。

    在这里插入图片描述

    [root@localhost dpdk-19.11]# lspci -s 0000:06:00.0 -v
    06:00.0 Ethernet controller: Huawei Technologies Co., Ltd. Hi1822 Family (2*25GE) (rev 45)
            Subsystem: Huawei Technologies Co., Ltd. Device d139
            Flags: fast devsel, NUMA node 0
            Memory at 80010400000 (64-bit, prefetchable) [size=128K]
            Memory at 80011320000 (64-bit, prefetchable) [size=32K]
            Memory at 80008b00000 (64-bit, prefetchable) [size=1M]
            Expansion ROM at e9300000 [disabled] [size=1M]
            Capabilities: [40] Express Endpoint, MSI 00
            Capabilities: [80] MSI: Enable- Count=1/32 Maskable+ 64bit+
            Capabilities: [a0] MSI-X: Enable- Count=32 Masked-
            Capabilities: [b0] Power Management version 3
            Capabilities: [c0] Vital Product Data
            Capabilities: [100] Advanced Error Reporting
            Capabilities: [150] Alternative Routing-ID Interpretation (ARI)
            Capabilities: [200] Single Root I/O Virtualization (SR-IOV)
            Capabilities: [310] #19
            Capabilities: [4e0] Device Serial Number 44-a1-91-ff-ff-a4-9b-ec
            Capabilities: [4f0] Transaction Processing Hints
            Capabilities: [600] Vendor Specific Information: ID=0000 Rev=0 Len=028 <?>
            Capabilities: [630] Access Control Services
            Kernel driver in use: igb_uio
            Kernel modules: hinic
    
    [root@localhost dpdk-19.11]#

    而 igb 驱动同样也会遍历 BAR 空间,但是它不会记录空间的物理地址,而是调用 ioremap() 将物理地址映射为虚拟地址,然后驱动就可以在内核态中读写映射出来的虚拟地址,而不是像 igb_uio 驱动似的在用户态中进行读写。

  • 相关阅读:
    bzoj2395: [Balkan 2011]Timeismoney
    bzoj2725: [Violet 6]故乡的梦&&bzoj4400: tjoi2012 桥
    bzoj3047: Freda的传呼机&bzoj2125: 最短路
    bzoj2734: [HNOI2012]集合选数
    bzoj2728: [HNOI2012]与非
    bzoj2730: [HNOI2012]矿场搭建
    bzoj2727: [HNOI2012]双十字
    蓝桥杯-计蒜客之节假日
    蔡基姆拉尔森计算公式
    最长公共子串与最长公共子序列
  • 原文地址:https://www.cnblogs.com/dream397/p/13553802.html
Copyright © 2011-2022 走看看