閱讀221 返回首頁    go 阿裏雲 go 技術社區[雲棲]


5.3 存儲器、I/O和配置讀寫請求TLP

本節講述PCIe總線定義的各類TLP,並詳細介紹這些TLP的格式。在這些TLP中,有些格式對於初學者來說較難理解。讀者需要建立PCIe總線中與TLP相關的一些基本概念,特別是存儲器讀寫相關的報文格式。在PCIe總線中,存儲器讀寫,I/O讀寫和配置讀寫請求TLP由以下幾類報文組成。

(1)      存儲器讀請求TLP和讀完成TLP

PCIe主設備,RC或者EP,訪問目標設備的存儲器空間時,使用Non-Posted總線事務向目標設備發出存儲器讀請求TLP,目標設備收到這個存儲器讀請求TLP後,使用存儲器讀完成TLP,主動向主設備傳遞數據。當主設備收到目標設備的存儲器讀完成TLP後,將完成一次存儲器讀操作。

(2)      存儲器寫請求TLP

PCIe總線中,存儲器寫使用Posted總線事務。PCIe主設備僅使用存儲器寫請求TLP即可完成存儲器寫操作,主設備不需要目標設備的回應報文。

(3)      原子操作請求和完成報文

原子操作由PCIe V2.1總線規範引入,一個完整的原子操作包括原子操作請求和原子操作完成報文組成。原子操作的使用方法與其他Non-Posted總線事務類似,首先PCIe主設備向目標設備發送原子操作請求,之後目標設備向主設備發送原子操作完成報文,結束一次原子操作。有關原子操作的詳細說明見第5.3.5節。

(4)      I/O讀寫請求TLP和讀寫完成TLP

PCIe總線中,I/O讀寫操作使用Non-Posted總線事務,I/O讀寫TLP都需要完成報文做為回應。隻是在I/O寫請求的完成報文中不需要“帶數據”,而僅含有I/O寫請求是否成功的狀態信息。

(5)      配置讀寫請求TLP和配置讀寫完成TLP

從總線事務的角度上看,配置讀寫請求操作的過程與I/O讀寫操作的過程類似。配置讀寫請求TLP都需要配置讀寫完成作為應答,從而完成一個完成的配置讀寫操作。

(6)      消息報文

PCI總線相比,PCIe總線增加了消息請求事務。PCIe總線使用基於報文的數據傳送模式,所有總線事務都是通過報文實現的,PCIe總線取消了一些在PCI總線中存在的邊帶信號。在PCIe總線中,一些由PCI總線的邊帶信號完成的工作,如中斷請求和電源管理等,在PCIe總線中由消息請求報文實現。

5.3.1 存儲器讀寫請求TLP

存儲器讀寫請求TLP的格式如5?8所示。

PCIe總線中,存儲器寫請求TLP使用Posted數據傳送方式。而其他與存儲器和I/O相關的報文都使用Split方式進行數據傳送,這些請求報文需要完成報文,通知發送端之前的數據請求報文已經被處理完畢,有關完成報文的詳細說明見第5.3.2節。

存儲器讀寫請求TLP使用地址路由方式進行數據傳遞,在這類TLP頭中包含Address字段,Address字段具有兩種地址格式,分別是32位和64位地址。在存儲器讀寫和I/O讀寫請求的第3和第4個雙字中,存放TLP32或者64位地址。存儲器、I/O和原子操作讀寫請求使用的TLP頭較為類似。本節僅介紹存儲器、I/O讀寫使用的TLP頭,而在第5.3.5節詳細介紹原子操作。

1 Length字段

在存儲器讀請求TLP中並不包含Data Payload,在該報文中,Length字段表示需要從目標設備數據區域讀取的數據長度;而在存儲器寫TLP中,Length字段表示當前報文的Data Payload長度。

Length字段的最小單位為DW。當該字段為n時,表示需要獲得的數據長度或者當前報文的數據長度為nDW,其中0?n?0x3FF。值得注意的是,當n等於0時,表示數據長度為1024DW

2 DW BE字段

PCIe總線以字節為基本單位進行數據傳遞,但是Length字段以DW為最小單位。為此TLP使用Last DW BEFirst DW BE這兩個字段進行字節使能,使得在一個TLP中,有效數據以字節為單位。

這兩個DW BE字段各由4位組成,其中Last DW BE字段的每一位對應數據Payload最後一個雙字的字節使能位;而First DW BE字段的每一位對應數據Payload第一個雙字的字節使能位。其對應關係如5?5所示。

5?5 FirstLast DW BE字段

Last DW BE

3

1表示數據Payload的最後一個雙字的字節3有效

2

1表示數據Payload的最後一個雙字的字節2有效

1

1表示數據Payload的最後一個雙字的字節1有效

0

1表示數據Payload的最後一個雙字的字節0有效

First DW BE

3

1表示數據Payload的第一個雙字的字節3有效

2

1表示數據Payload的第一個雙字的字節2有效

1

1表示數據Payload的第一個雙字的字節1有效

0

1表示數據Payload的第一個雙字的字節0有效

 

Last DW BEFirst DW BE這兩個字段的使用規則如下。

  • 如果傳送的數據長度在一個對界的雙字(DW)之內,則Last DW BE字段為0b0000,而First DW BE的對應位置1;如果數據長度超過1DWLast DW BE字段一定不能為0b0000PCIe總線使用Last DW BE字段為0b0000表示所傳送的數據在一個對界的DW之內。
  • 如果傳送的數據長度超過1DW,則First DW BE字段至少有一個位使能。不能出現First DW BE0b0000的情況。
  • 如果傳送的數據長度大於等於3DW,則在First DW BELast DW BE字段中不能出現不連續的置1位。
  • 如果傳送的數據長度在1DW之內時,在First DW BE字段中允許有不連續的置1位。此時PCIe總線允許在TLP中傳送1DW的第13字節或者第02字節。
  • 如果傳送的數據長度為2DW之內時,則First DW BE字段和Last DW BE字段允許有不連續的置1位。

值得注意的是,PCIe總線支持一種特殊的讀操作,即“Zero-Length”讀請求。此時Length字段的長度為1DW,而First DW BE字段和Last DW BE字段都為0b0000,即所有字節都不使能。此時與這個存儲器讀請求TLP對應的讀完成TLP中不包含有效數據。再次提醒讀者注意“Zero-Length”讀請求使用的Length字段為1,而不是為0,為0表示需要獲得的數據長度為1024DW

Zero-Length”讀請求的引入是為了實現“讀刷新”操作,該操作的主要目的是為了確保之前使用Posted方式所傳送的數據,到達最終的目的地,與“Zero-Length”讀對應的讀完成報文中不含有負載,從而提高了PCIe鏈路的利用率。

PCIe總線中,使用Posted方式進行存儲器寫時,目標設備不需要向主設備發送回應報文,因此主設備並不知道這個存儲器寫是否已經達到目的地。而主設備可以使用“讀刷新”操作,向目標設備進行讀操作來保證存儲器寫最終到達目的地。

PCIe總線中,標準的存儲器讀請求也可以完成同樣的刷新操作。但是“Zero-Length”讀請求與這種讀請求相比,其完成報文不需要“Data Payload”,因此在一定程度上提高了PCIe總線的效率。如果一個存儲器讀請求TLP報文的TH位為1時,DW BE字段將被重新定義為ST[7:0]字段,有關ST字段的詳細說明見第5.3.6節。

3 Requester ID字段

Requester ID字段包含“生成這個TLP報文”的PCIe設備的總線號(Bus Number)、設備號(Device Number)和功能號(Function Number),其格式如5?9所示。對於存儲器寫請求TLPRequester ID字段並不是必須的,因為目標設備收到存儲器寫請求TLP後,不需要完成報文作為應答,因此Requester ID字段對於存儲器寫請求TLP並沒有實際意義。

但是PCIe總線規範並沒有明確說明存儲器寫請求TLP究竟需不需要Requester ID字段,為此IC設計者依然需要將存儲器寫TLPRequester ID字段置為有效。值得注意的是,如果一個存儲器寫請求TLP報文的TH位為1時,Tag字段將被重新定義為ST[7:0]字段,有關ST字段的詳細說明見第5.3.6節。

對於Non-Posted數據請求,目標設備需要使用完成報文做為回應。在這個完成報文中,需要使用源設備的Requester ID字段。因此在Non-Posted數據請求TLP中,如存儲器讀請求、I/O和配置讀寫請求TLP,必須使用Requester ID字段。

存儲器,I/O讀請求TLP中含有Requester IDTag字段。在PCIe總線中Requester IDTag字段合稱為Transaction IDTransaction ID字段的格式如5?9所示。存儲器讀,I/O和配置讀寫請求TLP使用Transaction字段的主要目的是使接收端通過分析報文的Transaction ID,確認完成報文的目的地。

PCIe總線中,所有Non-Posted數據請求都需要完成報文作為應答,才能結束一次完整的數據傳遞。一個源設備在發送Non-Posted數據請求之後,如果並沒有收到目標設備回送的完成報文,TLP報文的發送端需要保存這個Non-Posted數據請求,此時該設備使用的Transaction ID(Tag字段)不能被再次使用,直到一次數據傳送結束,即數據發送端收齊與該TLP對應的所有完成報文。

PCIe設備發出的每一個Non-Posted數據請求TLP,在同一個時刻段內Transaction ID必須是唯一的。即在同一時間段內,在當前PCI總線域中不能存在兩個或者兩個以上的存儲器讀請求TLP,其Transaction ID完全相同。

源設備發送Non-Posted數據請求後,在沒有獲得全部完成報文之前,不能釋放這個Transaction ID占用的資源。在同一個PCIe設備發送的TLP中,其Requester ID字段是相同的,因此PCIe設備的設計者所能管理的資源是Tag字段。PCIe設備的設計者需要合理地管理Tag資源,以保證數據傳送的正確性。

PCIe設備在發送Non-Posted數據請求時,需要暫存這些Non-Posted數據請求。其中Tag字段的長度決定了發送端能夠暫存多少個同類型的TLP,如果Tag字段長度為5,發送端能夠暫存32個報文;如果PCIe設備使能了Extended Tag位,Tag字段可以由8位組成,此時發送端能夠暫存256個報文。

通過Tag字段的長度,可以發現每個PCIe設備最多可以暫存256個同類型的Non-Posted報文。但是在多數情況下,一個PCIe設備可能隻包含1Function。因此PCIe設備還可以使用Function號擴展Tag字段,從而擴展“暫存TLP報文”的數目。

PCIe設備在PCI Express Capability結構的Device Control寄存器中,設置了一個Phantom Functions Enable位,。當一個PCIe設備僅支持一個Function時,Phantom Functions Enable位可以被設置為1,此時PCIe設備可以使用Requester IDFunction Number字段對Tag字段進一步擴展,此時一個PCIe設備最多可以支持2048個同類型的數據請求。

由以上分析可以發現,一個PCIe設備最多可以支持2048個存儲器讀數據請求,基本上可以滿足絕大多數需要。但是在某些特殊應用場合,PCIe設備即使可以暫存2048個存儲器讀請求,也並不足夠。

PCI總線相比,PCIe總線的數據傳送延時較長,而為了彌補這個傳送延時,PCIe設備通常使用流水線技術。此時PCIe設備必須能夠連續發送多個存儲器讀請求報文,隨後RC也將連續回送多個存儲器讀完成報文,在PCIe設備的實現中,需要保證能夠源源不斷地從RC接收這些報文,以充分利用報文接收流水線,。

PCIe V2.1總線規範還提出了另一種Requester ID格式,即ARI (Alternative Routing-ID Interpretation)格式,除了Requester ID外,在完成報文中使用的Completer ID也可以使用這種格式。ARI格式將ID號分為兩個字段,分別為Bus號和Function號,而不使用Device號,ARI格式如5?10所示。

PCIe總線引入ARI格式的依據是在一個PCIe鏈路上僅可能存在一個PCIe設備,因而其Device號一定為0。在多數PCIe設備中,Requester IDCompletion ID包含的Device號是沒有意義的。使用ARI格式時,一個PCIe設備最多可以支持256Function,而傳統的PCIe設備最多隻能支持8Function

4 I/O讀寫請求TLP的規則

I/O讀寫請求與存儲器讀寫請求TLP的格式基本類似,隻是I/O讀寫請求TLP隻能使用32位地址模式和基於地址的路由方式,而且I/O讀寫請求TLP隻能使用Non-Posted方式進行傳遞。PCIe總線並不建議PCIe設備支持I/O地址空間,但是SwitchRC需要具備接收和發送I/O請求報文的能力,因為許多老的PCI設備依然使用I/O地址空間,這些PCI設備可以通過PCIe橋連接到PCIe總線中。因此雖然支持I/O讀寫請求的PCIe設備極少,但是在PCIe體係結構中,依然需要支持PCI總線域的I/O地址空間。

與存儲器讀寫請求TLP不同,I/O讀寫請求TLP的某些字段必須為以下值。

  • TC[2:0]必須為0I/O請求報文使用的TC標簽隻能為0
  • THAttr2位保留,而Attr[1:0]必須為“0b00”,這表示I/O請求報文必須使用PCI總線的強序數據傳送模式,而且在傳送過程中,硬件保證其傳送的數據與Cache保持一致,實際上I/O地址空間都是不可Cache的。
  •  AT[1:0]必須為“0b00”,表示不支持地址轉換,因此在虛擬化技術中,並不處理PCI總線域中的I/O空間。
  • Length[9:0]為“0b00 0000 0001”,表示I/O讀寫請求TLP最大的數據Payload1DW,該類TLP不支持突發傳送。
  • Last DW[3:0]為“0b0000”。

5.3.2 完成報文

PCIe總線支持Split傳送方式,目標設備使用完成報文向源設備主動發送數據。完成報文使用ID路由方式,由TLP Predix、報文頭和Data Payload組成,但是在某些完成報文可以不含有Data Payload,如I/O或者配置寫完成和Zero-Length讀完成報文。在PCIe總線中,有一下幾類數據請求需要收到完成報文之後,才能完成整個數據傳送過程,完成報文格式如5?11所示。

  • 所有的數據讀請求,包括存儲器、I/O讀請求、配置讀請求和原子操作請求。當一個PCIe設備發出這些數據請求報文後,必須收到目標設備的完成報文後,才能結束一次數據傳送。這一類完成報文必須包含Data Payload
  • 所有的Non-Posted數據寫請求,包括I/O和配置寫請求。當一個PCIe設備發出這些數據請求報文後,必須收到目標設備的完成報文後,才能結束數據傳送。但是這一類完成報文不包含數據,僅包含應答信息。
  • ATS機製相關的一些報文。

完成報文“Byte 0”中的大部分字段與“存儲器,I/O、配置請求報文”的對應字段的含義相同。完成報文一次最多能夠傳送的報文大小不能超過Max_Payload_Size參數。在多數處理器中,完成報文中包含的數據在一個Cache行之內,完成報文使用RCB參數來處理數據對界,RCB參數的大小與處理器係統的Cache行長度和DDR-SDRAM的一次突發傳送長度相關,這些參數的詳細描述見第5.4.3節。在x86PowerPC處理器中,一個存儲器讀完成報文一般不超過RCB參數。

1 Requester IDTag字段

完成報文使用ID路由方式,ID路由方式詳見第5.2.2節。完成報文頭的長度為3DW,完成報文頭中包含Transaction ID信息,由Requester IDTag字段組成,這個ID必須與源設備發送的數據請求報文的Transaction ID對應,完成報文使用Transaction ID進行ID路由,並將數據發送給源設備。

PCIe設備收到存儲器讀、I/O讀寫或者配置讀寫請求TLP時,需要首先保存這些報文的Transaction ID,之後當該設備準備好完成報文後,將完成報文的Requester IDTag字段賦值為之前保存的Transaction ID字段。

2 Completer ID字段

Completer ID字段的含義與Requester ID字段較為相似,隻是該字段存放“發送完成報文”的PCIe設備的ID號。PCIe設備進行數據請求時需要在TLP字段中包含Requester ID字段;而使用完成報文結束數據請求時,需要提供Completer ID字段。

3 Status字段

Status字段保存當前完成報文的完成狀態,表示當前TLP是正確地將數據傳遞給數據請求端;還是在數據傳遞過程中出現錯誤;或者要求數據請求方進行重試。PCIe總線規定了幾類完成狀態,如5?6所示。

5?6 Status字段

Status[2:0]

描述

0b000

SC(Sucessful Completion),正常結束

0b001

UR(Unsupported Request),不支持的數據請求

0b010

CRS(Configuration Request Retry Status),要求數據請求方進行重試。當RC對一個PCIe目標設備發起配置請求時,如果該目標設備沒有準備好,可以向RC發出CRS完成報文,當RC收到這類報文時,不能結束本次配置請求,必須擇時重新發送配置請求

0b100

CA(Completion Abort),數據夭折。表示目標設備無法完成本次數據請求

其他

保留

 

4 BCM位與Byte Count字段

BCM(Byte Count Modified)字段由PCI-X設備設置。PCI-X設備也支持Split Transaction傳送方式,當PCI-X設備進行存儲器讀請求時,目標設備不一定一次就能將所有數據傳遞給源設備。此時目標設備在進行第一次數據傳送時,需要設置Byte Count字段和BCM位。

BCM位表示Byte Count字段是否被更改,該位僅對PCI-X設備有效,而PCIe設備不能操縱BCM位,隻有PCI-X設備或者PCIe-to-PCI-X橋可以改變該位。本節對此位不做進一步介紹,對此位感興趣的讀者可以參考PCI-X Addendum to the PCI Local Bus Specification, Revision 2.0

Byte Count字段記錄源設備還需要從目標設備中,獲得多少字節的數據就能完成全部數據傳遞,當前TLP中的有效負載也被Byte Count字段統計在內。該字段由12位組成。該字段為0b0000-0000-0001表示還剩一個字節,為0b1111-1111-1111表示還剩4095個字節,而為0b0000-0000-0000表示還剩4096個字節。除了存儲器讀請求的完成報文外,大多數完成報文的Byte Count字段為4

如一個源設備向目標設備發送一個“讀取128B的存儲器讀請求TLP”,而目標設備收到這個讀請求TLP後,可能使用兩個存儲器讀完成TLP傳遞數據。其中第1個存儲器讀完成TLP的有效數據為64B,而Byte Count字段為128;第2個存儲器讀完成TLP中的有效數據為64B,而Byte Count字段也為64。當數據請求端接收完畢第1個存儲器讀完成TLP後,發現還有64B的數據沒有接收完畢,此時必須等待下一個存儲器讀完成TLP。等到數據請求端收齊所有數據後,才能結束整個存儲器讀請求。

目標設備發出的第2個讀完成TLP中的有效數據為64B,而Byte Count字段為64,當數據請求端接收完畢這個讀完成TLP後,將完成一個完整的存儲器讀過程,從而可以釋放這個存儲器讀過程使用的Tag資源。存儲器讀請求的完成報文的拆分方式較為複雜,Byte Count字段的設置也相對較為複雜。

5 Lower Address字段

如果當前完成報文為存儲器讀完成TLP,該字段存放在存儲器讀完成TLP中第一個數據所對應地址的最低位。值得注意的是,在完成報文中,並不存在First DW BELast DW BE字段,因此接收端必須使用存儲器讀完成TLPLow Address字段,識別一個TLP中包含數據的起始地址。

5.3.3 配置讀寫請求TLP

配置讀寫請求TLPRC發起,用來訪問PCIe設備的配置空間。配置請求報文使用基於ID的路由方式。PCIe總線也支持兩種配置請求報文,分別為Type 00hType 01h配置請求。配置請求TLP的格式如5?12所示。

配置請求TLP的第4~7字節與存儲器請求TLP類似。而第8~11字節的BusDeviceFunction Number中存放該TLP訪問的目標設備的相應的號碼,而Ext RegisterReigister Number存放寄存器號。配置請求報文的其他字段必須為以下值。

  • TC[2:0]必須為0I/O請求報文的傳送類型(TC)隻能為0
  • TH位為保留位;Attr2位為保留,而Attr[1:0]必須為“00b”,這表示I/O請求報文使用PCI總線的強序數據傳送模式;AT[1:0]必須為“0b00”,表示不進行地址轉換。
  • Length[9:0]為“0b00 0000 0001”,表示配置讀寫請求最大Payload1DW
  • Last DW BE字段為“0b0000”。而First DW BE字段根據配置讀寫請求的大小設置。

5.3.4 消息請求報文

PCIe總線中,多數消息報文使用隱式路由方式,其格式如5?13所示。其中Byte 0字段為通用TLP頭,而Byte 4的第3字節中存放Message Code字段。

PCIe總線規定了以下幾類消息報文。

  • INTx中斷消息報文(INTx Interrupt Signaling)
  • 電源管理消息報文(Power Management)
  • 錯誤消息報文(Error Signaling)
  • 鎖定事務消息報文(Locked Transaction Support)
  • 插槽電源限製消息報文(Slot Power Limit Support)
  • Vendor-Defined Messages

最後更新:2017-04-03 16:48:40

  上一篇:go 5.4 TLP中與數據負載相關的參數
  下一篇:go Davinci DM6446開發攻略——LINUX GPIO驅動源碼移植