.. SPDX-License-Identifier: GPL-2.0 .. include:: <isonum.txt> .. include:: ../disclaimer-zh_CN.rst :Original: Documentation/PCI/pciebus-howto.rst :翻译: å¸å»¶è…¾ Yanteng Si <siyanteng@loongson.cn> :æ ¡è¯‘: .. _cn_pciebus-howto: =========================== PCI Express端å£æ€»çº¿é©±åŠ¨æŒ‡å— =========================== :作者: Tom L Nguyen tom.l.nguyen@intel.com 11/03/2004 :版æƒ: |copy| 2004 Intel Corporation å…³äºŽæœ¬æŒ‡å— ========== 本指å—介ç»äº†PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºçš„基本知识,并æ供了如何使æœåŠ¡é©± 动程åºåœ¨PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºä¸æ³¨å†Œ/å–消注册的介ç»ã€‚ 什么是PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åº ================================= 一个PCI Express端å£æ˜¯ä¸€ä¸ªé€»è¾‘çš„PCI-PCI桥结构。有两ç§ç±»åž‹çš„PCI Express端 å£ï¼šæ ¹ç«¯å£å’Œäº¤æ¢ç«¯å£ã€‚æ ¹ç«¯å£ä»ŽPCI Expressæ ¹ç»¼åˆä½“å‘起一个PCI Express链接, 交æ¢ç«¯å£å°†PCI Express链接连接到内部逻辑PCI总线。交æ¢æœºç«¯å£ï¼Œå…¶äºŒçº§æ€»çº¿ä»£è¡¨ 交æ¢æœºçš„内部路由逻辑,被称为交æ¢æœºçš„上行端å£ã€‚交æ¢æœºçš„下行端å£æ˜¯ä»Žäº¤æ¢æœºçš„内部 路由总线桥接到代表æ¥è‡ªPCI Express交æ¢æœºçš„下游PCI Express链接的总线。 一个PCI Express端å£å¯ä»¥æ供多达四个ä¸åŒçš„功能,在本文ä¸è¢«ç§°ä¸ºæœåŠ¡ï¼Œè¿™å–决于 其端å£ç±»åž‹ã€‚PCI Express端å£çš„æœåŠ¡åŒ…括本地çƒæ‹”æ’支æŒï¼ˆHP)ã€ç”µæºç®¡ç†äº‹ä»¶æ”¯æŒï¼ˆPME)〠高级错误报告支æŒï¼ˆAER)和虚拟通é“支æŒï¼ˆVC)。这些æœåŠ¡å¯ä»¥ç”±ä¸€ä¸ªå¤æ‚çš„é©±åŠ¨ç¨‹åº å¤„ç†ï¼Œä¹Ÿå¯ä»¥å•ç‹¬åˆ†å¸ƒå¹¶ç”±ç›¸åº”çš„æœåŠ¡é©±åŠ¨ç¨‹åºå¤„ç†ã€‚ 为什么è¦ä½¿ç”¨PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºï¼Ÿ ========================================= 在现有的Linuxå†…æ ¸ä¸ï¼ŒLinux设备驱动模型å…许一个物ç†è®¾å¤‡åªç”±ä¸€ä¸ªé©±åŠ¨å¤„ç†ã€‚ PCI Express端å£æ˜¯ä¸€ä¸ªå…·æœ‰å¤šä¸ªä¸åŒæœåŠ¡çš„PCI-PCI桥设备。为了ä¿æŒä¸€ä¸ªå¹²å‡€å’Œç®€ å•çš„解决方案,æ¯ä¸ªæœåŠ¡éƒ½å¯ä»¥æœ‰è‡ªå·±çš„软件æœåŠ¡é©±åŠ¨ã€‚在这ç§æƒ…å†µä¸‹ï¼Œå‡ ä¸ªæœåŠ¡é©±åŠ¨å°† 竞争一个PCI-PCI桥设备。例如,如果PCI Expressæ ¹ç«¯å£çš„本机çƒæ‹”æ’æœåŠ¡é©±åŠ¨ç¨‹åº é¦–å…ˆè¢«åŠ è½½ï¼Œå®ƒå°±ä¼šè¦æ±‚一个PCI-PCIæ¡¥æ ¹ç«¯å£ã€‚å› æ¤ï¼Œå†…æ ¸ä¸ä¼šä¸ºè¯¥æ ¹ç«¯å£åŠ è½½å…¶ä»–æœ åŠ¡é©±åŠ¨ã€‚æ¢å¥è¯è¯´ï¼Œä½¿ç”¨å½“å‰çš„驱动模型,ä¸å¯èƒ½è®©å¤šä¸ªæœåŠ¡é©±åŠ¨åŒæ—¶åŠ 载并è¿è¡Œåœ¨ PCI-PCI桥设备上。 为了使多个æœåŠ¡é©±åŠ¨ç¨‹åºåŒæ—¶è¿è¡Œï¼Œéœ€è¦æœ‰ä¸€ä¸ªPCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºï¼Œå®ƒç®¡ ç†æ‰€æœ‰å¡«å……çš„PCI Express端å£ï¼Œå¹¶æ ¹æ®éœ€è¦å°†æ‰€æœ‰æ供的æœåŠ¡è¯·æ±‚分é…给相应的æœåŠ¡ 驱动程åºã€‚下é¢åˆ—出了使用PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºçš„一些关键优势: - å…许在一个PCI-PCI桥接端å£è®¾å¤‡ä¸ŠåŒæ—¶è¿è¡Œå¤šä¸ªæœåŠ¡é©±åŠ¨ã€‚ - å…许以独立的分阶段方å¼å®žæ–½æœåŠ¡é©±åŠ¨ç¨‹åºã€‚ - å…许一个æœåŠ¡é©±åŠ¨ç¨‹åºåœ¨å¤šä¸ªPCI-PCI桥接端å£è®¾å¤‡ä¸Šè¿è¡Œã€‚ - 管ç†å’Œåˆ†é…PCI-PCI桥接端å£è®¾å¤‡çš„资æºç»™è¦æ±‚çš„æœåŠ¡é©±åŠ¨ç¨‹åºã€‚ é…ç½®PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºä¸ŽæœåŠ¡é©±åŠ¨ç¨‹åº ============================================= å°†PCI Express端å£æ€»çº¿é©±åŠ¨æ”¯æŒçº³å…¥å†…æ ¸ ------------------------------------- 包括PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºå–å†³äºŽå†…æ ¸é…ç½®ä¸æ˜¯å¦åŒ…å«PCI Express支æŒã€‚å½“å†…æ ¸ ä¸çš„PCI Express支æŒè¢«å¯ç”¨æ—¶ï¼Œå†…æ ¸å°†è‡ªåŠ¨åŒ…å«PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºä½œä¸ºå†…æ ¸ 驱动程åºã€‚ å¯ç”¨æœåŠ¡é©±åŠ¨æ”¯æŒ ---------------- PCI设备驱动是基于Linux设备驱动模型实现的。所有的æœåŠ¡é©±åŠ¨éƒ½æ˜¯PCI设备驱动。如上所述, ä¸€æ—¦å†…æ ¸åŠ è½½äº†PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºï¼Œå°±ä¸å¯èƒ½å†åŠ 载任何æœåŠ¡é©±åŠ¨ç¨‹åºã€‚为了满 足PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºæ¨¡åž‹ï¼Œéœ€è¦å¯¹çŽ°æœ‰çš„æœåŠ¡é©±åŠ¨ç¨‹åºè¿›è¡Œä¸€äº›æœ€å°çš„改å˜ï¼Œå…¶ 对现有的æœåŠ¡é©±åŠ¨ç¨‹åºçš„功能没有影å“。 æœåŠ¡é©±åŠ¨ç¨‹åºéœ€è¦ä½¿ç”¨ä¸‹é¢æ‰€ç¤ºçš„两个API,将其æœåŠ¡æ³¨å†Œåˆ°PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹ åºä¸ï¼ˆè§ç¬¬5.2.1å’Œ5.2.2节)。在调用这些API之å‰ï¼ŒæœåŠ¡é©±åŠ¨ç¨‹åºå¿…é¡»åˆå§‹åŒ–头文件 /include/linux/pcieport_if.hä¸çš„pcie_port_service_driveræ•°æ®ç»“构。如果ä¸è¿™ æ ·åšï¼Œå°†å¯¼è‡´èº«ä»½ä¸åŒ¹é…,从而使PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºæ— æ³•åŠ è½½æœåŠ¡é©±åŠ¨ç¨‹åºã€‚ pcie_port_service_register ~~~~~~~~~~~~~~~~~~~~~~~~~~ :: int pcie_port_service_register(struct pcie_port_service_driver *new) 这个APIå–代了Linux驱动模型的 pci_register_driver API。一个æœåŠ¡é©±åŠ¨åº”该总是在模 å—å¯åŠ¨æ—¶è°ƒç”¨ pcie_port_service_register。请注æ„,在æœåŠ¡é©±åŠ¨è¢«åŠ è½½åŽï¼Œè¯¸å¦‚ pci_enable_device(dev) å’Œ pci_set_master(dev) 的调用ä¸å†éœ€è¦ï¼Œå› 为这些调用由 PCI端å£æ€»çº¿é©±åŠ¨æ‰§è¡Œã€‚ pcie_port_service_unregister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: void pcie_port_service_unregister(struct pcie_port_service_driver *new) pcie_port_service_unregisterå–代了Linux驱动模型的pci_unregister_driver。当一 个模å—退出时,它总是被æœåŠ¡é©±åŠ¨è°ƒç”¨ã€‚ 示例代ç ~~~~~~~~ 下é¢æ˜¯æœåŠ¡é©±åŠ¨ä»£ç 示例,用于åˆå§‹åŒ–端å£æœåŠ¡çš„驱动程åºæ•°æ®ç»“构。 :: static struct pcie_port_service_id service_id[] = { { .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, .port_type = PCIE_RC_PORT, .service_type = PCIE_PORT_SERVICE_AER, }, { /* end: all zeroes */ } }; static struct pcie_port_service_driver root_aerdrv = { .name = (char *)device_name, .id_table = &service_id[0], .probe = aerdrv_load, .remove = aerdrv_unload, .suspend = aerdrv_suspend, .resume = aerdrv_resume, }; 下é¢æ˜¯ä¸€ä¸ªæ³¨å†Œ/å–消注册æœåŠ¡é©±åŠ¨çš„示例代ç 。 :: static int __init aerdrv_service_init(void) { int retval = 0; retval = pcie_port_service_register(&root_aerdrv); if (!retval) { /* * FIX ME */ } return retval; } static void __exit aerdrv_service_exit(void) { pcie_port_service_unregister(&root_aerdrv); } module_init(aerdrv_service_init); module_exit(aerdrv_service_exit); å¯èƒ½çš„资æºå†²çª ============== 由于PCI-PCI桥接端å£è®¾å¤‡çš„所有æœåŠ¡é©±åŠ¨è¢«å…许åŒæ—¶è¿è¡Œï¼Œä¸‹é¢åˆ—出了一些å¯èƒ½çš„资æºå†²çªå’Œ 建议的解决方案。 MSI å’Œ MSI-X å‘é‡èµ„æº --------------------- 一旦设备上的MSI或MSI-Xä¸æ–被å¯ç”¨ï¼Œå®ƒå°±ä¼šä¸€ç›´ä¿æŒè¿™ç§æ¨¡å¼ï¼Œç›´åˆ°å®ƒä»¬å†æ¬¡è¢«ç¦ç”¨ã€‚ç”±äºŽåŒ ä¸€ä¸ªPCI-PCI桥接端å£çš„æœåŠ¡é©±åŠ¨ç¨‹åºå…±äº«åŒä¸€ä¸ªç‰©ç†è®¾å¤‡ï¼Œå¦‚果一个å•ç‹¬çš„æœåŠ¡é©±åŠ¨ç¨‹åºå¯ç”¨æˆ– ç¦ç”¨MSI/MSI-X模å¼ï¼Œå¯èƒ½ä¼šå¯¼è‡´ä¸å¯é¢„知的行为。 为了é¿å…è¿™ç§æƒ…况,所有的æœåŠ¡é©±åŠ¨ç¨‹åºéƒ½ä¸å…许在其设备上切æ¢ä¸æ–模å¼ã€‚PCI Expressç«¯å£ æ€»çº¿é©±åŠ¨ç¨‹åºè´Ÿè´£ç¡®å®šä¸æ–模å¼ï¼Œè¿™å¯¹æœåŠ¡é©±åŠ¨ç¨‹åºæ¥è¯´åº”该是é€æ˜Žçš„。æœåŠ¡é©±åŠ¨ç¨‹åºåªéœ€è¦çŸ¥é“ 分é…给结构体pcie_deviceçš„å—段irqçš„å‘é‡IRQ,当PCI Express端å£æ€»çº¿é©±åŠ¨ç¨‹åºæŽ¢æµ‹æ¯ 个æœåŠ¡é©±åŠ¨ç¨‹åºæ—¶ï¼Œå®ƒè¢«ä¼ 入。æœåŠ¡é©±åŠ¨åº”该使用(struct pcie_device*)dev->irqæ¥è°ƒç”¨ request_irq/free_irq。æ¤å¤–,ä¸æ–模å¼è¢«å˜å‚¨åœ¨struct pcie_deviceçš„interrupt_mode å—段ä¸ã€‚ PCI内å˜/IOæ˜ å°„çš„åŒºåŸŸ -------------------- PCI Express电æºç®¡ç†ï¼ˆPME)ã€é«˜çº§é”™è¯¯æŠ¥å‘Šï¼ˆAER)ã€çƒæ’拔(HP)和虚拟通é“(VC)的æœåŠ¡ 驱动程åºè®¿é—®PCI Express端å£çš„PCIé…置空间。在所有情况下,访问的寄å˜å™¨æ˜¯ç›¸äº’独立的。这 个补ä¸å‡å®šæ‰€æœ‰çš„æœåŠ¡é©±åŠ¨ç¨‹åºéƒ½ä¼šè¡¨çŽ°è‰¯å¥½ï¼Œä¸ä¼šè¦†ç›–其他æœåŠ¡é©±åŠ¨ç¨‹åºçš„é…置设置。 PCIé…置寄å˜å™¨ ------------- æ¯ä¸ªæœåŠ¡é©±åŠ¨éƒ½åœ¨è‡ªå·±çš„功能结构体上è¿è¡ŒPCIé…ç½®æ“作,除了PCI Express功能结构体,其ä¸æ ¹æŽ§åˆ¶ 寄å˜å™¨å’Œè®¾å¤‡æŽ§åˆ¶å¯„å˜å™¨æ˜¯åœ¨PMEå’ŒAER之间共享。这个补ä¸å‡å®šæ‰€æœ‰çš„æœåŠ¡é©±åŠ¨éƒ½ä¼šè¡¨çŽ°è‰¯å¥½ï¼Œä¸ä¼š 覆盖其他æœåŠ¡é©±åŠ¨çš„é…置设置。