本文翻譯自內核文檔:linux\Documentation\PCI\pcieaer-howto.txt
《 PCI Express高級錯誤報告驅動程序指南》 HOWTO
T.Long Nguyen <[email protected]>
張衍民<[email protected]>
2006年7月29日
目錄
2.1將PCI Express AER根驅動程序包含到Linux內核中
3.2.1回調reset_link用於重置PCI Express鏈接
3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev * dev);
3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev * dev);
3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev * dev);
1.概述
1.1關於本指南
本指南介紹了PCI Express Advanced錯誤的基礎知識。
介紹報告(AER)的驅動程序,並提供有關如何使用它的信息,例如如何啓動端點設備的驅動使其適用於PCI Express AER驅動程序。
1.2版權所有(C)英特爾公司2006。
1.3什麼是PCI Express AER驅動程序?
PCI Express錯誤信號可能會在PCI Express鏈接本身上發生或鏈路上產生了某些指示錯誤的傳輸事務。
PCI Express定義了兩個錯誤報告範例:基準capability和高級錯誤報告功能(AER capability)。基準能力是
所有PCI Express組件必選的,提供最低要求的一組錯誤報告。
高級錯誤報告(AER)可實現基準功能的擴展,提供了更強大的錯誤報告能力。
內核的PCI Express AER驅動程序提供了支持AER功能的基礎軟件架構。
PCI Express AER驅動程序提供以下三個基本功能:
- 如果發生錯誤,則收集全面的錯誤信息。
- 向用戶報告錯誤。
- 執行錯誤恢復操作。
注意:AER驅動程序僅支持PCI-Express AER的根(RC)端口。
2.用戶指南
2.1將PCI Express AER根驅動程序包含到Linux內核中
PCI Express AER根驅動程序是根端口驅動程序的一部分。如果用戶想使用它,這部分驅動編譯進內核。
選項CONFIG_PCIEAER支持此功能。它依賴於CONFIG_PCIEPORTBUS,所以請設置CONFIG_PCIEPORTBUS = y並
CONFIG_PCIEAER = y。
2.2加載PCI Express AER根驅動程序
某些系統在firmware中已經包含了對AER支持。同時啓用Linux AER支持,可能會導致firmware處理AER的同時,產生不可預測的
行爲。因此,除非固件通過ACPI _OSC方法將AER控制權授予OS,否則Linux不會處理AER事件。
參見PCI FW 3.0有關_OSC使用情況的詳細信息規範。
2.3 AER錯誤輸出
當捕獲到PCIe AER錯誤時,錯誤消息將輸出到console。
如果是可糾正的錯誤,則將其作爲警告輸出(warning)。
否則,將其打印爲錯誤(error)。因此用戶可以選擇不同的日誌級別以過濾出可糾正的錯誤消息。
下面顯示了一個示例:
0000:50:00.0: PCIe Bus Error: severity=Uncorrected (Fatal), type=Transaction Layer, id=0500(Requester ID)
0000:50:00.0: device [8086:0329] error status/mask=00100000/00000000
0000:50:00.0: [20] Unsupported Request (First)
0000:50:00.0: TLP Header: 04000001 00200a03 05010000 00050100
在示例中,“RequesterID”是指發送信息到根端口的設備的ID。請請參閱PCI Express specs其他領域。
3.開發人員指南
要啓用AER感知支持,需要使用軟件驅動程序對AER capability structure進行配置並提供回調接口。
爲了更好地支持AER,首先,開發人員需要了解AER的工作原理。
PCI Express錯誤分爲兩種類型:可糾正的錯誤和不可糾正的錯誤。
此分類的依據是基於這些錯誤中,是否會導致性能或功能下降。
可糾正的錯誤不會對功能接口造成影響。 PCI Express協議無需任何軟件干預即可恢復,且不會有任何數據丟失。
完全由硬件檢測到並糾正這些錯誤。與可糾正錯誤不同,不可糾正錯誤會影響接口的功能。
無法糾正的錯誤可能導致特定的事務或鏈接變得不可靠。
根據這些錯誤情況,無法糾正錯誤進一步分爲非致命錯誤和致命錯誤。
非致命錯誤會導致某些事務不可靠,但是PCI Express鏈接本身可以正常使用。
致命錯誤會導致鏈接不可靠。
啓用AER後,PCI Express設備檢測到錯誤產生後將把錯誤消息自動發送到其上方的PCIe根端口。
一根端口,在收到錯誤報告消息後,內部處理錯誤消息。並將其記錄在其PCI Express capability中。
記錄的錯誤信息包括:存儲錯誤報告的請求者ID,並設置相應的根節點錯誤寄存器位。
如果在根端口的錯誤命令寄存器中啓用了AER錯誤報告,當錯誤被檢測到後會產生一箇中斷請求。
請注意,上述錯誤與PCI Express 架構和連接有關。
這些錯誤不包括任何特定於設備的錯誤,因爲特定於設備的錯誤仍將直接發送到設備驅動程序。
3.1配置AER capability structure
PCI Express組件的AER感知驅動程序需要配置設備控制寄存器以啓用AER支持。
驅動程序也會配置AER的capability 寄存器,包括掩碼(mask)和嚴重性(severity)寄存器。
函數pci_enable_pcie_error_reporting可用於啓用AER。具體參見第3.3節。
3.2 提供回調
3.2.1回調reset_link用於重置PCI Express鏈接
在發生致命錯誤的情況下,此回調用於重置pci express物理鏈接:
根端口aer服務驅動程序提供了一個默認的reset_link函數,但不同的RC控制器可能有不同的方式來重置PCI Express鏈接,因此所有上游端口應提供自己的reset_link函數。
在struct pcie_port_service_driver中,新的指針reset_link已經被添加(控制器驅動程序需要對其賦值)。
pci_ers_result_t(* reset_link)(struct pci_dev * dev);
第3.2.2.2節提供了有關reset_link何時被調用的更多詳細信息。
3.2.2 PCI錯誤恢復回調
執行錯誤恢復操作時,PCI Express AER根驅動程序使用錯誤恢復回調對下游設備驅動程序進行協調。
數據結構pci_driver具有指向err_handler的指針
pci_error_handlers由幾個回調函數組成的。
AER驅動程序遵循定義在pci-error-recovery.txt中的規則要求,除了pcie特定的部分(例如reset_link)。
詳細信息,請參考pci-error-recovery.txt對回調的定義。
以下各節介紹何時調用錯誤回調函數。
3.2.2.1可糾正的錯誤
可糾正的錯誤不會對功能接口造成影響。 PCI Express協議無需任何軟件干預即可恢復,且不會有任何數據丟失。
這些錯誤不需要任何恢復操作。 AER驅動程序會清除設備的可糾正的錯誤狀態,並相應地註冊並記錄這些錯誤。
3.2.2.2不可糾正(非致命和致命)錯誤
如果錯誤消息指示非致命錯誤,上游端口是不需要執行link reset的。
AER驅動程序會調用error_detected(dev,pci_channel_io_normal)到層次結構中關聯的所有有問題的驅動程序。
例如,
端點<==>下游端口B <==>上游端口A <==>根端口。
如果上游端口A捕獲AER錯誤,則層次結構包括下游端口B和EndPoint。
驅動程序可能會返回PCI_ERS_RESULT_CAN_RECOVER,
PCI_ERS_RESULT_DISCONNECT或PCI_ERS_RESULT_NEED_RESET,
具體取決於是否可以恢復還是AER驅動程序接下來調用mmio_enabled。
如果錯誤消息指示致命錯誤,則內核將廣播error_detected(dev,pci_channel_io_frozen)到系統中所有有問題的驅動程序。
然後,在上游執行link reset是有必要的。由於不同類型的設備可能會使用不同的函數實現來重置鏈接,需要AER端口服務驅動程序提供重置鏈接的函數接口。首先,內核尋找上游組件具有aer的驅動程序。如果有,內核使用aer驅動程序的reset_link回調。
如果上游組件沒有aer驅動程序並且該端口是下游端口,我們通過設置橋接器控制的次級總線復位位來將執行hot reset。
至於上游端口,他們應該使用自己的aer服務驅動程序提供reset_link函數。
如果error_detected返回PCI_ERS_RESULT_CAN_RECOVER和reset_link返回PCI_ERS_RESULT_RECOVERED,錯誤處理
將啓用mmio_enabled。
3.3 助手功能
3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev * dev);
pci_enable_pcie_error_reporting使設備能夠發送錯誤
檢測到錯誤時將消息發送到根端口。注意設備(ep device)默認情況下不啓用錯誤報告,因此設備驅動程序需要
調用此功能將其啓用。
3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev * dev);
pci_disable_pcie_error_reporting禁止設備發送錯誤
檢測到錯誤時將消息發送到根端口。
3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev * dev);
pci_cleanup_aer_uncorrect_error_status 清除無法糾正的錯誤狀態寄存器。
3.4常見問題
問:如果PCI Express設備驅動程序不提供錯誤恢復處理程序(pci_driver-> err_handler等於NULL)會怎麼樣?
答:驅動程序附帶的設備將無法恢復。如果錯誤是致命的,內核將打印出警告消息。請參閱第3節以獲取更多信息。
問:如果上游端口服務驅動程序不提供回調reset_link會怎樣?
答:如果錯誤是由服務驅動程序連接的上游端口報告的,則致命錯誤將無法恢復。
問:此基礎架構如何處理非PCIe驅動程序?
答:發生錯誤時此基礎架構會調用驅動程序的錯誤回調函數。
但是如果驅動不是用於PCI Express的,設備可能不會將自己的錯誤報告給root端口。
問:該驅動程序需要進行哪些修改才能使其兼容PCI Express AER根驅動程序?
答:它可以調用幫助程序函數以在設備中啓用AER,並清理不可糾正的狀態寄存器。請請參閱第3.3節。
4.軟件錯誤注入
調試PCIe AER錯誤恢復代碼非常困難,因爲它很難觸發真正的硬件錯誤。基於軟件的錯誤注入可用於僞造各種PCIe錯誤。
首先,您應該在內核中啓用PCIe AER軟件錯誤注入
配置,即以下應位於您的.config中的項目。
CONFIG_PCIEAER_INJECT = y或CONFIG_PCIEAER_INJECT = m
使用新內核重新啓動或insmod模塊後,名爲設備文件
/ dev / aer_inject 會被創建。
然後,您需要一個名爲aer-inject的用戶空間工具,
該工具可以從此獲取: http://www.kernel.org/pub/linux/utils/pci/aer-inject/
有關aer-inject的更多信息可以在連接中的文檔及其源代碼中找到。