PCIe 学习笔记(二)

pci note 2

-v0.1 2014.11.18 *** draft
 本文继续pci note 1, 介绍pci_create_root_bus函数, 内核版本为3.18-rc1

 调用关系:
 pci_scan_root_bus

     --> pci_create_root_bus

[cpp]  view plain  copy
  1. /* 
  2.  * device说明见下文,bus是根总线号,ops是配置空间读写函数的接口,需要驱动作者 
  3.  * 传入回调函数, 会在pci_scan_child_bus->pci_scan_slot->pci_scan_single_device-> 
  4.  * pci_scan_device->pci_bus_read_dev_vendor_id调用到该ops中的read函数。sysdata 
  5.  * 传入私有数据。resources链表的元素是struct pci_host_bridge_window, 是dts上 
  6.  * 读上来的总线号,mem空间,I/O空间的信息, 一般一个pci_host_bridge_window对应 
  7.  * 一个信息 
  8.  */  
  9. struct pci_bus *pci_create_root_bus(struct device *parent, int bus,  
  10.         struct pci_ops *ops, void *sysdata, struct list_head *resources)  
  11. {  
  12.     ...  
  13.     /* 
  14.      * 分配 struct pci_host_bridge, 初始化其中的windows链表 
  15.      * windows链表上的存的结构是:struct pci_host_bridge_window 
  16.      * struct pci_host_bridge_window { 
  17.      *  struct list_head list; 
  18.      *  struct resource *res;   /* host bridge aperture (CPU address) */  
  19.      *  resource_size_t offset; /* bus address + offset = CPU address */  
  20.      * };  
  21.      */  
  22.     bridge = pci_alloc_host_bridge();  
  23.   
  24.     /* 
  25.      * 输入参数parent来自pci host驱动中pci host核心结构的struct device *dev, 
  26.      * dev来自 platform_device 中的dev。可以以drivers/pci/host下的pci-mvebu.c 
  27.      * 作为例子, 其中所谓的pci host核心结构是:struct mvebu_pcie 
  28.      */  
  29.     bridge->dev.parent = parent;  
  30.   
  31.     /* 分配 struct pci_bus */  
  32.     b = pci_alloc_bus(NULL);  
  33.   
  34.     b->sysdata = sysdata;  
  35.     b->ops = ops;  
  36.     b->number = b->busn_res.start = bus;  
  37.     /* 在pcie dts节点中找见domain字段, 加入pci_bus的domain_nr */  
  38.     pci_bus_assign_domain_nr(b, parent);  
  39.     /* 
  40.      * 在pci_root_buses全局链表中找相应domain下的bus, 首次调用的时候返回NULL 
  41.      * 上面分配的pci_root_buses是在当前函数的最后才加入pci_root_buses中的,现在该 
  42.      * 全局链表为空 
  43.      */  
  44.     b2 = pci_find_bus(pci_domain_nr(b), bus);  
  45.     /* 
  46.      * 上面两行处理有关pci domain的信息,kernel pci子系统怎么处理pci domain 
  47.      * 的呢? 首先数据结构是全局的链表:pci_root_buses, 局部链表:pci_domain_busn_res_list 
  48.      * pci_root_buses中存放每个pci domain的根总线,根总线在pci_create_root_bus 
  49.      * 函数的结尾被添加到pci_root_buses链表中。pci_domain_busn_res_list存放 
  50.      * 各个domain的信息, 包括domain号、domain包含的bus号范围, 该链表上存放 
  51.      * 存放的结构是:struct pci_domain_busn_res, 在函数get_pci_domain_busn_res 
  52.      * 中查找相应domain号的pci_domain_busn_res, 如果没有就分配一个新的 
  53.      * pci_domain_busn_res, 然后加到pci_domain_busn_res_list上 
  54.      */  
  55.   
  56.     bridge->bus = b;  
  57.     dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);  
  58.     error = pcibios_root_bridge_prepare(bridge);  
  59.   
  60.     error = device_register(&bridge->dev);  
  61.   
  62.     b->bridge = get_device(&bridge->dev);  
  63.     device_enable_async_suspend(b->bridge);  
  64.     pci_set_bus_of_node(b);  
  65.   
  66.     if (!parent)  
  67.         set_dev_node(b->bridge, pcibus_to_node(b));  
  68.   
  69.     b->dev.class = &pcibus_class;  
  70.     /* b->bridge 为对应pci_host_bridge中struct device dev的指针 */  
  71.     b->dev.parent = b->bridge;  
  72.     dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);  
  73.     error = device_register(&b->dev);  
  74.   
  75.     pcibios_add_bus(b);  
  76.   
  77.     /* Create legacy_io and legacy_mem files for this bus */  
  78.     pci_create_legacy_files(b);  
  79.   
  80.     ...  
  81.     /* 
  82.      * 取出pci_create_root_bus函数传入的链表resources中的pci_host_bridge_window, 
  83.      * 把每个pci_host_bridge_window加入pci_host_bridge中的window链表中 
  84.      */  
  85.     list_for_each_entry_safe(window, n, resources, list) {  
  86.         list_move_tail(&window->list, &bridge->windows);  
  87.         res = window->res;  
  88.         offset = window->offset;  
  89.         if (res->flags & IORESOURCE_BUS)  
  90.                 /* 
  91.              * 一般的,resources链表上有bus number, MEM space, I/O 
  92.              * space的节点,如果是bus number节点则调用以下函数。该 
  93.              * 函数会找到当前pci_bus的父结构,生成pci_bus中的busn_res 
  94.              * 并和父结构中的struct resource busn_res建立联系。 
  95.              * 如果父子在bus号上存在冲突,则返回冲突的bus号[1] 
  96.              */  
  97.             pci_bus_insert_busn_res(b, bus, res->end);  
  98.         else  
  99.             /* 
  100.              * 向pci_bus中的链表resources中加入struct pci_bus_resource 
  101.              * 记录mem, io的资源 
  102.              */  
  103.             pci_bus_add_resource(b, res, 0);  
  104.         if (offset) {  
  105.             if (resource_type(res) == IORESOURCE_IO)  
  106.                 fmt = " (bus address [%#06llx-%#06llx])";  
  107.             else  
  108.                 fmt = " (bus address [%#010llx-%#010llx])";  
  109.             snprintf(bus_addr, sizeof(bus_addr), fmt,  
  110.                  (unsigned long long) (res->start - offset),  
  111.                  (unsigned long long) (res->end - offset));  
  112.         } else  
  113.             bus_addr[0] = '\0';  
  114.         dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr);  
  115.     }  
  116.   
  117.     down_write(&pci_bus_sem);  
  118.     /* 把创建的pci_bus加入全局链表pci_root_buses中 */  
  119.     list_add_tail(&b->node, &pci_root_buses);  
  120.     up_write(&pci_bus_sem);  
  121.   
  122.     return b;  
  123.     ...  
  124. }  
[1] 关于linux中resource结构对资源的管理可以参看:
    http://www.linuxidc.com/Linux/2011-09/43708.htm
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PCIE-DMA是一种基于PCIe接口的直接内存访问技术,能够实现高速数据传输。在我的学习笔记中,我详细记录了与PCIE-DMA相关的知识和学习心得。 首先,我了解到PCIE-DMA技术的基本原理和作用。PCIE-DMA可以通过PCIe总线直接访问系统内存中的数据,而不需要过多的CPU干预,提高数据传输的速度和效率。这种技术在需要大量数据传输的场景下非常有效,比如高性能计算、数据采集等。 其次,我深入学习PCIE-DMA的工作原理。PCIE-DMA的核心是DMA控制器,它负责管理和控制数据传输的流程。当设备需要读写内存中的数据时,它通过DMA控制器发送请求,然后DMA控制器生成一个事务,将数据直接传输到或从内存中。这样就大大减少了CPU的参与,提高了数据传输的效率。 另外,我还学习PCIE-DMA的配置和编程方法。PCIE-DMA的配置主要包括硬件配置和软件配置两个部分。硬件配置通常涉及到DMA控制器和PCIe接口的初始化和配置,软件配置则需要编写驱动程序来驱动DMA控制器和处理数据传输过程中的事件和异常。这部分内容对于我来说还比较新颖,需要更多的实践和实践。 最后,我总结了PCIE-DMA的应用场景和发展前景。PCIE-DMA在高性能计算、数据采集等领域具有广阔的应用前景。随着数据量的不断增加和传输速度的要求越来越高,PCIE-DMA技术的需求也将越来越大。因此,对于我来说,学习掌握PCIE-DMA技术非常有价值。 通过学习和记录PCIE-DMA的相关知识和经验,我对这项技术有了更深入的理解和掌握。希望将来能通过应用PCIE-DMA技术解决实际问题,为科研和工程项目的顺利进行做出贡献。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值