私はあなたがそれを複雑にしていると思います。 amba/axiの仕様を見てください(また、マルチコアの皮質-m4はどこにありますか?)。 ldrex/strexは、マルチプロセッサチップ内のプロセッサ間でリソースを共有するためのものです。彼らはしばらくの間、他のものに間違って使われてきました。 ARMは残念なことに、これを正しく文書化するのは異常に悪い仕事でした。
ldrの排他的な部分は、processoridとアドレス(範囲)がテーブルに保存されていることです。 strexが起こると、そのアドレス(range)のprocessoridがEXOKAYと一致するかどうかチェックされ、OKAYではない場合はストアを実行してください。 Strexは何もクリアしていません。彼らは興味深いことに、このclrex命令を持っています。プロセッサIDは、ヒットしなかったり、テーブルを作成する方法によって、テーブルエントリを解放します。
私はこれを書いた後にこれを試してもよいが、あなたはldrexとstrexとstrexを、かなり確かに私は完全な大きさの腕にintした、皮質-m4 ldrex、strex、strex、clrex、ストリートと何が起こるか見る。
ldrex/strexはARMのロジックで動作することが期待されていますが、チップベンダーはサポートする必要はなく、(EXOKAYの代わりに)OKAYを返すだけです。 L1は確かにそしておそらくL2はあなたがチップベンダーに入ることを超える腕の論理です。 (cortex-msにはl2がありますか?)通常は、チップベンダのコードを叩くことを心配する必要はありません。キャッシュの1つに残るので、無期限に実行すると長時間実行できます。例えば、Linuxで両方のキャッシュを無効にすることはロイヤルPITAです。コンパイル時のオプションのように思えるかもしれませんが、現実を掘り下げて見てください。そして、1つのプロセッサだけでは、どのように異なるプロセッサIDを取得しますか?
マルチプロセッサチップでは、チップベンダーは排他的アクセス権を持っていてもキャッシュを超えて正しくサポートするはずです。ldrex/strexが通常どおりに使用されているか、L1チップベンダーが提供したものにさらされることはありませんが、途中で中断され、L2によって保存される可能性があります。この場合、複数のプロセッサが存在するため、チップ内に複数のプロセッサIDを持つことは理にかなっています。
これは
のCortex-M4プロセッサは、ローカル排他モニタを実装していいです。 プロセッサ内のローカルモニタは、 が物理アドレスを保持せず、その代わりに以前のLDREXのアドレスと一致するすべてのアクセスを として扱うように構成されています。これは、 が排他予約顆粒を実装したことがメモリ全体が の範囲であることを意味します。
m7 trmは同じことを言います。
複数のコアを持たない場合どのようにして異なるIDを生成できますか? ドキュメントでは、プロセッサIDという用語を使用して、使用されているプロセッサを示しています。どのように多くのプロセッサが皮質にありますか?他の文字列/名前を使用して別の場所で文書化されているかもしれませんが、現時点では、cortex-mのprocessoridがどのように生成され、ユニプロセッサであるかはわかりません。私は確かに知るためにコアにアクセスできない。
論理がアドレスごとの排他アクセスをサポートしていないにもかかわらず、プロセッサIDをチェックしなかったとは言わず、sharedとしてマークされたメモリのすべてのstrexアクセスを、最後のldrexのprocessoridそのアドレスの。
00000001
00000001
00000001
00000600 <-- ldrex
00000000 <-- strex pass
00000001 <-- strex fail
00000001
00006666
00000000
00000001
00006666
00007777
00000800
AABBCCDD
00006666
00000001
00006666
を生産
EDIT
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));
は、彼らがここで何をしたかのように見えるLDREXは、アドレスとは独立して通過した後の次のSTREXです。だからあなたの言葉を使って、ストリートは "ロックをクリア"します。
ldrexとstrexの間にclrexを置くと、strexが失敗することに注意してください。同じアドレスを打っていない
は結果を変更問題1 LDREX didntの上のデータキャッシュを回す
hexstring(LDREX(0x20000900));
hexstring(STREX(0x20000900,0x2222));
hexstring(STREX(0x20000900,0x2222));
3EEDCC1B
00000000
00000001
STREX 1にdoesntの。
テスト機能:兄付ARMとは異なり
.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上)を台無しにするはずです。上記
注チップ設計者は、それが安全になりますので、それが安全であるのCortex-M4 r0p1 CPUID 0x410FC241に
「DMB」は、メモリ階層(すなわちキャッシュ)内の様々な点までそれらを見えるようにすることによって、メモリアクセスを順序付ける。プロセッサが別のキャッシュをスヌーピングできるようにするには、キャッシュコヒーレンスメカニズムが必要です。仮定した状況は非常にうまくいく可能性があります。 ARMキャッシュは一貫しています。さらにオプションのない「DMB」はフルシステム同期を行いますが、私はそれが何を意味するのかはわかりませんが、私はメモリに書き込むことができます。 –
「DMB」は、リード・モディファイ・ライトのアトミック性には必要ありません。 「DMB」は、*他の*メモリ操作がRMW操作に関して順序付けされることを保証する。 – EOF
DMBは荷物を押して保管しておき、荷物を完成させてください。他の荷物を観察する前に、すべてのオブザーバーによってロックが成功していることを確認してください。他のメモリバリアを使用して、書き込みバッファやキャッシュなどをフラッシュするのと同じように。 –