參考
書籍《RapidIO The Embedded System Interconnect》
xilinx手冊pg007《Serial RapidIO Gen2 Endpoint v4.1 LogiCORE IP Product Guide》
Zynq-Linux移植學習筆記之14-RapidIO驅動開發
host初始化
直接看RapidIO的初始化,一些底層的比如物理層鏈路層之類的不需要關心,用到了再去看,畢竟都是基于芯片或者IP來開發。先從高層了解這個過程。
系統啟動過程概述
1. host CPU獲取引導代碼,啟動,如果有兩個host,則兩者是同時啟動的。
2. 開始執行系統探測和枚舉算法。
3. 枚舉所有器件并將相關器件信息記錄到器件數據庫,建立host和所有endpoint之間的路由。
? 計算并配置host和所有endpoint之間的最優路徑。
? 用最優路徑信息配置switch。
? 更新路由表。
4. 映射地址空間。
上面提到的最優路徑,就是所謂的枚舉算法的目的,可以是最短路徑或者包含一些用戶約束。
啟動要求
系統初始化之后,所有器件都會擁有一個ID,在系統初始化之前,按照下面設置。RapidIO系統應該只有一個引導代碼器件。
? 設置endpoint ID為0xFF(0xFFFF)。
? 設置引導代碼器件ID為0xFE(0x00FE)。
? 設置host ID為0x00(0x0000)。
枚舉
枚舉過程中,將給每個endpoint分配唯一的器件ID,為了增強容錯性,RapidIO系統可以有兩個host,經過競爭,最終只有一個host來完成枚舉,如果主機枚舉過程失敗并發生超時事件,則另一主機重新枚舉。枚舉算法根據器件ID大小設置優先級,ID大的host競爭獲勝,在枚舉同一個endpoint時會發生競爭,失敗host主動退出枚舉,枚舉結束之后,其他主機可以通過被動發現(passively discovery)收集網絡中的路由拓撲信息。所以host的ID可以設置為0x00(0x0000)和0x01(0x0001),其中0x01的優先級更高。host應當將自己的主機使能位置1,switch沒有這個位,當host釋放對失敗主機的鎖定時,枚舉完成,失敗host自己檢測是否被鎖定和釋放鎖定。在開放式(open)8位器件ID系統中,如果host枚舉失敗,那么失敗主機重新枚舉時,必須等待15秒。在閉合式(closed)或者16位器件ID系統中,超時等待時間需要設計。
Xilinx Srio IP
3. Host Base Device ID Lock CSR,器件鎖定寄存器,復位之后,這個寄存器只能被寫一次(之后被鎖定),配置之后如果寫入值和寄存器值相等,則寄存器值被復位為0xFFFF,向該寄存器寫入0xFFFF不會鎖定寄存器。
4. Maintenance Request Information Register,維護包配置寄存器,地址在0x10100,低16位用于配置目的ID,當用IP發維護包之前,需要配置這個寄存器。
5. Processing Elements Features CAR,表示這個設備提供的功能,可以是Bridge,Memory,Processor,Switch 4種,SRIO IP支持前3種(endpoint),支持16位地址模式,可在vivado中通過GUI設置。
2. CPS1848路由方式,每個端口提供256個緩存來存儲設備路由表,還有256個緩存來存儲域路由表,這樣設計的目的是,在大型的系統里會用到域路由表,大型系統有很多底板,每個底板上也會有很多子板,域路由表用來選擇包被發送到哪一塊板卡,而設備路由表用來將包發送到某個處理單元(某個芯片的SRIO端口)。RIO_DOMAIN由RapidIO Domain Register寄存器確定。
3. 單播(unicast)編程,CPS1848每個端口都有自己的路由表,所以可以支持虛擬網絡,路由配置時,有寄存器The Route Port Select Register selects來控制路由表項是添加到所有端口還是某個端口。路由配置主要是三個寄存器Standard Route Table Entries Configuration destID Select CSR,Standard Route Table Entry Configuration Port Select CSR和Standard Route Table Entry Default Port CSR。
4. 多播編程,用到再說。
5. 上面配置路由的方法是非直接方式(Indirect Programming),配置路由需要操作多次,在多(線程)設備的環境下要做互斥,CPS1848支持另外一種直接方式(Direct Programming)可以支持這種情況。
6. Switch Port Information CAR寄存器,這個寄存器很重要,在多個Switch互聯的系統里,用于確定拓撲關系。
7. Port General Control CSR寄存器,會用到DISCV位,是發現標志位。
8. Port Error and Status CSR寄存器,第1位PORT_OK。
9. Host Base deviceID Lock CSR寄存器,同xilinx SRIO IP。
zynq SRIO系統初始化過程
1. 使能host模式。
2. 配置ID。
3. 配置CPS1848路由,使能端口收發(手冊默認是打開的)。
4. 鎖定host。
5. 搜索系統拓撲。
鎖定host
1. 讀取Lock ID CSR,如果寄存器值等于host ID,則判定已經鎖定,退出,否則進入2。
2. 寫入host ID,再讀取host ID,如果寄存器值大于host ID則進入退避狀態,如果小于host ID,則已經被鎖定(但和另一個host沖突),進入等待退避狀態,等待另一個host退避。如果等于host ID,則鎖定成功。
搜索系統拓撲
這里只考慮Switch是CPS1848的情況,TSI578原理是一致。
1. 如果這個CPS1848是直接與host zynq相連的switch。
? 搜索CPS1848,設置0x13c寄存器Port General Control CSR的DISCV位,表示這個switch已經被發現,設置Component Tag CSR,它是一個設備的身份標識。
? 讀0x14寄存器Switch Port Information CAR得到port數量,就是18。
? 循環搜索每個port,如果是host port則使能端口收發,如果是其他port,讀取鏈路狀態,如果正常,用默認ID 0xFF配置路由,使能端口收發,然后嘗試鎖定該端口設備(Endpoint或Switch),鎖定過程和鎖定host是一樣的。
-如果鎖定成功,讀取Processing Elements Features CAR寄存器,等到Function,判斷設備類型,決定下一步拓撲方式。如果是Endpoint類型,關閉Master Enable,置位Discovered,分配ID號,配置該port的路由表。如果是Switch類型,則遞歸調用Switch枚舉過程。
-如果是已經鎖定狀態(存在環路),直接更新拓撲,不做任何配置。
2. 如果這個CPS1848不和host直接相連。
? 設置DISCV位,得到與上級Switch相連的端口號,設置host的路由,設置默認路由為到host的端口。
? 同上。
? 同上。
現在拓撲關系已經搜索出來了。下面就是配置路由,因為上述搜索過程的路由配置不一定是最優配置,也不滿足用戶的需求。 所以現在需要按照設計需求,生成路由表然后寫到各個Switch。
zynq SRIO驅動
這里實現Linux用戶態的驅動,數據結構定義,
struct srioEndpoint
{
unsigned int devId;
unsigned int hopCnt;
struct srioSwitch* pSw;
unsigned int port;
};
#define SRIO_SW_MAX_PORT 18//get from cps1848
struct srioSwitch
{
unsigned int hopCnt;
unsigned int componentTag;//component tag
unsigned int portNum;
struct srioEndpoint* pEp[SRIO_SW_MAX_PORT];//port connected
unsigned int epNum;
unsigned int portEp[SRIO_SW_MAX_PORT];//for get ep info for certain port fastly
struct srioSwitch* pSw[SRIO_SW_MAX_PORT];//switch connected, complicate and will be implenmented laterly
unsigned int swNum;
unsigned int portSw[SRIO_SW_MAX_PORT];//for get sw info for certain port fastly
struct srioSwitch* pSwParent;
unsigned int portParent;
};
#define SRIO_SYS_MAX_EP_NUM 64
#define SRIO_SYS_MAX_SW_NUM 4
struct srioSystem
{
struct srioEndpoint epInfo[SRIO_SYS_MAX_EP_NUM];
unsigned int epNum;
struct srioSwitch swInfo[SRIO_SYS_MAX_SW_NUM];
unsigned int swNum;
};
編輯:hfy
-
Xilinx
+關注
關注
71文章
2167瀏覽量
121469 -
RapidIO
+關注
關注
1文章
39瀏覽量
20816 -
Zynq
+關注
關注
10文章
610瀏覽量
47185
發布評論請先 登錄
相關推薦
評論