我認爲你已經過分複雜化了。看看amba/axi規範(以及你在哪裏找到了多核cortex-m4?)。 ldrex/strex用於在多處理器芯片中的處理器之間共享資源。一段時間以來,它們被錯誤地用於其他事物。不幸的是,ARM做了一個非常糟糕的工作,正確記錄了所有這些。
ldr的獨佔部分是processorid和地址(範圍)保存在表中。當strex發生時,會檢查該地址(範圍)的processorid是否與EXOKAY匹配,如果不是OKAY則不進行存儲。 Strex沒有清除任何東西,他們有趣的是有這個clrex指令,我假設它將processorid設置爲某些不會觸及的值,或者取決於他們如何構建表格,它們釋放了一個表格條目。
我可以寫這之後,試試這個,但你可以很容易地LDREX然後STREX然後STREX,相當肯定我做了INT在全尺寸的武器,將嘗試在一個皮質-M4 LDREX,STREX,STREX,CLREX, strex,看看會發生什麼。
在單處理器系統中,LDREX/STREX預計在ARM的邏輯工作,但不是必需的芯片供應商,以支持它,並且可以簡單地返回OKAY(代替EXOKAY)。除了你進入芯片供應商之外,L1當然也可能是L2邏輯邏輯。 (cortex-ms是否有l2?)。通常情況下,您不必擔心觸及芯片供應商代碼,如果不是無限期地運行很長時間,您可能會停留在其中一個緩存中,但不知道這些情況。例如,在Linux中禁用這兩個緩存就是一個皇家PITA,它們可能會使它看起來像是編譯時選項,但可以深入瞭解現實。只有一個處理器,你如何獲得不同的處理器ID?
在多處理器芯片中,芯片供應商應該在緩存之外正確支持它,如果您甚至可以通過獨佔訪問達到目的,如何正常使用ldrex/strex,最有可能在您的L1並且永遠不會暴露於芯片供應商提供的內容,但是如果您在兩者之間中斷並且很可能由L2保存,則可能會發生這種情況。在這種情況下,芯片中有多個processorid是有道理的,因爲有多個處理器。
這是很好
了Cortex-M4處理器實現本地監控獨家。處理器內的本地監視器已被構建,以使其 不包含任何物理地址,而是將任何訪問視爲與先前LDREX的地址匹配的 。這意味着 實施的獨佔預留顆粒是整個內存 地址範圍。
m7 trm說同樣的事情。
沒有多核心怎麼會/會產生一個不同的ID? 該文檔使用術語processorid來指示正在使用哪個處理器。 cortex-m中有多少處理器?也許它在其他地方使用不同的字符串/名稱進行記錄,但此時我不知道cortex-m中的processorid是如何生成的,並且單處理器是否存在多個?我沒有獲得核心知道肯定。
所以即使邏輯不支持每個地址的獨佔訪問,他們並沒有說他們沒有檢查processorid,他們只是考慮所有標記爲共享的內存的strex訪問與最後一個獨立於ldrex的processorid進行檢查的地址。
編輯
PUT32(0x01000600,0x600);
PUT32(0x01000700,0x700);
PUT32(0x01000800,0x800);
CLREX();
hexstring(STREX(0x20000600,0x12345678));
hexstring(STREX(0x20000700,0x12345678));
hexstring(STREX(0x20000800,0x12345678));
hexstring(LDREX(0x20000600));
hexstring(STREX(0x20000600,0x6666));
hexstring(STREX(0x20000700,0x12345678));
hexstring(STREX(0x20000800,0x12345678));
hexstring(LDREX(0x20000600));
hexstring(STREX(0x20000700,0x7777));
hexstring(STREX(0x20000800,0x12345678));
hexstring(GET32(0x20000600));
hexstring(GET32(0x20000700));
hexstring(GET32(0x20000800));
CLREX();
hexstring(0xAABBCCDD);
hexstring(LDREX(0x20000600));
CLREX();
hexstring(STREX(0x20000600,0x2222));
hexstring(GET32(0x20000600));
生產
00000001
00000001
00000001
00000600 <-- ldrex
00000000 <-- strex pass
00000001 <-- strex fail
00000001
00006666
00000000
00000001
00006666
00007777
00000800
AABBCCDD
00006666
00000001
00006666
所以看起來他們在這裏做什麼是下一個STREX LDREX通過獨立的地址後。因此,使用你的條款strex「清除鎖定」。
請注意,在ldrex和strex之間加入clre會導致strex失敗。
不打相同的地址事項的一個LDREX一個STREX
hexstring(LDREX(0x20000900));
hexstring(STREX(0x20000900,0x2222));
hexstring(STREX(0x20000900,0x2222));
3EEDCC1B
00000000
00000001
開啓數據高速緩存上didnt並沒有改變結果。
測試功能:
.thumb_func
.globl LDREX
LDREX:
ldrex r0,[r0]
bx lr
.thumb_func
.globl CLREX
CLREX:
clrex
bx lr
.thumb_func
.globl STREX
STREX:
strex r0,r1,[r0]
bx lr
不像大哥哥懷裏:
CLREX();
hexstring(STREX(0x20000600,0x12345678));
hexstring(LDREX(0x20000600));
hexstring(STREX(0x20000600,0x6666));
hexstring(LDREX(0x20000600));
PUT32(0x20000600,0x11);
hexstring(STREX(0x20000600,0x6666));
00000001
00000600
00000000
00006666
00000000
的STREX生存的,之間至少基於文檔您發佈非獨佔店非獨佔訪問應該破壞先前的ldrex(在armv7-a上)。
注意上面是一個皮質-M4 r0p1 CPUID 0x410FC241
'DMB'通過使內存訪問直到內存層次結構中的各個點(即緩存)來指令內存訪問。高速緩存一致性機制對於允許處理器偵聽另一個高速緩存是必需的,否則您假設的情況可能會發生。 ARM緩存是一致的。沒有選項的'DMB'會進行全系統同步,我不知道它是什麼意思,但我可以寫一個內存。 –
對於讀取 - 修改 - 寫入的原子性而言,'DMB'不是必需的。 'DMB'確保*其他*內存操作按照RMW操作進行排序。 – EOF
的DMB是推動負載和存儲出去,讓他們完成這樣其他看到它... ...「確保鎖的成功要求由所有觀察者觀察到他們所觀察到的任何後續加載或存儲之前。」就像您使用其他內存障礙,刷寫寫入緩衝區和緩存等一樣。 –