對(duì)于復(fù)雜的系統(tǒng),魯棒性是非常重要的。為了協(xié)助客戶建立魯棒性系統(tǒng),KeyStone器件提供了多種硬件保護(hù)機(jī)制,如內(nèi)存保護(hù)、EDC。本文介紹如何利用這些特性在KeyStone器件上建立一個(gè)魯棒的系統(tǒng)。同時(shí)提供了與文檔配套的例程。
1 簡(jiǎn)介
如圖1所示,KeyStone器件提供了多種協(xié)助客戶建立魯棒性應(yīng)用的特性。
圖1 KeyStone器件魯棒系統(tǒng)
如圖1所示,在LL2、L1P及L1D中集成了內(nèi)存保護(hù)模塊;LL2、SL2及DDR控制器中集成了錯(cuò)誤檢查糾正模塊;L1P 集成了錯(cuò)誤檢測(cè)模塊。MPAX和MPU模塊附在總線上,用于監(jiān)控檢測(cè)以避免非法的總線訪問。每個(gè)DSP CorePac有一個(gè)獨(dú)立的MPAX用于監(jiān)控與MSMC連接的總線。
對(duì)于系統(tǒng)中其他的master,根據(jù)權(quán)限ID進(jìn)行分類。對(duì)每個(gè)權(quán)限ID,在MSMC中集成了2個(gè)MPAX用于監(jiān)視與該權(quán)限ID 相關(guān)的訪問。其中一個(gè)是SES MPAX 用于保護(hù)對(duì)DDR3的訪問,另一個(gè)是SMS MPAX 用于保護(hù)對(duì)SL2的訪問。關(guān)于每個(gè)master對(duì)應(yīng)的權(quán)限ID,參考相應(yīng)的器件手冊(cè)。
某些外設(shè)的配置端口上添加了MPU,用于保護(hù)對(duì)該外設(shè)配置區(qū)域的非法訪問。但是并非所有的外設(shè)都受MPU的保護(hù),具體參考相應(yīng)器件手冊(cè)中受MPU保護(hù)的外設(shè)列表。每個(gè)CorePac有一個(gè)看門狗定時(shí)器用于監(jiān)視其活動(dòng),如果該核死機(jī),看門狗可以觸發(fā)不可屏蔽中斷或者復(fù)位信號(hào)。
EMC可以避免DSP core訪問沒有映射的的配置空間,XMC則可以避免DSP core訪問沒有映射的數(shù)據(jù)空間。所有這些功能都由硬件模塊實(shí)現(xiàn),使用這些功能對(duì)系統(tǒng)性能基本上沒有影響。使用EDC會(huì)對(duì)存儲(chǔ)器的訪問性能稍有影響,但從整個(gè)系統(tǒng)層面上看,它幾乎是微不足道的。
在出現(xiàn)問題時(shí),所有這些模塊可以向DSP core觸發(fā)異常,DSP core的異常監(jiān)控模塊可以記錄這些狀態(tài)并觸發(fā)異常服務(wù)程序執(zhí)行相應(yīng)的操作。本文討論這些特性的應(yīng)用,并給出相關(guān)基于寄存器層CSL 實(shí)現(xiàn)的例程。代碼使用如下方式定義寄存器指針。
上述各種特性具體描述分布于各自子系統(tǒng)的文檔中,本文最后的參考章節(jié)中列出了所有相關(guān)的文檔。在看本文之前,假設(shè)客戶已經(jīng)閱讀了相關(guān)屬性對(duì)應(yīng)的文檔,所以本文旨在提供相關(guān)的補(bǔ)充信息。
本文適用于KeyStone 1系列DSP,例程在TCI6614 EVM,C6670 EVM,C6678 EVM上進(jìn)行了驗(yàn)證。對(duì)于其他的KeyStone器件包擴(kuò)KeyStone 2系列,基本功能都是一樣的,一些細(xì)節(jié)上的些許差異請(qǐng)參閱相應(yīng)器件手冊(cè)。
2 內(nèi)存保護(hù)
文檔“Memory Protection On KeyStone Devices(SPRWIKI9012)”中討論了KeyStone器件上的內(nèi)存保護(hù)屬性,其中包括其它文檔中沒有的很多有用信息,本節(jié)在其基礎(chǔ)上做一些總結(jié)和補(bǔ)充。
表1 總結(jié)列出不同內(nèi)存保護(hù)模塊的差異。
系統(tǒng)中有多個(gè)master和slave,位于slave輸入端口的保護(hù)模塊用于阻止來自其他master對(duì)該slave的非法訪問;位于master輸出端口的保護(hù)模塊用于阻止該master對(duì)所有其他slave的非法訪問。每個(gè)內(nèi)存頁、分片或范圍的保護(hù)屬性都是可編程的。
2.1 L1及LL2內(nèi)存保護(hù)
關(guān)于L1及LL2內(nèi)存保護(hù)的基本信息參考“TMS320C66x CorePac User Guide(SPUGW0)”中內(nèi)存保護(hù)章節(jié)。
L1及LL2內(nèi)存保護(hù)只區(qū)分7個(gè)外部請(qǐng)求ID,但是系統(tǒng)可能有16個(gè)權(quán)限ID。默認(rèn)情況下,系統(tǒng)權(quán)限ID 0~5映射到CorePac AID 0~5,所有其他的權(quán)限ID均映射到AIDx。
CorePac AID與系統(tǒng)權(quán)限ID之間的映射關(guān)系可由EMC編程配置,具體參考“TMS320C66x CorePac User Guide(SPUGW0)”中“外部存儲(chǔ)控制器(EMC)”章節(jié)。注意,IDMA的AID與其所屬CorePac的數(shù)值一致,EDMA傳輸?shù)臋?quán)限ID與配置并發(fā)起這個(gè)傳輸?shù)暮说木幪?hào)一致。
通常L1被配置為cache,此時(shí)所有L1相關(guān)的內(nèi)存保護(hù)屬性寄存器應(yīng)該清零從而阻止其他master的對(duì)L1的訪問。
CorePac內(nèi)部?jī)?nèi)存保護(hù)模塊(保護(hù)L1,LL2及XMC/MPAX)的寄存器被一個(gè)鎖保護(hù)起來。默認(rèn)情況下,這些寄存器沒有被鎖住,用戶軟件可以使用自定義的密鑰鎖住這些寄存器,然后,只有用該密鑰進(jìn)行解鎖后才可以訪問這些寄存器。
2.2 共享內(nèi)存保護(hù)–MPAX
關(guān)于CorePac共享內(nèi)存保護(hù)的基本信息參考“TMS320C66x CorePac User Guide(SPRUGW0)”中“擴(kuò)展存儲(chǔ)控制器(XMC)”章節(jié);關(guān)于系統(tǒng)中其他master的共享內(nèi)存保護(hù)基本信息參考“KeyStone Architecture Multicore Shared Memory Controller User Guide (SPRUGW7)”中“內(nèi)存保護(hù)及地址擴(kuò)展(MPAX)”章節(jié)。如下是例程中關(guān)于XMC/MPAX的配置樣例,每一行代表MPAX中的一個(gè)分片配置。
邏輯地址低于0x0C00_0000 的地址訪問不會(huì)進(jìn)入XMC。對(duì)地址空間0x0000_0000~0x07FF_FFFF
進(jìn)行訪問時(shí),在C66x CorePac內(nèi)部進(jìn)行地址解析。這塊地址范圍包括內(nèi)部及外部配置總線,及L1D、L1P、L2存儲(chǔ)空間。對(duì)位于0x0C00_0000~0x0FFF_FFFF區(qū)間的邏輯地址訪問時(shí),會(huì)經(jīng)過L1 cache,并且在讀操作時(shí)會(huì)經(jīng)過預(yù)取緩存,與該地址范圍對(duì)應(yīng)的內(nèi)存屬性配置寄存器MAR是硬件拉死的,不可修改。也就是說對(duì)該邏輯地址空間的訪問在進(jìn)入XMC MPAX之前不會(huì)經(jīng)過L2 cache,所以這塊邏輯地址空間稱為“快速SL2 RAM 路徑”。對(duì)大于等于0x1000_0000的邏輯地址訪問會(huì)首先經(jīng)過L2 cache控制器,然后經(jīng)過XMC MPAX,這種常規(guī)路徑會(huì)增加一個(gè)cycle 的時(shí)延。
根據(jù)上述配置例子,在訪問SL2時(shí),采用邏輯地址0x0C00_0000的訪問速率高于使用重映射后的邏輯地址0x1800_0000。但是0x1800_0000對(duì)應(yīng)的內(nèi)存屬性寄存器MAR 是可編程的,因此可以配置通過0x1800_0000訪問的SL2為non-cacheable及non-prefetchable。
注意替換地址RADDR是36-bit物理地址>>4。常見的DDR3錯(cuò)誤配置如下:
或者
注意DDR3起始物理地址為0x8:0000_0000,而0x9:0000_0000相對(duì)起始地址有4GB的偏移,在大多數(shù)系統(tǒng)中這是一個(gè)非法的地址。
在真實(shí)系統(tǒng)中,應(yīng)該充分利用好MPAX的所有片段更好地將存儲(chǔ)空間劃分成盡可能多的小片,并仔細(xì)設(shè)定各個(gè)分片的訪問限定屬性。
不用的地址不應(yīng)該映射,MPAX會(huì)拒絕對(duì)未映射的地址訪問并上報(bào)異常事件,從而有助于捕獲軟件錯(cuò)誤。
SMS/MPAX只允許對(duì)SL2的訪問,如下為其配置例子:
SES/MPAX是用于保護(hù)對(duì)DDR3的訪問,如下為其配置例子:
當(dāng)兩個(gè)master通過共享memory交換數(shù)據(jù)時(shí),應(yīng)該確保兩個(gè)master使用的邏輯地址映射到相同的物理地址。注意EDMA的權(quán)限ID是繼承于對(duì)其配置的CorePac。
警告:
在修改一條MPAX表項(xiàng)時(shí),需要確保此時(shí)沒有對(duì)該表項(xiàng)所覆蓋地址的訪問。在修改之前,需要先將該表項(xiàng)覆蓋地址對(duì)應(yīng)的cache及預(yù)取緩存中的數(shù)據(jù)進(jìn)行回寫及失效操作。
對(duì)于MPAX的配置,推薦在程序開始之初且沒有使用任何共享存儲(chǔ)空間之前完成。用于CorePac MPAX配置的代碼和數(shù)據(jù)應(yīng)該放在LL2。
如果要運(yùn)行時(shí)動(dòng)態(tài)修改一個(gè)MPAX表項(xiàng),安全的方法是先將新的配置寫到一個(gè)未使用的編號(hào)高度表項(xiàng),然后清掉舊的表項(xiàng)。這是由于編號(hào)高度表項(xiàng)的優(yōu)先級(jí)高于編號(hào)低端表項(xiàng)。
在修改MPAX表項(xiàng)之前需要先執(zhí)行如下操作:
1.將MPAX表項(xiàng)對(duì)應(yīng)的存儲(chǔ)空間內(nèi)容從cache中剔除出去。即使對(duì)于屬性為不可寫的存儲(chǔ)空間,應(yīng)該使用CACHE_wbInvL2()而非CACHE_inv L2()。
2.如果對(duì)受影響的存儲(chǔ)器空間使能了預(yù)取功能,則需要對(duì)預(yù)取緩存執(zhí)行失效操作。
3.執(zhí)行“MFENCE”確?;貙懠笆Р僮魍瓿?。
CorePac的MPAX寄存器受CorePac的內(nèi)存保護(hù)寄存器鎖保護(hù)。SES及SMS的MPAX內(nèi)存保護(hù)屬性寄存器被MSMC內(nèi)部分別用于SES及SMS的鎖保護(hù)。MSMC內(nèi)部其他寄存器被MSMC內(nèi)部用于非MPAX 的鎖保護(hù)。
2.3 外設(shè)配置端口保護(hù)–MPU
關(guān)于MPU的基本信息參考“KeyStone Architecture Memory Protection Unit User Guide (SPRUGW5)”。
MPU0、MPU1、MPU2及MPU3對(duì)所有KeyStone 1器件是相同的。但是對(duì)于不同的器件,其附加MPU的個(gè)數(shù),每個(gè)MPU 支持的地址范圍表項(xiàng)數(shù),MPU的默認(rèn)配置均有所差異。具體可參考相關(guān)器件手冊(cè)的“內(nèi)存保護(hù)單元(MPU)”章節(jié)。
MPU與MPAX的區(qū)別在于,如果訪問地址不在MPU任何一個(gè)地址范圍內(nèi),則該地址訪問是允許的;而當(dāng)該地址與MPAX中任意表項(xiàng)地址范圍不匹配時(shí),則該地址訪問被拒絕。
注意,如果沒有被MPPA的設(shè)置所拒絕,MPU單元默認(rèn)所有的訪問都是許可的。對(duì)于一個(gè)地址訪問,MPU首先將訪問的權(quán)限ID與MPPA寄存器的AID bit配置進(jìn)行核對(duì),如果與權(quán)限ID對(duì)應(yīng)的AID bit為0,則不需要核對(duì)地址范圍,該訪問被許可。如MPPA=0則允許所有的對(duì)該空間的訪問,如果要拒絕任意對(duì)該空間的訪問則需要將MPPA配置為0x03FFFC00。L1及LL2內(nèi)存保護(hù)的MPPA設(shè)置則有所不同,當(dāng)MPPA中AID bit為0是拒絕相應(yīng)的訪問。
當(dāng)傳輸與MPU中多個(gè)地址范圍匹配時(shí),所有重疊的范圍必須允許其訪問,否則該訪問會(huì)被拒絕。最終賦予的訪問權(quán)限與所有匹配表項(xiàng)中最低的權(quán)限等級(jí)一致。如某傳輸與2個(gè)表項(xiàng)匹配,其中一個(gè)是RW,另一個(gè)是RX,則最終的權(quán)限是R。這與MPAX也是不一樣的。如果一個(gè)地址落入多個(gè)MPAX表項(xiàng),編號(hào)高的表項(xiàng)優(yōu)先于編號(hào)低的表項(xiàng)。MPAX 只會(huì)用編號(hào)最高的表項(xiàng)決定權(quán)限,并忽略其他匹配的表項(xiàng)。
如下與本文對(duì)應(yīng)例程中一個(gè)對(duì)MPU1的配置例子。每行代表MPU中一個(gè)配置范圍。
如上配置知,隊(duì)列保護(hù)如下:
隊(duì)列0~2047只可由AID0~7進(jìn)行寫(PUSH)操作;
隊(duì)列2048~6143可由AID11以外所有的AID進(jìn)行寫(PUSH)操作;
隊(duì)列6144~8191只可由AID8~15(AID11除外)進(jìn)行寫(PUSH)操作。
TCI6614上的MPU6用于避免ARM對(duì)DDR3的非法操作。注意,MPU6是用于低32-bit DDR物理地址范圍的保護(hù)。注意,為了清除MPU異常/中斷事件,必須在服務(wù)程序的最后向EOI寄存器寫0。
TCI6614的MPU事件與其他KeyStone器件有所不同。TCI6614中所有的MPU0~7事件被合并為一個(gè)事件并作為一個(gè)系統(tǒng)事件連接到CIC0。由于TCI6614 MPU事件是電平中斷而非脈沖中斷事件,所有必須首先清除MPU事件標(biāo)志,然后才可以清CIC標(biāo)志。對(duì)于脈沖中斷事件,必須首選清CIC標(biāo)志,然后清源標(biāo)志。
另外,只有在通過PSC使能BCP后,才可以訪問TCI6614中用于BCP的MPU5。即在訪問TCI6614中MPU5寄存器時(shí),如果此時(shí)BCP沒有被使能,則該訪問將觸發(fā)訪問錯(cuò)誤。
2.4 預(yù)留區(qū)域保護(hù)
預(yù)留區(qū)域(非法地址)被自動(dòng)保護(hù)。對(duì)非法地址進(jìn)行讀操作時(shí)將返回垃圾數(shù)據(jù),寫操作則會(huì)被阻止。對(duì)預(yù)留區(qū)域的訪問可以產(chǎn)生異常,這有益于捕獲軟件bug。
由于DSP core的訪問會(huì)經(jīng)過L1D控制器,所以DSP core對(duì)非法地址的訪問會(huì)觸發(fā)L1D內(nèi)存保護(hù)異常。DSP core從非法地址執(zhí)行時(shí)將觸發(fā)指令獲取異常。對(duì)于非法寫操作,觸發(fā)的異常取決于相應(yīng)的目的地址。DMA對(duì)非法地址訪問時(shí),DMA模塊會(huì)上報(bào)總線錯(cuò)誤。DMA錯(cuò)誤事件可以作為異常路由到DSP core。
3 EDC
EDC(Error Detection and Correction)用于存儲(chǔ)器軟錯(cuò)誤(Soft Error)。軟錯(cuò)誤是一個(gè)錯(cuò)誤的信號(hào)或數(shù)據(jù),但是并不意味著硬件被破壞。在觀測(cè)到一個(gè)軟錯(cuò)誤后,并不意味著系統(tǒng)可靠性會(huì)下降。在宇宙飛船中這種類型的錯(cuò)誤稱為單一事件擾亂。在內(nèi)存系統(tǒng)中,一個(gè)軟錯(cuò)誤會(huì)改變程序中的一條指令或者一個(gè)數(shù)據(jù)值。軟錯(cuò)誤通??梢酝ㄟ^器件的重啟進(jìn)行糾正,而硬件錯(cuò)誤通常不能通過重啟來恢復(fù)。軟錯(cuò)誤不會(huì)對(duì)系統(tǒng)硬件造成破壞;僅僅會(huì)對(duì)處理的代碼或數(shù)據(jù)造成錯(cuò)誤。產(chǎn)生軟錯(cuò)誤的原因有:
1.阿爾法粒子輻射及宇宙射線產(chǎn)生能量中子及質(zhì)子。發(fā)生的概率取決于器件的地理位置及周圍環(huán)境。通常,一個(gè)器件在幾年中才會(huì)出現(xiàn)幾次。
2.軟錯(cuò)誤也可由隨機(jī)噪聲、干擾或信號(hào)完整性錯(cuò)誤引發(fā),如板載電感應(yīng)或電容串?dāng)_。如果軟錯(cuò)誤發(fā)送概率高于上述條目1 中的理論值,則應(yīng)該檢查硬件設(shè)計(jì)找出其他原因。一個(gè)常見的原因是供電電源電壓低于預(yù)期,導(dǎo)致器件對(duì)噪聲或干擾的影響更敏感。
KeyStone器件各級(jí)memory中都實(shí)現(xiàn)了EDC機(jī)制,下表對(duì)不同memory模塊的實(shí)現(xiàn)機(jī)制進(jìn)行了比較。
3.1 L1P錯(cuò)誤檢測(cè)
關(guān)于L1P及LL2 EDC基本信息參考“TMS320C66x DSP CorePac User Guide(SPRUGW0)”。校驗(yàn)比特生成與核對(duì):校驗(yàn)比特在進(jìn)行64-bit對(duì)齊的DMA寫或L1P cache緩存時(shí)生成。非64-bit對(duì)齊的DMA 訪問將使校驗(yàn)信息失效。在256-bit對(duì)齊的程序讀取或64-bit對(duì)齊的DMA讀操作時(shí),L1P EDC邏輯會(huì)核對(duì)校驗(yàn)信息。
錯(cuò)誤檢查設(shè)置:器件復(fù)位后默認(rèn)情況下L1P錯(cuò)誤檢查特性是關(guān)閉的。一旦L1PEDCMD寄存器中的“EN”bit被置位,所有L1P memory中的ED邏輯被使能。下面是從應(yīng)用代碼中摘錄的L1P ED功能使能例子。
注意:要使L1P ED功能工作正常,必須同時(shí)使能L2 EDC。
對(duì)L1P cache訪問時(shí)的錯(cuò)誤處理: 對(duì)從L1P cache中獲取程序產(chǎn)生的校驗(yàn)錯(cuò)誤,沒有專用的系統(tǒng)事件,然而,錯(cuò)誤檢測(cè)邏輯會(huì)發(fā)送一個(gè)直接的異常事件給DSP(IERR.IFX事件),然后用戶可以使用內(nèi)部異常事件獲取這個(gè)錯(cuò)誤。L1PEDSTAT寄存器的PERR bit會(huì)被置位。L1PEDARRD寄存器會(huì)記錄包含錯(cuò)誤bit的的地址信息。在L1P錯(cuò)誤對(duì)應(yīng)的異常處理服務(wù)函數(shù)中,需要對(duì)包含錯(cuò)誤地址的cache line進(jìn)行失效操作。
對(duì)DMA訪問的錯(cuò)誤處理:對(duì)DMA/IDMA訪問產(chǎn)生的校驗(yàn)錯(cuò)誤,對(duì)應(yīng)#113號(hào)系統(tǒng)事件。用戶可以使用這個(gè)事件獲取錯(cuò)誤。L1PEDSTAT寄存器的DERR比特位會(huì)被置位,并且L1PEDARRD寄存器會(huì)記錄包含錯(cuò)誤bit的地址信息。
L1P EDC功能驗(yàn)證:通過置位LPEDCMD寄存器中的SUSP比特可以暫停L1P EDC邏輯。使用該特性,可以軟件模仿EDC錯(cuò)誤并驗(yàn)證EDC功能。與本文對(duì)應(yīng)的例程中提供了驗(yàn)證L1P EDC功能的代碼,對(duì)應(yīng)函數(shù)L1P_ED_test()。
3.2 LL2錯(cuò)誤檢查與糾正
校驗(yàn)比特生成與核對(duì):在對(duì)L2以128 bits為單元進(jìn)行內(nèi)存寫操作時(shí)會(huì)產(chǎn)生相應(yīng)的校驗(yàn)信息。非128-bit對(duì)齊或者小于128 bits的寫操作會(huì)使校驗(yàn)信息失效。對(duì)128-bit對(duì)齊的memory讀操作時(shí),LL2 EDC邏輯會(huì)核對(duì)校驗(yàn)信息。更多信息參考“TMS320C66x DSP CorePac User Guide(SPRUGW0)”。
錯(cuò)誤檢查及糾正配置:器件復(fù)位后默認(rèn)情況下LL2 EDC特性是被關(guān)閉的。與某些C64+DSP不同的是,KeyStone DSP不能對(duì)內(nèi)存分塊使能EDC。一旦EDC使能,EDC邏輯對(duì)整個(gè)CorePac L2內(nèi)存生效。然而,可以對(duì)不同的內(nèi)存訪問請(qǐng)求者分別使能,如L1D控制器、L1P控制器或DMA控制器。例如,如果用戶只需要對(duì)代碼段使用EDC,需要使能下面三個(gè)域:
1.設(shè)置L2EDCMD寄存器中的EN bit以使能LL2 EDC邏輯;
2.設(shè)置L2EDCEN寄存器中的PL2SEN比特以使能L1 SRAM的EDC邏輯對(duì)L1P訪問的檢查;
3.設(shè)置L2EDCEN寄存器中的PL2CEN比特以使能L2 cache的EDC邏輯對(duì)L1P訪問的檢查。
從關(guān)閉到使能狀態(tài)轉(zhuǎn)變時(shí),LL2 EDC邏輯不會(huì)初始化校驗(yàn)RAM。因此,在進(jìn)入使能狀態(tài)后,校驗(yàn)RAM中的值是隨機(jī)值,需要用戶軟件對(duì)其進(jìn)行初始化。對(duì)L2 EDC的配置必須遵循“TMS320C66x DSP CorePac User Guide(SPRUGW0)”中闡述的EDC配置順序。下面是從例程中摘錄的L2 EDC使能函數(shù)參考代碼:
對(duì)來自L1D控制器的訪問錯(cuò)誤處理:在經(jīng)過L1D cache從LL2中獲取數(shù)據(jù)時(shí),對(duì)所有這些數(shù)據(jù)會(huì)進(jìn)行錯(cuò)誤檢查,但是不會(huì)有任何的糾正。不管是1-bit或者是多bit錯(cuò)誤,將會(huì)通過#117號(hào)系統(tǒng)事件(L2_ED2:不可糾正比特錯(cuò)誤檢測(cè))上報(bào)給DSP core。
對(duì)來自L1P及DMA控制器的訪問錯(cuò)誤處理:1-bit錯(cuò)誤可以被糾正并通過#116號(hào)系統(tǒng)事件(L2_ED1:可被糾正的比特錯(cuò)誤)上報(bào) 。2-bit錯(cuò)誤可以被檢測(cè),并通過#117號(hào)系統(tǒng)事件上報(bào)該錯(cuò)誤。下表列出對(duì)于不同存儲(chǔ)器訪問請(qǐng)求者,相應(yīng)的1-bit錯(cuò)誤處理細(xì)節(jié)。
錯(cuò)誤計(jì)數(shù)器(L2EDCPEC, L2EDNPEC)非常有用,可用于在長時(shí)間運(yùn)行的系統(tǒng)中評(píng)估校驗(yàn)比特錯(cuò)誤發(fā)生的種類與概率。下表列出對(duì)不同存儲(chǔ)器訪問請(qǐng)求者,相應(yīng)的2-bit錯(cuò)誤處理細(xì)節(jié)。
對(duì)于大于2bits的錯(cuò)誤,EDC邏輯可能會(huì)檢測(cè)并報(bào)告為1-bit或2-bit錯(cuò)誤,或者EDC根本檢測(cè)不到該錯(cuò)誤。所以說,KeyStone系列EDC硬件邏輯只能保證檢測(cè)2-bit錯(cuò)誤或糾正1-bit錯(cuò)誤。
通常軟錯(cuò)誤出現(xiàn)的概率很低,首先出現(xiàn)1-bit錯(cuò)誤,在相對(duì)長時(shí)間后,第二個(gè)錯(cuò)誤bit也許會(huì)產(chǎn)生。由于1-bit 錯(cuò)誤可以被糾正,而2-bit錯(cuò)誤不能被糾正,所以我們應(yīng)該盡可能在第二個(gè)比特錯(cuò)誤出現(xiàn)前糾正好第一個(gè)比特錯(cuò)誤。
糾正1-bit錯(cuò)誤的操作通常稱為“刷新”。為了刷新一塊存儲(chǔ)器,可以使用IDMA,把IDMA的源地址與目的地址設(shè)為相同的地址;字節(jié)長度設(shè)置為期望覆蓋的內(nèi)存塊。地址訪問必須是128-bit對(duì)齊,并且整塊的內(nèi)存范圍長度必須是128bits的整數(shù)倍。在IDMA從LL2讀取數(shù)據(jù)時(shí),對(duì)于存在有效校驗(yàn)信息的128-bit字,EDC硬件會(huì)糾正可能存在于其中的1-bit錯(cuò)誤。當(dāng)IDMA把數(shù)據(jù)回寫到相同的地址時(shí),EDC會(huì)對(duì)數(shù)據(jù)產(chǎn)生校驗(yàn)信息并標(biāo)識(shí)其為有效。
刷新操作通常是在1-bit錯(cuò)誤中斷服務(wù)函數(shù)中進(jìn)行。但是在1-bit錯(cuò)誤發(fā)生之后2-bit錯(cuò)誤發(fā)生之前,某些數(shù)據(jù)也許不會(huì)被訪問,在沒有訪問時(shí)1-bit錯(cuò)誤是不會(huì)被自動(dòng)上報(bào)的。為了避免這種情況,應(yīng)該周期性地刷新整塊存儲(chǔ)器區(qū)間來糾正潛在的1-bit錯(cuò)誤。下面是一段LL2 EDC刷新的代碼例子。
通常,這個(gè)函數(shù)可以在一個(gè)定時(shí)中斷中調(diào)用。如在一個(gè)600秒周期的定時(shí)中斷中調(diào)用該函數(shù)。
這樣, 1MB的存儲(chǔ)區(qū)間會(huì)每7天被刷新一遍。由于刷新操作會(huì)與正常的內(nèi)存操作相競(jìng)爭(zhēng),因此會(huì)影響正常內(nèi)存操作的性能。所以刷新操作不能太頻繁,但是必須在2-bit錯(cuò)誤產(chǎn)生前完成。在設(shè)計(jì)時(shí)必須權(quán)衡考慮。LL2 EDC功能驗(yàn)證:通過設(shè)置L2EDCMD寄存器中的SUSP比特可以暫停LL2 EDC邏輯。使用該特性,可以軟件模仿EDC錯(cuò)誤并驗(yàn)證EDC功能。與本文對(duì)應(yīng)的例程中提供了驗(yàn)證LL2 EDC功能的代碼,對(duì)應(yīng)函數(shù)LL2_ED_test()。
3.3 SL2錯(cuò)誤檢測(cè)與糾正
對(duì)共享存儲(chǔ)器SL2的基本信息,參考“KeyStone Architecture Multicore Shared Memory Controller User Guide(SPRUGW7)”。校驗(yàn)比特產(chǎn)生與核對(duì):有兩種機(jī)制用于MSMC校驗(yàn)信息的產(chǎn)生與檢測(cè):
1.對(duì)任意master發(fā)起的256-bit內(nèi)存段的寫操作時(shí),校驗(yàn)信息會(huì)被更新并設(shè)置為有效。小于256bits的寫操作會(huì)使校驗(yàn)信息失效。當(dāng)DSP master發(fā)起256-bit內(nèi)存段的的讀操作時(shí),校驗(yàn)信息會(huì)被檢查。
2.MSMC包含一個(gè)后臺(tái)錯(cuò)誤糾正硬件稱作刷新引擎,用于周期刷新存儲(chǔ)器的內(nèi)容。刷新的周期數(shù)可以通過SMEDCC 寄存器中的REFDEL比特域來配置,每次刷新會(huì)讀取并回寫大小是4個(gè)32字節(jié)的塊。在檢測(cè)并糾正1-bit或者檢查到2-bit錯(cuò)誤時(shí),刷新引擎還會(huì)上報(bào)EDC錯(cuò)誤。在MSMC用戶手冊(cè)中有具體的機(jī)制細(xì)節(jié)描述。
DSP復(fù)位后,MSMC硬件會(huì)使校驗(yàn)信息失效,并重新初始化校驗(yàn)信息。在第一次讀MSMC存儲(chǔ)器時(shí),軟件必須先檢查SMEDCC中的PRR比特(校驗(yàn)RAM是否準(zhǔn)備好的狀態(tài)信息)。
錯(cuò)誤檢測(cè)與糾正配置:DSP復(fù)位后SL2 EDC邏輯的刷新引擎被使能,并且會(huì)在后臺(tái)產(chǎn)生校驗(yàn)信息。軟件不需要像LL2 EDC一樣使用DMA進(jìn)行存儲(chǔ)器刷新,只需要查詢SMEDCC寄存器中的PRR(校驗(yàn)RAM準(zhǔn)備)比特位來確認(rèn)校驗(yàn)比特已經(jīng)產(chǎn)生。為了使能錯(cuò)誤糾正,SMEDCC中的ECM比特同樣應(yīng)該使能。請(qǐng)注意,錯(cuò)誤糾正邏輯會(huì)對(duì)從SL2的讀操作增加1cycle的時(shí)延(訪問流水線增加了一級(jí)),不過訪問吞吐量并不會(huì)降低。
下面是使能MSMC EDC功能的例程:
錯(cuò)誤上報(bào)機(jī)制:MSMC用戶手冊(cè)中有詳細(xì)的錯(cuò)誤上報(bào)機(jī)制信息,這里總結(jié)如下表。
請(qǐng)注意,由刷新引擎上報(bào)的錯(cuò)誤地址是從0開始的地址偏移,而為非刷新訪問記錄的錯(cuò)誤地址是器件中從0x0C000000開始的SL2地址。
MSMC EDC功能驗(yàn)證:可以通過設(shè)置SMEDCTST寄存器中的PFn比特位(bit0~3)來暫停MSMC EDC邏輯。SMEDCTST 的地址偏移是0x58。每個(gè)SL2 RAM bank對(duì)應(yīng)PFn中一個(gè)比特(PF0~3與bank0~3依次對(duì)應(yīng)),每個(gè)比特可以用于禁止對(duì)校驗(yàn)RAM的寫操作。這樣可以凍結(jié)bank對(duì)應(yīng)的校驗(yàn)RAM,因此可以通過故意注入錯(cuò)誤來破壞SL2存儲(chǔ)內(nèi)容與校驗(yàn)信息的一致性,從而測(cè)試檢測(cè)糾正邏輯。具體的順序如下:
1.向測(cè)試bank中的某一個(gè)位置寫一個(gè)已知值,這樣可以正確地為這個(gè)位置初始化一個(gè)校驗(yàn)值。
2.向SMEDCSTST對(duì)應(yīng)的PF比特寫1以凍結(jié)該校驗(yàn)值。
3.向上述被寫的位置寫任意字節(jié)來改變?cè)撐恢玫臄?shù)值,如果檢驗(yàn)糾正功能則寫一個(gè)1-bit差異的值,如果檢驗(yàn)檢測(cè)功能則寫一個(gè)存在2-bit差異的值。此時(shí)該位置的校驗(yàn)值與其存儲(chǔ)的數(shù)值沒有同步。
4.讀回該位置的值,將會(huì)產(chǎn)生所選類型的校驗(yàn)錯(cuò)誤。
與本文對(duì)應(yīng)的例程中提供了相應(yīng)的代碼用于驗(yàn)證SL2 EDC功能,對(duì)應(yīng)的函數(shù)為SL2_EDC_test()。
4 其它魯棒性特性
4.1看門狗定時(shí)器
對(duì)應(yīng)看門狗定時(shí)器的基本知識(shí),請(qǐng)參考“KeyStone Architecture Timer64 User Guide(SPRUGV5)”中“看門狗定時(shí)器模式”章節(jié)。
定時(shí)器0~(N-1)可用于N個(gè)core的看門狗。在TCI6614中定時(shí)器8是ARM的看門狗定時(shí)器。在看門狗模式下,定時(shí)器倒計(jì)時(shí)到0時(shí)產(chǎn)生一個(gè)事件。需要由軟件在倒計(jì)時(shí)終止前向定時(shí)器寫數(shù),然后計(jì)數(shù)重新開始。如果計(jì)數(shù)到0,會(huì)產(chǎn)生一個(gè)定時(shí)器事件??撮T狗定時(shí)器事件可以觸發(fā)本核復(fù)位、器件復(fù)位或者NMI異常,這可以通過配置相應(yīng)器件手冊(cè)中描述的“復(fù)位復(fù)用寄存器(RSTMUXx)”來選擇。
使看門狗事件觸發(fā)NMI異常具有更高的靈活性,在NMI異常服務(wù)函數(shù)中,錯(cuò)誤的原因及某些關(guān)鍵的狀態(tài)信息可以被記錄下來,或者上報(bào)給上位機(jī)來進(jìn)行故障分析,然后如果它不能自恢復(fù)則可以再由軟件來復(fù)位器件。
4.2 EDMA錯(cuò)誤檢測(cè)
關(guān)于基本的EDMA CC錯(cuò)誤信息可以參考“KeyStone Architecture Enhanced Direct Memory Access(EDMA3)Controller User Guide(SPRUGS5)”中的“錯(cuò)誤中斷”章節(jié)。
關(guān)于基本的EDMA TC錯(cuò)誤信息可以參考“KeyStone Architecture Enhanced Direct Memory Access(EDMA3) Controller User Guide(SPRUGS5)”中的“錯(cuò)誤產(chǎn)生”章節(jié)。
所有的EDMA錯(cuò)誤事件可作為異常被路由到CorePac。事件丟失錯(cuò)誤是一種最常見的EDMA CC錯(cuò)誤,意味著EDMA不能按要求及時(shí)完成數(shù)據(jù)的傳輸,或者錯(cuò)誤的事件觸發(fā)了不應(yīng)該的EDMA傳輸??偩€錯(cuò)誤是一種最常見的EDMA TC 錯(cuò)誤,通常意味著EDMA訪問了錯(cuò)誤的地址(如預(yù)留地址或受保護(hù)的地址)。
4.3 中斷丟失檢測(cè)
中斷丟失或遺漏是實(shí)時(shí)系統(tǒng)中常見也是常被忽略的問題。中斷丟失檢測(cè)是一種用于捕捉這種異常的有效方法。對(duì)基本的中斷丟失檢測(cè)信息參考“TMS320C66x DSP CorePac User Guide(SPRUGW0)”中“中斷錯(cuò)誤事件”章節(jié)。
軟件系統(tǒng)應(yīng)該對(duì)路由到DSP core且有對(duì)應(yīng)軟件服務(wù)的中斷使能中斷丟失檢測(cè)。在所有中斷配置完畢后可以添加如下代碼使能中斷丟失檢測(cè):
注意,當(dāng)使能中斷丟失檢測(cè)并在CCS/Emulator下使用斷點(diǎn)或單步進(jìn)行調(diào)測(cè)時(shí),由于在仿真停止時(shí)中斷沒有被響應(yīng),所有此時(shí)中斷丟失錯(cuò)誤上報(bào)的概率很高。如果想忽略它,可以在調(diào)測(cè)時(shí)暫時(shí)對(duì)某些或全部中斷關(guān)閉中斷丟失檢測(cè),但是注意不要忘記在正式發(fā)布的程序中重新使能該功能。
5 異常處理
關(guān)于異常處理的基本信息參考“TMS320C66x DSP CPU and Instruction Set Reference Guide(SPRUGH7)”中“CPU 異?!币还?jié)。
關(guān)于中斷或異常事件路由的基本信息參考“TMS320C66x DSP CorePac User Guide(SPRUGW0)”中“中斷控制器”章節(jié)。
5.1 異常事件路由
所有源自或由CorePac觸發(fā)的錯(cuò)誤事件均直接路由到CorePac的中斷控制器。常被當(dāng)作異常處理的錯(cuò)誤如下表所示。
一些其他非致命的錯(cuò)誤事件,如可糾正的LL2 EDC錯(cuò)誤,應(yīng)該被路由到中斷而非異常。源自或者由器件中共享模塊觸發(fā)的錯(cuò)誤事件被路由到CIC。CIC基本信息參考“KeyStone Architecture Chip Interrupt Controller(CIC) User Guide(SPRUGW4)”。
CIC事件中常被當(dāng)作異常處理的事件如下表所示。
每種這樣的異常事件只能路由到一個(gè)CorePac。通常所有的這些事件被路由到一個(gè)CorePac。下圖描述DSP core 內(nèi)部控制異常處理的開關(guān)。
圖2 DSP核異常控制開關(guān)
一旦軟件置位TSR.GEE 及IER.NMIE,不能再由軟件清除,只能在復(fù)位后被清除。TSR.XEN可以由軟件置位并清除。XEN可以在進(jìn)入異常服務(wù)函數(shù)中由硬件自動(dòng)清除,并在退出異常服務(wù)函數(shù)時(shí)自動(dòng)恢復(fù)原來的狀態(tài)。因此,默認(rèn)情況下,在中斷服務(wù)函數(shù)中,TSR.GEE=1,IER.NMIE=1及TSR.XEN=0.
5.2 異常服務(wù)函數(shù)
異常函數(shù)中應(yīng)該記錄或上報(bào)異常原因及相關(guān)信息,用于故障分析。關(guān)鍵的記錄信息是NRP。NRP是異常返回指針,通常用于確定異常觸發(fā)的位置。實(shí)際上,非法操作與NRP捕獲之間的時(shí)延大概在10~100個(gè)DSP Core cycles 之間,具體的時(shí)延取決于很多因素,如操作類型,產(chǎn)生異常事件的模塊等等。例如對(duì)于向一個(gè)被MPU保護(hù)的寄存器執(zhí)行寫操作,其時(shí)延包括:從DSP core到寄存器的寫指令時(shí)延;錯(cuò)誤事件從MPU到CIC然后到CorePac異常模塊的路由時(shí)延。因此,當(dāng)我們獲得NRP后,應(yīng)從NRP指向的位置向后搜索大概10~100cycles來找有問題的操作。
不過,某些異常NRP是沒有意義的,例如,對(duì)于指令獲取異常及非法操作碼異常。這通常發(fā)生在當(dāng)程序跳轉(zhuǎn)到一個(gè)非法的地址時(shí),這時(shí)NRP也指向一個(gè)非法的地址。我們真正想知道的是在程序跳轉(zhuǎn)到非法地址前到底發(fā)生了什么,但是這并不能從NRP推導(dǎo)出來。在這種情況下,寄存器B3,A4,B4,B14及B15也許會(huì)有所幫助。B3可能還保存著上次函數(shù)調(diào)用的返回指針;A4及B4也許保存著上次函數(shù)調(diào)用的參數(shù);B15是棧指針;B14是指向某些全局變量的數(shù)據(jù)指針。更多的細(xì)節(jié)可以參考“TMS320C6000 Optimizing Compiler User Guide(SPRUG187)” 中“7.4 函數(shù)結(jié)構(gòu)及調(diào)用約定”章節(jié)。根據(jù)這些信息,我們也許可以推導(dǎo)出在程序跳轉(zhuǎn)到非法地址前發(fā)生了什么。注意,B3,A4,B4可能在異常發(fā)生前已經(jīng)被修改用于保存其它信息,所以它們也許不是有用的。實(shí)際上,B3,A4,B4包含有價(jià)值信息的概率還是很高的,所以這些寄存器是值得記錄并分析的。
通用寄存器的值不能用C 代碼記錄,而必須用匯編代碼來記錄。下面的例子是將B3,A4,B4,B14,B15 寄存器記錄在“exception_record”中,然后調(diào)用 “Exception_service_routine”。
其它需要記錄的基本信息有:EFR,IERR,NTSR,TSCL/TSCH.EFR用于判決異常類型:內(nèi)部、外部或是NMI。對(duì)于內(nèi)部異常,內(nèi)部異常的原因記錄在IERR。NTSR記錄異常發(fā)生時(shí)的DSP core狀態(tài)。記錄的TSCL/TSCH用于確定異常發(fā)生前器件運(yùn)行的時(shí)長。
對(duì)于外部異常,通過檢查INTC及CIC標(biāo)志寄存器來決定異常原因。對(duì)應(yīng)一個(gè)特定的異常,往往有特定的狀態(tài)寄存器可以檢查、記錄或上報(bào)。例如對(duì)應(yīng)內(nèi)存保護(hù)異常,需要記錄的關(guān)鍵信息是故障地址。參考各模塊的用戶指南了解相關(guān)狀態(tài)或標(biāo)志的更多細(xì)節(jié)。
通常,異常服務(wù)函數(shù)將這些異常信息保存在一個(gè)類似如下的數(shù)據(jù)結(jié)構(gòu)中。
可以在異常服務(wù)函數(shù)中將這些數(shù)據(jù)結(jié)構(gòu)中的信息傳遞給主機(jī),或者將其導(dǎo)出來進(jìn)行錯(cuò)誤分析。
通常異常服務(wù)函數(shù)處理的錯(cuò)誤是致命的,用戶不應(yīng)該期望從異常服務(wù)函數(shù)中返回。另外,軟件也不總是能從異常服務(wù)函數(shù)中安全返回,阻止從異常中安全返回的條件有:
1.被異常終止的SPLOOPs不能正確地重新開始。在返回前應(yīng)該核實(shí)NTSR中的SPLX比特?cái)?shù)值為0.
2.中斷被堵塞時(shí)發(fā)生的異常不能正確地重新開始。在返回前應(yīng)該核實(shí)NTSR中的IB比特?cái)?shù)值為0.
3.在不能被安全中斷的代碼處(如一個(gè)保護(hù)多個(gè)賦值的緊湊循環(huán))發(fā)生的異常不能正確地返回。編譯器通常會(huì)在代碼中的這些地方關(guān)閉中斷;查看NTSR中的GIE比特值為1來驗(yàn)證滿足這個(gè)條件。
4.NRP不是一個(gè)合法的地址。
所以通常異常服務(wù)函數(shù)以一個(gè)while(1)循環(huán)作為結(jié)束。默認(rèn)情況下在異常服務(wù)程序中,TSR.GEE=1,IER.NMIE=1 及TSR.XEN=0.即在異常服務(wù)程序中NMI及內(nèi)部異常是使能的。
當(dāng)一個(gè)使能的異常發(fā)生在第一個(gè)異常服務(wù)程序中時(shí),復(fù)位向量指向的程序會(huì)被執(zhí)行。這時(shí)NTSR和NRP不會(huì)發(fā)生改變。TSR復(fù)制到ITSR,此時(shí)的PC復(fù)制到IRP。此時(shí)為了避免其他外部異常,硬件將TSR設(shè)置為默認(rèn)的異常處理值,NMIE中的IER比特被清零。
通常中斷服務(wù)表中的復(fù)位向量是跳轉(zhuǎn)到程序起始位置如_c_int00,這樣,嵌套異常會(huì)重啟程序。然而這并非大部分用戶所期望的,我們通常期望的是異常發(fā)生時(shí)在異常服務(wù)程序執(zhí)行完后結(jié)束程序。為了避免嵌套異常導(dǎo)致程序重啟,可以給嵌套異常添加一個(gè)額外的異常服務(wù)程序,用戶可以修改復(fù)位向量跳轉(zhuǎn)到嵌套異常服務(wù)程序。在KeyStone器件中,加載程序不依賴于復(fù)位向量啟動(dòng)程序,所以修改復(fù)位向量不會(huì)影響程序的加載。
6 例程
本文相關(guān)的例程可以在TCI6614 EVM, C6670 EVM及C6678 EVM上跑通。如下為工程目錄結(jié)構(gòu):
圖3 例程目錄結(jié)果
“common“文件夾中包含通用代碼如DDR 初始化及DMA、定時(shí)器、多核導(dǎo)航器、SRIO驅(qū)動(dòng)等。內(nèi)存保護(hù)初始化代碼、EDC及異常處理的代碼包含在KeyStone_common.c。
“src”文件夾中的每個(gè)c文件包含一個(gè)測(cè)試用例代碼。主函數(shù)在 “Robust_System.c”。在 “Robust_System.c“的開頭有一些宏開關(guān),每個(gè)開關(guān)用于使能或關(guān)閉一個(gè)測(cè)試用例。
如果使能多個(gè)測(cè)試用例,每個(gè)用例會(huì)依次執(zhí)行。由于程序并不能總是安全地從異常服務(wù)程序中返回,因此有可能在一個(gè)測(cè)試用例后輸出如下信息,然后測(cè)試流程被終止。
如果出現(xiàn)這種情況,可以關(guān)閉這個(gè)測(cè)試用例然后重新測(cè)試其他的用例。在EVM上運(yùn)行例程的步驟如下:
1.解壓例程,將CCS workspace切換到解壓后的文件夾;
2.在workspace中導(dǎo)入工程;
3.如果發(fā)生代碼修改對(duì)工程重新編譯,也許需要在編譯選項(xiàng)中修改CSL保護(hù)路徑;
4.設(shè)置EVM板上的器件加載模式為No boot模式;
5.將代碼加載到DSP core0,運(yùn)行;
6.查看CCS stdout窗口瀏覽測(cè)試結(jié)果。
如下為TCI6614上的測(cè)試結(jié)果。
評(píng)論