10-Armv8-A memory model guide
目錄
- 1 簡介
- 2 內(nèi)存模型是什么,為什么需要它?
- 3 頁表中的Describing
- 3.1. 屬性的層次
- 3.2. 關(guān)閉MMU
- 4 內(nèi)存訪問排序
- 5 內(nèi)存類型
- 6 Normal memory
- 6.1. 訪問排序
- 6.2. 重新排序
- 7 Device memory
- 8 Describing the memory type
- 9 Cacheability 和 shareability屬性
- 10 權(quán)限屬性
- 10.1. 對非特權(quán)數(shù)據(jù)的特權(quán)訪問
- 10.2. 執(zhí)行權(quán)限
- 11 Access Flag :訪問標志
- 11.1. 更新 AF 位
- 11.2. Dirty狀態(tài)
- 12 對?和大小端
- 12.1. 對齊
- 12.2. 大小端
- 13 內(nèi)存別名和不匹配的內(nèi)存類型
- 14 Stage 1 和 Stage 2 的屬性位的結(jié)合
- 14.1 錯誤處理
1 簡介
本文介紹了 Armv8-A 中的內(nèi)存模型。 它首先解釋描述內(nèi)存的屬性來自哪里以及它們?nèi)绾畏峙浣o內(nèi)存區(qū)域。 然后介紹可用的不同屬性并解釋內(nèi)存排序的基礎(chǔ)知識。
此信息對于開發(fā)低級代碼(如引導代碼或驅(qū)動程序)的任何人都很有用。 它與編寫代碼來設(shè)置或管理內(nèi)存管理單元 (MMU) 的任何人都特別相關(guān)。
2 內(nèi)存模型是什么,為什么需要它?
內(nèi)存模型是一種組織和定義記憶行為的方式。 它提供了一種結(jié)構(gòu)和一組規(guī)則,供您在配置如何在系統(tǒng)中訪問和使用地址或地址區(qū)域時遵循。
內(nèi)存模型提供了可以應用于地址的屬性,它定義了與內(nèi)存訪問順序相關(guān)的規(guī)則。 考慮一個帶有地址空間的簡單系統(tǒng),如下圖所示:
地址空間中內(nèi)存區(qū)域的排列稱為地址映射。 在這里,map包含:
- 內(nèi)存和外圍設(shè)備
- 內(nèi)存中的代碼和數(shù)據(jù)中
- 屬于操作系統(tǒng)的資源和屬于用戶應用程序的資源
您希望處理器與外設(shè)交互的方式與它應該與內(nèi)存交互的方式不同。 您通常希望緩存內(nèi)存,但不想緩存外圍設(shè)備。 緩存是將信息的副本從內(nèi)存存儲到某個位置(稱為緩存)的行為。 緩存更靠近內(nèi)核,因此內(nèi)核訪問速度更快。 同樣,您通常希望處理器阻止用戶訪問內(nèi)核資源。 此圖顯示了具有一些您可能希望應用于內(nèi)存區(qū)域的不同內(nèi)存屬性的地址映射:
您需要能夠向處理器描述這些不同的屬性,以便處理器適當?shù)卦L問每個位置。
3 頁表中的Describing
虛擬地址空間和物理地址空間之間的映射在一組轉(zhuǎn)換表中定義,有時也稱為頁表。 對于虛擬地址的每個塊或頁面,轉(zhuǎn)換表提供相應的物理地址和訪問該頁面的屬性。 每個轉(zhuǎn)換表條目稱為塊或頁描述符。 在大多數(shù)情況下,屬性來自這個描述符。 此圖顯示了一個示例塊描述符,以及其中的屬性字段:
重要的比特位:
- SH - The shareable attribute
- AP - The access permission
- UXN and PXN – Execution permissions
3.1. 屬性的層次
某些內(nèi)存屬性可以在更高級別表的表描述符中指定。 這些是分層屬性。 這適用于訪問權(quán)限、執(zhí)行權(quán)限和物理地址空間。
如果這些位被設(shè)置,那么它們將覆蓋較低級別的條目,如果這些位被清除,則較低級別的條目將不加修改地使用。 一個例子,使用PXNTable(執(zhí)行權(quán)限)
從 Armv8.1-A 開始,您可以禁用對使用表描述符中的分層屬性設(shè)置訪問權(quán)限和執(zhí)行權(quán)限的支持。 這是通過相關(guān)的 TCR_ELx 寄存器控制的。 禁用時,以前用于分層控制的位可供軟件用于其他用途。
3.2. 關(guān)閉MMU
總而言之,地址的屬性來自轉(zhuǎn)換表。 轉(zhuǎn)換表位于內(nèi)存中,用于存儲虛擬地址和物理地址之間的映射。 這些表還包含物理內(nèi)存位置的屬性。
轉(zhuǎn)換表由內(nèi)存管理單元 (MMU) 訪問。 如果 MMU 被禁用會發(fā)生什么? 在編寫將在重置后立即運行的代碼時,這是一個需要解決的重要問題。
當 Stage 1 MMU 被禁用時:
- 所有數(shù)據(jù)訪問都是 Device_nGnRnE。 我們將在本指南的后面解釋這一點。
- 所有指令提取都被視為可緩存的。
- 所有地址都具有讀/寫訪問權(quán)限并且是可執(zhí)行的。
對于虛擬化涵蓋的異常級別,當禁用第 2 階段時,將使用未經(jīng)修改的第 1 階段屬性。
4 內(nèi)存訪問排序
在我們的指南 Armv8-A 指令集架構(gòu)中,我們介紹了簡單順序執(zhí)行 (SSE)。 SSE 是指令排序的概念模型。內(nèi)存訪問順序和指令順序是兩個不同但相關(guān)的概念。了解它們之間的區(qū)別很重要。
SSE 描述了處理器執(zhí)行指令的順序。總而言之,現(xiàn)代處理器擁有長而復雜的管道。這些流水線通常能夠重新排序指令或并行執(zhí)行多條指令,以幫助它們最大限度地提高性能。 SSE 意味著處理器必須像處理器一次執(zhí)行一條指令一樣,按照它們在程序代碼中給出的順序。這意味著硬件對指令的任何重新排序或多次發(fā)布必須對軟件不可見。
內(nèi)存排序是關(guān)于內(nèi)存訪問在內(nèi)存系統(tǒng)中出現(xiàn)的順序。由于寫緩沖區(qū)和緩存等機制,即使指令按順序執(zhí)行,相關(guān)的內(nèi)存訪問也可能不會按順序執(zhí)行。這就是為什么即使處理器遵循 SSE 模型來獲取指令,內(nèi)存排序也是一個需要考慮的重要事項。
5 內(nèi)存類型
系統(tǒng)中所有未被標記為故障的地址都被分配了一個內(nèi)存類型。 內(nèi)存類型是處理器應如何與地址區(qū)域交互的高級描述。 Armv8-A中有兩種內(nèi)存類型:Normal memory和device。
注意:Armv6 和 Armv7 包括第三種內(nèi)存類型:Strongly Ordered。 在 Armv8 中,這映射到 Device_nGnRnE。
6 Normal memory
普通內(nèi)存類型用于任何行為類似于內(nèi)存的東西,包括 RAM、閃存或 ROM。 代碼只能放置在標記為 Normal 的位置。 Normal 通常是系統(tǒng)中最常見的內(nèi)存類型,如下圖所示:
6.1. 訪問排序
傳統(tǒng)上,計算機處理器按照程序中指定的順序執(zhí)行指令。事情按照程序中指定的次數(shù)發(fā)生,并且一次只發(fā)生一次。這稱為簡單順序執(zhí)行 (SSE) 模型。大多數(shù)現(xiàn)代處理器似乎都遵循此模型,但實際上,許多優(yōu)化都已應用并可供您使用,以幫助提高性能。我們將在這里介紹其中的一些優(yōu)化。
標記為 Normal 的位置在訪問時沒有直接的副作用。這意味著讀取位置只是將數(shù)據(jù)返回給我們,但不會導致數(shù)據(jù)更改或直接觸發(fā)另一個進程。因此,對于標記為“正常”的位置,處理器可能會:
? 合并訪問。代碼可以多次訪問一個位置,或訪問多個連續(xù)的位置。為了效率,允許處理器檢測這些訪問并將這些訪問合并為單個訪問。例如,如果軟件多次寫入一個變量,處理器可能只顯示最后一次寫入內(nèi)存系統(tǒng)。
? 推測性地執(zhí)行訪問。允許處理器讀取標記為“正常”的位置,而無需軟件特別請求。例如,處理器可能會根據(jù)先前訪問的模式,在軟件請求數(shù)據(jù)之前使用模式識別來預取數(shù)據(jù)。該技術(shù)用于通過預測行為來加快訪問速度。
? 重新排序訪問。在內(nèi)存系統(tǒng)中看到的訪問順序可能與軟件發(fā)出訪問的順序不匹配。例如,處理器可能會重新排序兩次讀取以允許它生成更有效的總線訪問。對同一位置的訪問不能重新排序,但可能會合并。
想想這些優(yōu)化,比如允許處理器采用技術(shù)來加速性能和提高電源效率的自由。這意味著 Normal 內(nèi)存類型通常會提供最佳性能。
注意:允許處理器以這些方式進行優(yōu)化,但這并不意味著它總是如此。給定處理器對這些自由的利用程度取決于其微架構(gòu)。從軟件的角度來看,您應該假設(shè)處理器可能會執(zhí)行其中的任何一項或全部。
6.2. 重新排序
概括地說,對標記為“正常”的位置的訪問可以重新排序。 讓我們考慮這個示例代碼,其中包含三個內(nèi)存訪問、兩個存儲和一個加載的序列:
如果處理器對這些訪問進行重新排序,這可能會導致內(nèi)存中出現(xiàn)錯誤的值,這是不允許的。對于對相同字節(jié)的訪問,必須保持順序。處理器需要檢測危險并確保為預期結(jié)果正確排序訪問。
這并不意味著本示例沒有優(yōu)化的可能性。處理器可以將兩個存儲合并在一起,向內(nèi)存系統(tǒng)呈現(xiàn)一個合并的存儲。它還可以檢測到加載操作來自存儲指令寫入的字節(jié),以便它可以返回新值而無需從內(nèi)存中重新讀取它。
注意:示例中給出的序列是故意設(shè)計來說明這一點的。在實踐中,這些類型的危害往往更加微妙。
還有其他強制排序的情況,例如地址依賴關(guān)系。地址依賴是指加載或存儲使用先前加載的結(jié)果作為地址。在此代碼示例中,第二條指令取決于第一條指令的結(jié)果
此示例還顯示了地址依賴關(guān)系,其中第二條指令依賴于第一條指令的結(jié)果:
LDR X0,[X1] STR X2,[X5, X0] // The result of the previous load is used to calculate the address.在兩次內(nèi)存訪問之間存在地址相關(guān)性的情況下,處理器必須保持順序。 此規(guī)則不適用于控制依賴項。 控制依賴是指使用先前加載的值來做出決定。 此代碼示例顯示了一個負載,然后是一個依賴于負載值的比較和零分支操作:
LDRX0, [X1] CBZ X0, <somewhere_else> STRX2, [X5][Symbol] // There is a control dependency on X0, this does not guarantee ordering.在某些情況下,需要在訪問 Normal 內(nèi)存或訪問 Normal 和 Device 內(nèi)存之間強制執(zhí)行排序。 這可以使用屏障指令來實現(xiàn)
7 Device memory
設(shè)備內(nèi)存類型用于描述外設(shè)。 外設(shè)寄存器通常稱為內(nèi)存映射 I/O (MMIO)。 在這里,我們可以看到在我們的示例地址映射中通常標記為設(shè)備的內(nèi)容:
回顧一下,Normal 內(nèi)存類型意味著訪問沒有副作用。對于設(shè)備類型內(nèi)存,情況正好相反。設(shè)備內(nèi)存類型用于可能產(chǎn)生副作用的位置。
例如,對 FIFO 的讀取通常會導致它前進到下一個數(shù)據(jù)。這意味著對 FIFO 的訪問次數(shù)很重要,因此處理器必須遵守程序指定的內(nèi)容。設(shè)備區(qū)域永遠不可緩存。這是因為您不太可能希望緩存對外圍設(shè)備的訪問。
不允許對標記為設(shè)備的區(qū)域進行推測數(shù)據(jù)訪問。如果在架構(gòu)上訪問該位置,則處理器只能訪問該位置。這意味著已在架構(gòu)上執(zhí)行的指令已訪問該位置。
說明不應放置在標記為設(shè)備的區(qū)域中。我們建議始終將設(shè)備區(qū)域標記為不可執(zhí)行。否則,處理器可能會推測性地從中獲取指令,這可能會導致讀取敏感設(shè)備(如 FIFO)出現(xiàn)問題。
注意:這里有一個很容易被忽略的細微差別。將區(qū)域標記為設(shè)備僅可防止推測性數(shù)據(jù)訪問。將區(qū)域標記為不可執(zhí)行可防止推測性指令訪問。這意味著,為了防止任何推測性訪問,必須將區(qū)域標記為設(shè)備和不可執(zhí)行。
以下對device memory的類型進行總結(jié)
- Device-nGnRnE : 處理器必須嚴格按照代碼中內(nèi)存訪問來進行、必須嚴格執(zhí)行program order(無需重排序)、寫操作的ack必須來自最終的目的地
- Device-nGnRE : 處理器必須嚴格按照代碼中內(nèi)存訪問來進行、必須嚴格執(zhí)行program order(無需重排序)、寫操作的ack可以來自中間的write buffer
- Device-nGRE : 處理器必須嚴格按照代碼中內(nèi)存訪問來進行、內(nèi)存訪問指令可以進行重排、寫操作的ack可以來自中間的write buffer
- Device-GRE : 處理器對多個memory的訪問是否可以合并、內(nèi)存訪問指令可以進行重排、寫操作的ack可以來自中間的write buffer
?Gathering和non Gathering(G or nG):表示對多個memory的訪問是否可以合并,如果是nG,表示處理器必須嚴格按照代碼中內(nèi)存訪問來進行,不能把兩次訪問合并成一次。例如:代碼中有2次對同樣的一個地址的讀訪問,那么處理器必須嚴格進行兩次read transaction
?Reordering(R or nR):表示是否允許處理器對內(nèi)存訪問指令進行重排。nR表示必須嚴格執(zhí)行program order
?Early Write Acknowledgement(E or nE):PE訪問memory是有問有答的(更專業(yè)的術(shù)語叫做transaction),對于write而言,PE需要write ack操作以便確定完成一個write transaction。為了加快寫的速度,系統(tǒng)的中間環(huán)節(jié)可能會設(shè)定一些write buffer。nE表示寫操作的ack必須來自最終的目的地而不是中間的write buffer
8 Describing the memory type
9 Cacheability 和 shareability屬性
-
如果將block的內(nèi)存屬性配置成Non-cacheable,那么數(shù)據(jù)就不會被緩存到cache,那么所有observer看到的內(nèi)存是一致的,也就說此時也相當于Outer Shareable。
其實官方文檔,也有這一句的描述:
在B2.7.2章節(jié) “Data accesses to memory locations are coherent for all observers in the system, and correspondingly are treated as being Outer Shareable” -
如果將block的內(nèi)存屬性配置成write-through cacheable 或 write-back cacheable,那么數(shù)據(jù)會被緩存cache中。write-through和write-back是緩存策略。
-
如果將block的內(nèi)存屬性配置成 non-shareable, 那么core0訪問該內(nèi)存時,數(shù)據(jù)緩存的到Core0的L1 d-cache 和 cluster0的L2 cache,不會緩存到其它cache中
-
如果將block的內(nèi)存屬性配置成 inner-shareable, 那么core0訪問該內(nèi)存時,數(shù)據(jù)只會緩存到core 0和core 1的L1 d-cache中, 也會緩存到clustor0的L2 cache,不會緩存到clustor1中的任何cache里。
-
如果將block的內(nèi)存屬性配置成 outer-shareable, 那么core0訪問該內(nèi)存時,數(shù)據(jù)會緩存到所有cache中
以下也總結(jié)了一下shareable、cacheable屬性對緩存策略的影響:
| non-shareable | 數(shù)據(jù)不會緩存到cache (對于觀察則而言,又相當于outer-shareable) | core訪問該內(nèi)存時,數(shù)據(jù)只緩存的到Core的 cache 中,不會緩存到其它cache中 | 同左側(cè) |
| inner-shareable | 數(shù)據(jù)不會緩存到cache (對于觀察則而言,又相當于outer-shareable) | core訪問該內(nèi)存時,數(shù)據(jù)只會緩存到core的cache和 cluster的 cache中,該地址的TAG也不會存到snoop filter中,即不會被其它ACE Master snoop | 同左側(cè) |
| outer-shareable | 數(shù)據(jù)不會緩存到cache (對于觀察則而言,又相當于outer-shareable) | core訪問該內(nèi)存時,數(shù)據(jù)只會緩存到core的cache和 cluster的 cache中,該地址的TAG會存到snoop filter中,會被其它ACE Master snoop | 同左側(cè) |
10 權(quán)限屬性
訪問權(quán)限 (AP) 屬性控制是否可以讀取和寫入位置,以及需要什么權(quán)限。下表顯示了 AP 位設(shè)置:
如果訪問破壞了指定的權(quán)限,例如對只讀區(qū)域的寫入,則會生成異常(標記為權(quán)限錯誤)。
10.1. 對非特權(quán)數(shù)據(jù)的特權(quán)訪問
標準權(quán)限模型是特權(quán)較高的實體可以訪問屬于特權(quán)較低的實體的任何內(nèi)容。換句話說,操作系統(tǒng) (OS) 可以看到分配給應用程序的所有資源。例如,hypervisor可以查看分配給虛擬機的所有資源。這是因為在更高的異常級別執(zhí)行意味著特權(quán)級別也更高。
然而,這并不總是可取的。惡意應用程序可能會試圖欺騙操作系統(tǒng)代表應用程序訪問數(shù)據(jù),而應用程序不應該看到這些數(shù)據(jù)。這需要操作系統(tǒng)檢查系統(tǒng)調(diào)用中的指針。
Arm 架構(gòu)提供了幾個控件來簡化此操作。首先,有 PSTATE.PAN(從不特權(quán)訪問)位。
當該位置位時,從 EL1(或 E2H==1 時的 EL2)加載和存儲到非特權(quán)區(qū)域?qū)a(chǎn)生異常(Permission Fault),如下圖所示:
(注意是在 Armv8.1?A 中添加的PAN。)
PAN 允許對非特權(quán)數(shù)據(jù)的意外訪問被捕獲。例如,操作系統(tǒng)執(zhí)行訪問認為目的地是特權(quán)的。事實上,目的地是沒有特權(quán)的。這意味著操作系統(tǒng)的期望(目的地是特權(quán))和現(xiàn)實(目的地是非特權(quán)的)之間存在不匹配。這可能是由于編程錯誤,也可能是系統(tǒng)受到攻擊的結(jié)果。在任何一種情況下,PAN 都允許我們在訪問發(fā)生之前對其進行捕獲,從而確保安全操作。
有時操作系統(tǒng)確實需要訪問非特權(quán)區(qū)域,例如,寫入應用程序擁有的緩沖區(qū)。為了支持這一點,指令集提供了 LDTR 和 STTR 指令。
LDTR 和 STTR 是非特權(quán)加載和存儲。即使在 EL1 或 EL2 由操作系統(tǒng)執(zhí)行時,它們也會根據(jù) EL0 權(quán)限檢查進行檢查。因為這些是明確的非特權(quán)訪
問,所以它們不會被 PAN 阻止,如下圖所示:
這允許操作系統(tǒng)區(qū)分旨在訪問特權(quán)數(shù)據(jù)的訪問和預期訪問非特權(quán)數(shù)據(jù)的訪問。這也允許硬件使用該信息來檢查訪問。
注意: LDTR 中的 T 代表翻譯。這是因為第一個支持虛擬到物理轉(zhuǎn)換的 Arm 處理器只針對用戶模式應用程序,而不是操作系統(tǒng)。為了讓操作系統(tǒng)訪問應用程序數(shù)據(jù),它需要一個特殊的負載,一個帶有翻譯的負載。
當然,今天所有軟件都可以看到虛擬地址,但名稱仍然存在。
10.2. 執(zhí)行權(quán)限
除了訪問權(quán)限,還有執(zhí)行權(quán)限。這些屬性允許您指定不能從地址獲取指令:
- UXN. User (EL0) Execute Never (Not used at EL3, or EL2 when HCR_EL2.E2H==0) :EL0不允許執(zhí)行
- PXN. Privileged Execute Never (Called XN at EL3, and EL2 when HCR_EL2.E2H==0):特權(quán)程序不允許執(zhí)行
有單獨的 Privileged 和 Unprivileged 位,因為應用程序代碼需要在用戶空間 (EL0) 中可執(zhí)行,但絕不應使用內(nèi)核權(quán)限 (EL1/EL2) 執(zhí)行,如下圖所示:
該架構(gòu)還在系統(tǒng)控制寄存器 (SCTLR_ELx) 中提供控制位,以使所有可寫地址都不可執(zhí)行。
具有 EL0 寫入權(quán)限的位置永遠不能在 EL1 上執(zhí)行。注意:請記住,Arm 建議始終將設(shè)備區(qū)域標記為從不執(zhí)行 (XN)。
11 Access Flag :訪問標志
您可以使用訪問標志 (AF) 位來跟蹤轉(zhuǎn)換表條目所覆蓋的區(qū)域是否已被訪問。你可以設(shè)置AF 位:
- AF=0. Region not accessed.
- AF=1. Region accessed.
AF 位對操作系統(tǒng)很有用,因為您可以使用它來識別哪些頁面當前未被使用并且可以被調(diào)出(從 RAM 中刪除)。
注意:訪問標志通常不用于裸機環(huán)境,您可以使用預先設(shè)置的 AF 位生成表。
11.1. 更新 AF 位
當使用 AF 位時,會創(chuàng)建轉(zhuǎn)換表,且 AF 位最初是清零的。當一個頁面被訪問時,它的 AF 位被置位。軟件可以解析表格去檢查 AF 位是設(shè)置還是清除。AF=0表示該頁面沒用被訪問,將其頁面換出去可能是更好選擇.
有兩種方法可以在訪問時設(shè)置 AF 位:?
- 軟件更新:訪問頁面會導致同步異常(Access Flag fault)。在異常處理程序中,軟件負責設(shè)置相關(guān)轉(zhuǎn)換表條目中的AF位并返回。
- 硬件更新:訪問頁面會導致硬件自動設(shè)置 AF 位,而無需生成異常,此行為需要啟用并已添加到 Armv8.1?A 中。
11.2. Dirty狀態(tài)
Armv8.1?A 引入了處理器管理塊或頁面的臟狀態(tài)的能力。Dirty狀態(tài)記錄塊或頁是否已被寫入。這很有用,因為如果塊或頁面被調(diào)出,Dirty狀態(tài)會告訴管理軟件是否需要將 RAM 的內(nèi)容寫出到存儲中。
例如,讓我們考慮一個文本文件。該文件最初從磁盤(閃存或硬盤驅(qū)動器)加載到 RAM 中。當它稍后從內(nèi)存中刪除時,操作系統(tǒng)需要知道 RAM 中的內(nèi)容是否比磁盤上的內(nèi)容更新。如果 RAM 中的內(nèi)容更新,則需要更新磁盤上的副本。如果不是,則可以刪除 RAM 中的副本。
當啟用Dirty狀態(tài)管理時,軟件最初創(chuàng)建轉(zhuǎn)換表條目,并將訪問權(quán)限設(shè)置為只讀,并設(shè)置 DBM(Dirty位修飾符)位。如果該頁面被寫入,硬件會自動將訪問權(quán)限更新為讀寫。
將 DBM 位設(shè)置為 1 會更改訪問權(quán)限位(AP[2] 和 S2AP[1])的功能,以便記錄Dirty狀態(tài)而不是記錄訪問權(quán)限。這意味著當 DBM 位設(shè)置為 1 時,訪問權(quán)限位不會導致訪問錯誤。
注意:不使用硬件更新選項也可以獲得相同的結(jié)果。該頁面將被標記為只讀,導致第一次寫入時出現(xiàn)異常(權(quán)限錯誤)。異常處理程序會手動將頁面標記為可讀寫,然后返回。如果軟件想要進行寫時復制,則可能仍會使用此方法。
12 對?和大小端
12.1. 對齊
如果地址是元素大小的倍數(shù),則訪問被描述為對?。
對于 LDR 和 STR 指令,元素大小是訪問的大小。例如,一條 LDRH 指令加載一個 16 位的值,并且必須來自一個 16 位的倍數(shù)的地址才能被視為對?。
LDP 和 STP 指令分別加載和存儲一對元素。要對?,地址必須是元素大小的倍數(shù),而不是兩個元素的組合大小。例如:LDP X0, X1, [X2] .
此示例加載兩個 64 位值,因此總共 128 位。 X2 中的地址需要是 64 位的倍數(shù)才能被視為對? . 同樣的原則也適用于向量加載和存儲。
當?shù)刂凡皇窃卮笮〉谋稊?shù)時,訪問是不對?的。允許對標記為正常的地址進行未對?的訪問,但不允許對設(shè)備區(qū)域進行非對?訪問。對設(shè)備區(qū)域的未對?訪問將觸發(fā)異常(對?錯誤)。
通過設(shè)置 SCTLR_ELx.A 可以捕獲對標記為 Normal 的區(qū)域的未對?訪問。如果該位置位,對正常區(qū)域的未對?訪問也會產(chǎn)生對?錯誤。
12.2. 大小端
在 Armv8?A 中,指令提取始終被視為小端
對于數(shù)據(jù)訪問,是否支持 little?endian 和 big?endian 由實現(xiàn)定義。如果只支持一個,則由實現(xiàn)定義支持哪一個。
對于同時支持大端和小端的處理器,字節(jié)序是按異常級別配置的。
注意:如果您不記得 IMPLEMENTATION DEFINED 的定義,請閱讀介紹 Arm 架構(gòu)。Arm Cortex?A 處理器同時支持大端和小端。
13 內(nèi)存別名和不匹配的內(nèi)存類型
當物理地址空間中的給定位置有多個虛擬地址時,這稱為別名。
屬性基于虛擬地址。這是因為屬性來自翻譯表。當一個物理位置有多個別名時,所有虛擬別名都必須具有兼容的屬性,這一點很重要。我們將兼容描述為:
- Same memory type, and for Device the same sub-type
- For Normal locations, the same cacheability and shareability
如果屬性不兼容,則內(nèi)存訪問的行為可能與您預期的不同,這可能會影響性能。
此圖顯示了別名的兩個示例。位置 A 的兩個別名具有兼容的屬性。這是推薦的方法。位置 B 的兩個別名具有不兼容的屬性(Normal 和 Device),這會對一致性和性能產(chǎn)生負面影響:
Arm 強烈建議軟件不要將不兼容的屬性分配給同一位置的不同別名。
14 Stage 1 和 Stage 2 的屬性位的結(jié)合
使用虛擬化時,虛擬地址要經(jīng)過兩個轉(zhuǎn)換階段。一個階段在操作系統(tǒng)的控制下,另一階段在管理程序的控制下。 Stage 1 和 Stage 2 表都包含屬性。這些是如何結(jié)合的?
下圖顯示了一個示例,其中階段 1 將位置標記為device,但相應的階段 2 轉(zhuǎn)換標記為normal。結(jié)果類型應該是什么?
在 Arm 架構(gòu)中,默認是使用最嚴格的類型。在此示例中,Device 比 Normal 更嚴格。因此,生成的類型是 Device。
對于類型和可緩存性,附加控件 (HCR_EL2.FWB) 允許覆蓋此行為。設(shè)置 FWB 后,Stage 2 可以覆蓋 Stage 1 的類型和可緩存性設(shè)置,而不是組合行為。
(注意: HCR_EL2.FWB 是在 Armv8.4?A 中引入的。)
14.1 錯誤處理
我們先看一下 下圖的兩個示例;
在這兩個示例中,結(jié)果屬性都是 RO(只讀)。如果軟件要寫入位置,則會產(chǎn)生錯誤(權(quán)限錯誤)。但是,在第一種情況下,這是一個階段 1 故障,而在第二種情況下,這將是一個階段 2 故障。在該示例中,階段 1 故障將發(fā)送到 EL1 的操作系統(tǒng),而階段 2 故障將發(fā)送到 EL2 并由管理程序處理。
最后,我們來看一個 Stage 1 和 Stage 2 屬性相同的例子:
在這里,結(jié)果屬性很簡單。是 R0。但如果軟件寫入該位置,是否會產(chǎn)生階段 1 或階段 2 故障?答案是第 1 階段。如果第 1 階段和第 2 階段會引發(fā)不同的故障類型,這也是正確的。階段 1 故障總是優(yōu)先于階段 2 故障。
總結(jié)
以上是生活随笔為你收集整理的10-Armv8-A memory model guide的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 09-LearnTheArchitect
- 下一篇: 编写TA链接静态库的方法