前面描述中斷的時候,我們曾經多次體積PCI,甚至提供了一些PCI的相關知識,但是整個PCI是一個很大的體系,專門記錄這個體系超出了這個系列的范疇,有興趣的可以到PCI官網了解詳細的情況。
但是還是會花費一些時間討論PCI技術,接下來我們從WDM的角度討論PCI協議。
先正式的介紹一下PCIe:
PCI Express (PCIe) 是一種 I/O 總線技術,旨在 PCI、PCI-X 和加速圖形端口 (AGP) 取代外圍組件互連。 通過提供高級功能和增加的帶寬,PCIe 解決了 PCI、PCI-X 和 AGP 的許多缺點。 PCIe 保留了與 PCI 本地總線規范 2.3 的完整軟件兼容性,并將 PCI 和 PCI-X 的并行多滴總線體系結構替換為串行的點到點連接總線體系結構。
兩個 PCIe 設備通過一個鏈路連接,每個鏈路由一個或多個通道組成。 每條車道由兩個低電壓、差分信號對組成,可向相反方向傳送 2.5 Gbps 的流量。 一對用于傳輸,另一對用于接收。 若要進一步增加鏈路的帶寬,可以在兩個 PCIe 設備之間) (x1、x2、x4、x8、x12、x16 或 x32 通道并行放置多個通道,以聚合每個通道的帶寬。
PCIe 硬件與 Microsoft Windows 2000 和 Microsoft Windows XP 操作系統上的 PCI 軟件向后兼容。 高級 PCIe 功能僅在 Windows Vista 和更高版本的 Windows 中受本機支持。
設備驅動程序和 PCI 電源管理
通常,設備驅動程序的責任如下:
總線驅動程序:總線驅動程序負責枚舉、配置和控制設備。 對于 PCI-PM,PCI 驅動程序負責讀取 PCI-PM 寄存器以確定硬件的功能。 當 POWER IRP 請求電源狀態更改時,PCI 驅動程序會寫入 PCI 電源管理寄存器,以將硬件設置為不同的 Dx 狀態。
當設備啟用喚醒時,PCI 驅動程序會寫入 PCI-PM 寄存器,使設備能夠觸發 PME 。 最后,當 ACPI 確定 PCI 總線正在喚醒系統時,PCI 驅動程序會掃描 PCI 配置空間,查找哪個設備正在斷言 PME,在該設備中禁用 PME,并通知驅動程序該設備。
設備驅動程序:設備的特定驅動程序負責保存和還原設備上下文,以及以設備策略所有者的身份請求電源狀態更改。 當設備驅動程序收到要求更改較低設備電源狀態的 POWER IRP 時,設備驅動程序負責保存以后打開設備所需的任何專有設備上下文。 在某些情況下,可能沒有任何可保存內容。
PCI-PM 寄存器嚴格是 PCI 驅動程序的域 -- IHV 的設備驅動程序不需要訪問這些寄存器中的任何一個,這樣做會導致系統無法可靠地工作, 設備驅動程序的責任是僅執行專有操作。
看上面的信息會感覺非常吃力,我們可以看看實際的配置,實際上,有兩個配置,分別是PMC和PMCSR寄存器:
當然上面的表述也確實沒有錯,PMC是一個只讀寄存器, PMCSR則是可以配置的
注意: 我們只需要關注這個寄存器三個設置項即可:
15-PME狀態
觸發函數獨立于PME_En位的狀態來斷言PME#信號的能力。注意:當輔助電源可用時,消耗輔助電源的設備功能必須保留此粘性寄存器的值。在這種功能中,此寄存器值不會被常規復位或FLR修改。
預定義值:
0b:沒有效果。
1b:該字段將被清除,功能將s8-PME啟用(RW)
8-觸發函數斷言PME:注意:當輔助電源可用時,消耗輔助電源的設備功能必須保留此粘性寄存器的值。在這種功能中,此寄存器值不會被常規復位或FLR修改。
預定義值:
0b:斷言已禁用
1b:斷言是在斷言PME#信號之前啟用的(如果啟用)。
0~1:電源狀態該2位字段既用于確定函數的當前功率狀態,也用于將函數設置為新的功率狀態。字段值的定義如下所示。如果軟件試圖將不受支持的可選狀態寫入該字段,則寫入操作必須在總線上正常完成;然而,數據被丟棄并且不發生狀態改變。
預定義值:
00b:D0
01b:D1
10b:D2
11b:D3hot
集成 ACPI 和 PCI PM
某些設備(尤其是便攜式中的主板視頻設備)可能需要 PCI 電源管理和 ACPI 源語言匯編程序 (ASL) 才能完全為設備供電。 PCI 電源管理寄存器將控制設備的內部狀態,例如內部時鐘和電源平面。 ASL 將控制外部狀態,如外部時鐘和電源平面,或者對于視頻控制器,ASL 將控制視頻背光。 請注意,ASL 和 PCI-PM 只能在主板設備上組合使用。
OnNow 體系結構是一種分層體系結構,可以自然地處理設備驅動程序、PCI 驅動程序和 ACPI 驅動程序 ( ASL) 集成。 以下方案顯示了調用驅動程序以處理這些設備的順序。
注意:?要使上述方案正常工作,WDM 驅動程序必須按照當前版本的 Microsoft Windows DDK 中所述正確轉發 POWER IRP。
方案 1:關閉設備
- 設備驅動程序:保存專有設備狀態;
- PCI 驅動程序:保存即插即用配置,禁用設備 (中斷和 BAR) ,并使用 PCI-PM 寄存器將設備置于 D3 中;
- ACPI 驅動程序:運行 ASL 代碼 (_PS3 和 _OFF) 以便不再使用電源資源來控制芯片外部的狀態;
方案 2:PCI 電源管理和設備驅動程序
- ACPI 驅動程序:運行 ASL 代碼 (_PS0 并_ON任何 OnNow 所需的電源資源) ,控制芯片外部的狀態;
- PCI 驅動程序:使用 PCI-PM 寄存器將設備置于 D0 中,并還原即插即用配置 (中斷和 BAR) 這些可能與設備以前不同;
- 設備驅動程序:還原設備中的專有上下文;
方案 3:啟用喚醒
- 設備驅動程序:在芯片中設置專有寄存器以啟用喚醒。 例如,在模式匹配網絡喚醒中,這是將模式編程到適配器中的時間;
- PCI 驅動程序:設置 PCI PM 寄存器中的喚醒啟用位,以允許設備斷言 PME;
- ACPI 驅動程序:在與 PME 關聯的芯片集中啟用 GPE,如根 PCI 總線下列出的 _PRW 對象所述;
方案 4:喚醒
- ACPI 驅動程序:喚醒并掃描 GPE 狀態位以查找喚醒事件,禁用設置 GPE 狀態位的 GPE,并運行與設置的 GPE 位關聯的任何_Lxx或_Exx方法。 為了響應 PCI 總線上的喚醒通知,ACPI 驅動程序將完成 PCI 驅動程序的WAIT_WAKE IRP,以通知 PCI 驅動程序正在喚醒系統;
- PCI 驅動程序:掃描配置空間,查找具有設置 PME 狀態位的任何設備。 對于每個設備,它會禁用 PME 并完成該設備的WAIT_WAKE IRP,以通知驅動程序它正在斷言喚醒。 當 PCI 驅動程序通過所有 PCI 設備完成未找到任何斷言 PME 且 PME 停止斷言時,它將停止掃描喚醒設備;
- 設備驅動程序:請求將設備放入 D0 (請參閱方案 2) 并在芯片中設置處理喚醒事件所需的任何專有寄存器;
訪問 PCI 設備配置空間
外圍組件互連PCI設備上的某些操作保留給設備的功能驅動程序。 例如,此類操作包括訪問總線的設備特定配置空間,以及DMA控制器對直接內存訪問進行編程。 Microsoft 通過兩種方法為訪問 PCI 設備的配置空間提供系統支持:
- BUS_INTERFACE_STANDARD總線接口
- 配置 I/O 請求數據包 (IRP) 、 IRP_MN_READ_CONFIG 和 IRP_MN_WRITE_CONFIG
從 Windows 10 版本 2004 開始,如果設備具有安全設備 (SDEV) ACPI 表且啟用了基于虛擬化的安全性,則會對不受支持的 PCI 設備配置空間訪問方法施加限制。 如果驅動程序或進程嘗試使用上面未列出的方法讀取或操作 PCI 設備配置空間,則訪問將被阻止,并導致系統 bug 檢查。
根據 PCI 本地總線 規范的定義,Windows XP 和 Windows Server 2003 及更高版本的操作系統對配置空間標頭以及功能鏈接列表中的所有功能具有獨占控制權。 驅動程序不得嘗試修改這些寄存器。
但是,驅動程序可以使用 IRP_MN_WRITE_CONFIG 請求或 BUS_INTERFACE_STANDARD 的 SetBusData 方法寫入不屬于供應商定義的標頭或功能列表的配置空間。 驅動程序還可以使用 BUS_INTERFACE_STANDARD 的 IRP_MN_READ_CONFIG 請求或 GetBusData 方法讀取設備的功能。 若要使用IRP_MN_READ_CONFIG或IRP_MN_WRITE_CONFIG,驅動程序必須在PASSIVE_LEVEL運行。?
驅動程序可以從擴展 PCI 設備配置空間讀取,即使用 IRP_MN_READ_CONFIG 請求或 getBusData BUS_INTERFACE_STANDARD 方法超過 256 字節的配置數據。 同樣,驅動程序可以使用 IRP_MN_WRITE_CONFIG 請求或 BUS_INTERFACE_STANDARD 的 SetBusData 方法寫入擴展的 PCI 設備配置空間。 如果設備沒有擴展配置空間,或者平臺未定義設備上擴展配置空間的路徑,則讀取請求將返回0xFFFF,寫入請求將不起作用。 若要確定操作是否成功,驅動程序可以檢查讀取或寫入的字節數。
PCI Express 和 PCI-X 模式 2 支持大于 256 字節的擴展 PCI 設備配置空間。 驅動程序可以讀取和寫入此配置空間,但只能使用適當的硬件和 BIOS 支持。 在 ACPI BIOS 中,根總線的 PNP ID 必須為 PNP0A08 或 PNP0A03。 對于 PNP ID 為 PNP0A03 的根總線,具有函數 4 的 _DSM 方法應指示當前模式為 PCI-X 模式 2。 所有網橋和設備都應為 PCI express 或在 PCI-X 模式 2 中運行。
此外,系統應支持內存映射配置空間訪問。 這是通過在系統 BIOS/固件中定義 MCFG 表。 Windows Vista 和 Windows Server 2008 及更高版本的操作系統自動支持內存映射配置空間訪問。
HalGetBusDataByOffset 和 HalSetBusDataByOffset 是為向后兼容而提供的,但僅當無法使用上述兩種方法時才應使用。