211
技術社區[雲棲]
5.1 TLP的格式
當處理器或者其他PCIe設備訪問PCIe設備時,所傳送的數據報文首先通過事務層被封裝為一個或者多個TLP,之後才能通過PCIe總線的各個層次發送出去。TLP的基本格式如圖5?1所示。
一個完整的TLP由1個或者多個TLP Prefix、TLP頭、Data Payload(數據有效負載)和TLP Digest組成。TLP頭是TLP最重要的標誌,不同的TLP其頭的定義並不相同。TLP頭包含了當前TLP的總線事務類型、路由信息等一係列信息。在一個TLP中,Data Payload的長度可變,最小為0,最大為1024DW。
TLP Digest是一個可選項, 一個TLP是否需要TLP Digest由TLP頭決定。Data Payload也是一個可選項,有些TLP並不需要Data Payload,如存儲器讀請求、配置和I/O寫完成TLP並不需要Data Payload。
TLP Prefix由PCIe V2.1總線規範引入,分為Local TLP Prefix和EP-EP TLP Prefix兩類。其中Local TLP Prefix的主要作用是在PCIe鏈路的兩端傳遞消息,而EP-EP TLP Prefix的主要作用是在發送設備和接收設備之間傳遞消息。設置TLP Prefix的主要目的是為了擴展TLP頭,並以此支持PCIe V2.1規範的一些新的功能。
TLP頭由3個或者4個雙字(DW)組成。其中第一個雙字中保存通用TLP頭,其他字段與通用TLP頭的Type字段相關。一個通用TLP頭由Fmt、Type、TC、Length等字段組成,如圖5?2所示。
如果存儲器讀寫TLP支持64位地址模式時,TLP頭的長度為4DW,否則為3DW。而完成報文的TLP頭不含有地址信息,使用的TLP頭長度為3DW。其中Byte 4~Byte 15的格式與TLP相關,下文將結合具體的TLP介紹這些字段。
1.1.1 通用TLP頭的Fmt字段和Type字段
Fmt和Type字段確認當前TLP使用的總線事務,TLP頭的大小是由3個雙字還是4個雙字組成,當前TLP是否包含有效負載。其具體含義如表5?1所示。
Fmt[2:0] | TLP的格式 |
0b000 | TLP大小為3個雙字,不帶數據。 |
0b001 | TLP大小為4個雙字,不帶數據。 |
0b010 | TLP大小為3個雙字,帶數據。 |
0b011 | TLP大小為4個雙字,帶數據。 |
0b100 | TLP Prefix |
其他 | PCIe總線保留 |
其中所有讀請求TLP都不帶數據,而寫請求TLP帶數據,而其他TLP可能帶數據也可能不帶數據,如完成報文可能含有數據,也可能僅含有完成標誌而並不攜帶數據。在TLP的Type字段中存放TLP的類型,即PCIe總線支持的總線事務。該字段共由5位組成,其含義如表5?2所示。
TLP類型 | Fmt[2:0] | Type[4:0] | 描述 |
MRd | 0b000 0b001 | 0b0 0000 | 存儲器讀請求;TLP頭大小為3個或者4個雙字,不帶數據。 |
MRdLk | 0b000 0b001 | 0b0 0001 | 帶鎖的存儲器讀請求;TLP頭大小為3個或者4個雙字,不帶數據。 |
MWr | 0b010 0b011 | 0b0 0000 | 存儲器寫請求;TLP頭大小為3個或者4個雙字,帶數據。 |
IORd | 0b000 | 0b0 0010 | IO讀請求;TLP頭大小為3個雙字,不帶數據。 |
IOWr | 0b010 | 0b0 0010 | IO寫請求;TLP頭大小為3個雙字,帶數據。 |
CfgRd0 | 0b000 | 0b0 0100 | 配置0讀請求;TLP頭大小為3個雙字,不帶數據。 |
CfgWr0 | 0b010 | 0b0 0100 | 配置0寫請求;TLP頭大小為3個雙字,帶數據。 |
CfgRd1 | 0b000 | 0b0 0101 | 配置1讀請求;不帶數據。 |
CfgWr1 | 0b010 | 0b0 0101 | 配置1寫請求;帶數據。 |
TCfgRd | 0b010 | 0b1 1011 | 本書對這兩種總線事務不做介紹。 |
TCfgWr | 0b001 | 0b1 1011 |
|
Msg | 0b001 | 0b1 0r2r1r0 | 消息請求;TLP頭大小為4個雙字,不帶數據。“rrr”字段是消息請求報文的Route字段,下文將詳細介紹該字段。 |
MsgD | 0b011 | 0b1 0r2r1r0 | 消息請求;TLP頭大小為4個雙字,帶數據。 |
Cpl | 0b000 | 0b0 1010 | 完成報文;TLP頭大小為3個雙字,不帶數據。包括存儲器、配置和I/O寫完成。 |
CplD | 0b001 | 0b0 1010 | 帶數據的完成報文,TLP頭大小為3個雙字,包括存儲器讀、I/O讀、配置讀和原子操作讀完成。 |
CplLk | 0b000 | 0b0 1011 | 鎖定的完成報文,TLP頭大小為3個雙字,不帶數據。 |
CplDLk | 0b010 | 0b0 1011 | 帶數據的鎖定完成報文,TLP頭大小為3個雙字,帶數據。 |
FetchAdd | 0b010 0b011 | 0b0 1100 | Fetch and Add原子操作。 |
Swap | 0b010 0b011 | 0b0 1101 | Swap原子操作。 |
CAS | 0b010 0b011 | 0b0 1110 | CAS原子操作。 |
LPrfx | 0b100 | 0b0 L3L2L1L0 | Local TLP Prefix |
EPrfx | 0b100 | 0b1 E3E2E1E0 | End-End TLP Prefix |
由上表所示,存儲器讀和寫請求,IO讀和寫請求,及配置讀和寫請求的type字段相同,如存儲器讀和寫請求的Type字段都為0b0 0000。此時PCIe總線規範使用Fmt字段區分讀寫請求,當Fmt字段是“帶數據”的報文,一定是“寫報文”;當Fmt字段是“不帶數據”的報文,一定是“讀報文”。
PCIe總線的數據報文傳送方式與PCI總線數據傳送有類似之處。其中存儲器寫TLP使用Posted方式進行傳送,而其他總線事務使用Non-Posted方式。
PCIe總線規定所有Non-Posted存儲器請求使用Split總線方式進行數據傳遞。當PCIe設備進行存儲器讀、I/O讀寫或者配置讀寫請求時,首先向目標設備發送數據讀寫請求TLP,當目標設備收到這些讀寫請求TLP後,將數據和完成信息通過完成報文(Cpl或者CplD)發送給源設備。
其中存儲器讀、I/O讀和配置讀需要使用CplD報文,因為目標設備需要將數據傳遞給源設備;而I/O寫和配置寫需要使用Cpl報文,因為目標設備不需要將任何數據傳遞給源設備,但是需要通知源設備,寫操作已經完成,數據已經成功地傳遞給目標設備。
在PCIe總線中,進行存儲器或者I/O寫操作時,數據與數據包頭一起傳遞;而進行存儲器或者I/O讀操作時,源設備首先向目標設備發送讀請求TLP,而目標設備在準備好數據後,向源設備發出完成報文。
PCIe總線規範還定義了MRdLk報文,該報文的主要作用是與PCI總線的鎖操作相兼容,但是PCIe總線規範並不建議用戶使用這種功能,因為使用這種功能將極大影響PCIe總線的數據傳送效率。
與PCI總線並不相同,PCIe總線規範定義了Msg報文,即消息報文。分別為Msg和MsgD,這兩種報文的區別在於一個報文可以傳遞數據,一個不能傳遞數據。
PCIe V2.1總線規範還補充了一些總線事務,如、Swap、CAS、LPrfx和EPrfx。其中LPrfx和EPrfx總線事務分別與Local TLP Prefix和EP-EP TLP Prefix對應。在PCIe總線規範V2.0中,TLP頭的大小為1DW,而使用LPrfx和EPrfx總線事務可以對TLP頭進行擴展,本節不對這些TLP Prefix做進一步介紹。PCIe設備可以使用FetchAdd、Swap和CAS總線事務進行原子操作,本篇將在第5.3.5節詳細介紹該類總線事務。
5.1.2 TC字段
TC字段表示當前TLP的傳送類型,PCIe總線規定了8種傳輸類型,分別為TC0~TC7,缺省值為TC0,該字段與PCIe的QoS相關。PCIe設備使用TC區分不同類型的數據傳遞,而多數EP中隻含有一個VC,因此這些EP在發送TLP時,也僅僅使用TC0,但是有些對實時性要求較高的EP中,含有可以設置TC字段的寄存器。
在Intel的高精度聲卡控製器(High Definition Audio Controller)的擴展配置空間中含有一個TCSEL寄存器。係統軟件可以設置該寄存器,使聲卡控製器發出的TLP使用合適的TC。聲卡控製器可以使用TC7傳送一些對實時性要求較強的控製信息,而使用TC0傳送一般的數據信息。在具體實現中,一個EP也可以將控製TC字段的寄存器放入到設備的BAR空間中,而不必和Intel的高精度聲卡控製器相同,存放在PCI配置空間中。
目前許多處理器係統的RC僅支持一個VC通路,此時EP使用不同的TC進行傳遞數據的意義不大。x86處理器的MCH中一般支持兩個VC通路,而多數PowerPC處理器僅支持一個VC通路。PLX公司的多數Switch也僅支持兩個VC通路。
有些RC,如MPC8572處理器,也能決定其發出TLP使用的TC。在該處理器的PCIe Outbound窗口寄存器(PEXOWARn)中,含有一個TC字段,通過設置該字段可以確定RC發出的TLP使用的TC字段。不同的TC可以使用PCIe鏈路中的不同VC,而不同的VC的仲裁級別並不相同。EP或者RC通過調整其發出TLP的TC字段,可以調整TLP使用的VC,從而調整TLP的優先級。
5.1.3 Attr字段
Attr字段由3位組成,其中第2位表示該TLP是否支持PCIe總線的ID-based Ordering;第1位表示是否支持Relaxed Ordering;而第0位表示該TLP在經過RC到達存儲器時,是否需要進行Cache共享一致性處理。Attr字段如圖5?3所示。
一個TLP可以同時支持ID-based Ordering和Relaxed Ordering兩種位序。Relaxed Ordering最早在PCI-X總線規範中提出,用來提高PCI-X總線的數據傳送效率;而ID-based Ordering由PCIe V2.1總線規範提出。TLP支持的序如表5?3所示。
Attr[2] | Attr[1] | 類型 |
0 | 0 | 缺省序,即強序模型 |
0 | 1 | PCI-X Relaxed Ordering模型 |
1 | 0 | ID-Based Ordering(IDO)模型 |
1 | 1 | 同時支持Relaxed Ordering和IDO模型 |
當使用標準的強序模型時,在數據的整個傳送路徑中,PCIe設備在處理相同類型的TLP時,如PCIe設備發送兩個存儲器寫TLP時,後麵的存儲器寫TLP必須等待前一個存儲器寫TLP完成後才能被處理,即便當前報文在傳送過程中被阻塞,後一個報文也必須等待。
如果使用Relaxed Ordering模型,後一個存儲器寫TLP可以穿越前一個存儲器寫TLP,提前執行,從而提高了PCIe總線的利用率。有時一個PCIe設備發出的TLP,其目的地址並不相同,可能先進入發送隊列的TLP,在某種情況下無法發送,但這並不影響後續TLP的發送,因為這兩個TLP的目的地址並不相同,發送條件也並不相同。
值得注意的是,在使用PCI總線強序模型時,不同種類的TLP間也可以亂序通過同一條PCIe鏈路,比如存儲器寫TLP可以超越存儲器讀請求TLP提前進行。而PCIe總線支持Relaxed Ordering模型之後,在TLP的傳遞過程中出現亂序種類更多,但是這些亂序仍然是有條件限製的。在PCIe總線規範中為了避免死鎖,還規定了不同報文的傳送數據規則,即Ordering Rules。
PCIe V2.1總線規範引入了一種新的“序”模型,即IDO(ID-Based Ordering)模型,IDO模型與數據傳送的數據流相關,是PCIe V2.1規範引入的序模型。
Attr字段的第0位是“No Snoop Attribute”位。當該位為0時表示當前TLP所傳送的數據在通過FSB時,需要與Cache保持一致,這種一致性由FSB通過總線監聽自動完成而不需要軟件幹預;如果為1,表示FSB並不會將TLP中的數據與Cache進行一致,在這種情況下,進行數據傳送時,必須使用軟件保證Cache的一致性。
在PCI總線中沒有與這個“No Snoop Attribute”位對應的概念,因此一個PCI設備對存儲器進行DMA操作時會進行Cache一致性操作。這種“自動的”Cache一致性行為在某些特殊情況下並不能帶來更高的效率。
當一個PCIe設備對存儲器進行DMA讀操作時,如果傳送的數據非常大,比如512MB,Cache的一致性操作不但不會提高DMA寫的效率,反而會降低。因為這個DMA讀訪問的數據在絕大多數情況下,並不會在Cache中命中,但是FSB依然需要使用Snoop Phase進行總線監聽。而處理器在進行Cache一致性操作時仍然需要占用一定的時鍾周期,即在Snoop Phase中占用的時鍾周期,Snoop Phase是FSB總線事務的一個階段,如圖3?6所示。
對於這類情況,一個較好的做法是,首先使用軟件指令保證Cache與主存儲器的一致性,並置“No Snoop Attribute”位為1,然後再進行DMA讀操作。同理使用這種方法對一段較大的數據區域進行DMA寫時,也可以提高效率。
除此之外,當PCIe設備訪問的存儲器,不是“可Cache空間”時,也可以通過設置“No Snoop Attribute”位,避免FSB的Cache共享一致性操作,從而提高FSB的效率。“No Snoop Attribute”位是PCIe總線針對PCI總線的不足,所作出的重要改動。
5.1.4 通用TLP頭中的其他字段
除了Fmt和Type字段外,通用TLP頭還含有以下字段。
1 TH位、TD位和EP位
TH位為1表示當前TLP中含有TPH(TLP Processing Hint)信息,TPH是PCIe V2.1總線規範引入的一個重要功能。TLP的發送端可以使用TPH信息,通知接收端即將訪問數據的特性,以便接收端合理地預讀和管理數據,TPH的詳細介紹見第5.3.6節。
TD位表示TLP中的TLP Digest是否有效,為1表示有效,為0表示無效。而EP位表示當前TLP中的數據是否有效,為1表示無效,為0表示有效。
2 AT字段
AT字段與PCIe總線的地址轉換相關。在一些PCIe設備中設置了ATC(Address Translation Cache)部件,這個部件的主要功能是進行地址轉換。隻有在支持IOMMU技術的處理器係統中,PCIe設備才能使用該字段。
AT字段可以用作存儲器域與PCI總線域之間的地址轉換,但是設置這個字段的主要目的是為了方便多個虛擬主機共享同一個PCIe設備。對這個字段有興趣的讀者可以參考Address Translation Sevices規範,這個規範是PCI的IO Virtualization規範的重要組成部分。對虛擬化技術有興趣的讀者可以參考清華大學出版社的《係統虛擬化——原理與實現》,以獲得基本的關於虛擬化的入門知識。
3 Length字段
Length字段用來描述TLP的有效負載(Data Payload)大小。PCIe總線規範規定一個TLP的Data Payload的大小在1B~4096B之間。PCIe總線設置Length字段的目的是提高總線的傳送效率。
當PCI設備在進行數據傳送時,其目標設備並不知道實際的數據傳送大小,這在一定程度上影響了PCI總線的數據傳送效率。而在PCIe總線中,目標設備可以通過Length字段提前獲知源設備需要發送或者請求的數據長度,從而合理地管理接收緩衝,並根據實際情況進行Cache一致性操作。
當PCI設備進行DMA寫操作,將PCI設備中4KB大小的數據傳送到主存儲器時,這個PCI設備的DMA控製器將存放傳送的目的地址和傳送大小,然後啟動DMA寫操作,將數據寫入到主存儲器。由於PCI總線是一條共享總線,因此傳送4KB大小的數據,可能會使用若幹個PCI總線寫事務才能完成,而每一個PCI總線寫事務都不知道DMA控製器何時才能將數據傳送完畢。
如果這些總線寫事務還通過一係列PCI橋才能到達存儲器,在這個路徑上的每一個PCI橋也無法預知,何時這個DMA操作才能結束。這種“不可預知”將導致PCI總線的帶寬不能被充分利用,而且極易造成PCI橋數據緩衝的浪費。
而PCIe總線通過TLP的Length字段,可以有效避免PCIe鏈路帶寬的浪費。值得注意的是,Length字段以DW為單位,其最小單位為1個DW。如果PCIe主設備傳送的單位小於1個DW或者傳送的數據並不以DW對界時,需要使用字節使能字段,即“DW BE”字段。有關“DW BE”字段的詳細說明見第5.3.1節。
最後更新:2017-04-03 16:48:37