zoukankan      html  css  js  c++  java
  • dpdk ioport mmap

    初始化分析

    一个设备驱动要实现的功能根据实际需要可能千差万别,但是究其本质来说无非两件事情:一个是内存的操作,另外一个就是中断的处理。Igb_uio驱动和igb驱动都是网卡这个PCI设备的驱动,相同点就是要使能PCI设备,分配内存等,不同的就在于对内存和中断的处理方式的差异。

    下面看下igb_uio驱动与igb驱动相比的probe函数的不同之处:

    ◆记录设备的资源

    igb_uio模块遍历此PCI设备BAR空间,对应于类型为存储器空间IORESOURCE_MEM的BAR,将其物理地址、大小等信息保存到uio_info结构的mem数组中之中;类型为寄存器空间IORESOURCE_IO的BAR,将其物理地址、大小等信息保存到uio_info结构的port数组中。

    从上图可知,此网卡PCI设备有三个BAR空间,BAR0类型为存储器空间,物理地址为0xfbd00000,大小为128K;BAR2类型为寄存器空间,物理地址为0xb000,大小为32字节;BAR3类型为存储器空间,物理地址为0xfbd40000,大小为16K。

    Igb驱动也会遍历BAR空间,但是它不会记录空间的物理地址,而是调用ioremap函数将物理地址映射为虚拟地址,驱动在内核态读写操作映射出来的虚拟地址。

    /** IO resource type: */
    #define IORESOURCE_IO 0x00000100
    #define IORESOURCE_MEM 0x00000200

     424 pci_uio_ioport_map(struct rte_pci_device *dev, int bar,
        425                    struct rte_pci_ioport *p)
        426 {
        427         FILE *f;
        428         char buf[BUFSIZ];
        429         char filename[PATH_MAX];
        430         uint64_t phys_addr, end_addr, flags;
        431         int fd, i;
        432         void *addr;
        433 
        434         /* open and read addresses of the corresponding resource in sysfs */
        435         snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource",
        436                 rte_pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
        437                 dev->addr.devid, dev->addr.function);
        438         f = fopen(filename, "r");
        439         if (f == NULL) {
        440                 RTE_LOG(ERR, EAL, "Cannot open sysfs resource: %s
    ",
        441                         strerror(errno));
        442                 return -1;
        443         }
        444         for (i = 0; i < bar + 1; i++) {
        445                 if (fgets(buf, sizeof(buf), f) == NULL) {
        446                         RTE_LOG(ERR, EAL, "Cannot read sysfs resource
    ");
        447                         goto error;
        448                 }
        449         }
        450         if (pci_parse_one_sysfs_resource(buf, sizeof(buf), &phys_addr,
        451                         &end_addr, &flags) < 0)
        452                 goto error;
        453         if ((flags & IORESOURCE_IO) == 0) {
    454                 RTE_LOG(ERR, EAL, "BAR %d is not an IO resource
    ", bar);
        455                 goto error;
        456         }
        457         snprintf(filename, sizeof(filename), "%s/" PCI_PRI_FMT "/resource%d",
        458                 rte_pci_get_sysfs_path(), dev->addr.domain, dev->addr.bus,
        459                 dev->addr.devid, dev->addr.function, bar);
        460 
        461         /* mmap the pci resource */
        462         fd = open(filename, O_RDWR);
        463         if (fd < 0) {
        464                 RTE_LOG(ERR, EAL, "Cannot open %s: %s
    ", filename,
        465                         strerror(errno));
        466                 goto error;
        467         }
        468         addr = mmap(NULL, end_addr + 1, PROT_READ | PROT_WRITE,
        469                 MAP_SHARED, fd, 0);
        470         close(fd);
        471         if (addr == MAP_FAILED) {
        472                 RTE_LOG(ERR, EAL, "Cannot mmap IO port resource: %s
    ",
        473                         strerror(errno));
        474                 goto error;
        475         }
        476 
        477         /* strangely, the base address is mmap addr + phys_addr */
        478         p->base = (uintptr_t)addr + phys_addr;
        479         p->len = end_addr + 1;
        480         RTE_LOG(DEBUG, EAL, "PCI Port IO found start=0x%"PRIx64"
    ", p->base);
        481         fclose(f);
        482 
        483         return 0;
    484 
        485 error:
        486         fclose(f);
        487         return -1;
        488 }

    rte_pci_ioport_map

    read & write

  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/dream397/p/13632686.html
Copyright © 2011-2022 走看看