あかりラボ

七森中赤座あかり研究室の活動日記

aarch64 デバイスメモリ属性 GREについて

aarch64では、ページテーブルエントリによってページ単位でメモリ領域に属性をつけることができます。普通のメモリ領域とデバイスメモリ領域(MMIO領域など)にそれぞれNormalとDeviceという属性を付けるのが一般的です。

Deviceとマークされたメモリ領域はキャッシュされず、投機的なアクセスも禁止されます。そして、この領域はXN bitで実行不可能とマークすることが推奨されています*1

さらに、Deviceではもっと詳細に属性を以下の4種類のうちから指定する必要があります。

  • GRE
  • nGRE
  • nGnRE
  • nGnRnE

GREは、それぞれ以下の意味を持ちます。

  • G(Gathering)

write combiningを許可する。つまり、複数の同一領域への読み込み/書き込みを内部で単一の読み込み/書き込みにまとめて一回で処理する。詳細は以下を参照。

Understanding Write Combining on Arm - Resources - Research Collaboration and Enablement - Arm Community

  • R(Re-ordering)

メモリアクセスの順序変更を許可する。Normalメモリへのアクセス時と同じRe-orderingが発生し得る。

  • E(Early Write Acknowledgement)

posted writeを許可する。つまり、CPUがデバイスメモリ領域にwriteをしたときにデバイスからの到達応答を待たずにwriteアクセスを完了させる。

全てを許可したい場合はGREを指定し、Eだけを許可したい場合はnGnREを指定する必要があります。

使用方法

結局どのデバイス領域にどの属性を付ければええねん、というのはLinuxioremapを基準に考えると分かりやすいです。

https://dri.freedesktop.org/docs/drm/driver-api/device-io.html#architecture-exampleから引用、一部改変:

API Memory region type and cacheability
ioremap_np() Device-nGnRnE
ioremap() Device-nGnRE
ioremap_wc() Normal-Non Cacheable
ioremap_cache() Normal-Write-Back Cacheable

ioremap_wc()はDevice-GREと同義な気がしますが(実際にそういうパッチも出ている)、Normal Non Cacheableとして実装されています。

GREはメモリアクセスの順序があまり気にならないFrameBuffer領域によく使用されているみたいです。

結論

何も考えずにnGnRnEを指定するのはあまりよろしくない

*1:DDI0487H B2.1.2 Memory type overview 参照