1. i.MX 8M PlusのInline ECC機能

 

i.MX 8M PlusのDDR Controllerは、ソフトエラー(アルファ線や中性子などに起因するDRAMのビット反転)からシステムを保護するため、Inline ECC機能をサポートしています。 64bitsデータ毎に8bitsのECC (Error Correcting Code)を保持することで、シングルビットエラーの訂正とダブルビットエラーの検出を行います。

ECCを保持するための専用メモリは持たないため、DDR容量の約1/8をECC領域として使用します。

32bitデータバスをデータとECCで共有するため、Inline ECC機能を有効にするとDDRアクセスのパフォーマンスは下がります。

 

1.1. SEC(Single-bit Error Correction)

SECは、1ビットのエラーを検出し、正しい値に修正するDDR Controllerの機能です。Keita_Nagashima_4-1765435456176.png

Fig. 1 SECの概念図

 

1.2. DED(Double-bit Error Detection)

DEDは、2ビットのエラーを検出するDDR Controllerの機能です。Keita_Nagashima_5-1765435507241.png

Fig. 2 DEDの概念図

Note : 

実際には、8バイトではなく、64バイトアラインのデータ領域(+8バイトのECC)でSEC、DEDを検出します。

 

2. Inline ECCのメモリマッピング(概略)

 

DDR容量によってInline ECCのメモリマッピングの設定方法が異なります。

 

2.1. DDR容量が2のべき乗の場合 (binary-aligned densities)

例えば、1, 2, 4, 8, 16GBの場合、

  1. DDRの下位アドレス 7/8 をデータ領域、上位アドレス 1/8 をECC領域として使用します。ECC領域には基本的にはアクセスできません。

  2. データ領域をRegion 0~6、Other regionの最大8つの領域に分割して、各regionでECC機能の有効・無効を設定します。

  3. Region 0~6の容量はすべて同じで、DDR容量の1/8, 1/16, 1/32, 1/64のいずれかに設定します。残りはすべてOther regionになります。

以下は、Region 0~6の容量を1/8に設定した場合のメモリマッピングです。この場合はOther regionは存在しません。

Keita_Nagashima_2-1765437269920.png

Fig. 3 メモリマッピングの例 (1/8)

 

以下は、Region 0~6の容量を1/16に設定した場合のメモリマッピングです。

Keita_Nagashima_3-1765437330955.png
Fig. 4 メモリマッピングの例 (1/16)

 

2.2. DDR容量が2のべき乗ではない場合 (non-binary-aligned densities)

例えば、3, 6, 12GBの場合、(i.MX 8M Plus LPDDR4 EVKは6GBなので、このケースに該当します)

  1.  DDR全体を2のべき乗の容量で3分割します。

    • 3GBの場合、1GB x 3

    • 6GBの場合、2GB x 3

    • 12GBの場合、4GB x 3

  2.  3分割された下位アドレスの領域に対して、 2.1. DDR容量が2のべき乗の場合 の設定を行います。

  3.  3分割された上位アドレスの2つの領域の設定は、下位アドレス領域と同じ設定になります。

 以下は、1/8を設定した場合のメモリマッピングです。

Keita_Nagashima_4-1765437541555.png

Fig. 5 DDR容量が2のべき乗ではない場合のメモリマッピングの例 (1/8)

 

3. DDR Register Programming Aidによる設定

 

DDR Register Programming Aid (以下、DDR RPA)でInline ECCの設定を行います。

Note : 

事前にInline ECCが無効の状態でDDR stress testが動作する(だけではなく、u-boot起動まで動作確認できている)DDR RPAを用意してください。

i.MX8MP LPDDR4/DDR4 RPA v6以前の設定には不具合があるためInline ECCが正常動作しません。 少なくともv7以降を使用してください。特に事情がなければ最新版のDDR RPAを使ってください。 (2024/09時点での最新版はv9です。)

Linux BSPのU-Bootに含まれているi.MX 8M Plus EVK用の lpddr4_timing.cddr4_timing.cCONFIG_IMX8M_DRAM_INLINE_ECC のdefineが入っていて一見動作しそうですが、Inline ECC設定の不具合があり正常動作しません。 EVKでテストする場合であってもDDR RPAとDDR Toolでlpddr4_timing.c/ddr4_timing.cを生成してください。

 

3.1. Inline ECCを有効にする

DDR RPAのRegister ConfigurationシートでInline ECCの項目をEnableに設定します。

 
Keita_Nagashima_1-1765438351335.png

 

3.2. メモリマッピング

 

3.2.1. DDR容量が2のべき乗の場合 (binary-aligned densities)

DDR容量が2のべき乗の場合は、ECC_Config_BinaryAlignedのシートを使用します。

  • Region 0~6の容量を指定します。(1/8, 1/16, 1/32, 1/64のいずれか)

  • Region 0~6、Other RegionのECC有効・無効を設定します。(PROTECTED, UNPROTECTEDのいずれか)

Region 0~6の容量を1/8に設定した場合の例です。

Keita_Nagashima_2-1765438431895.png

Fig. 6 DDR RPAでの設定 (1/8)

 

Region 0~6の容量を1/16に設定した場合の例です。

Keita_Nagashima_3-1765438479461.png

Fig. 7 DDR RPAでの設定 (1/16)

 

3.2.2. DDR容量が2のべき乗ではない場合 (non-binary-aligned densities)

DDR容量が2のべき乗ではない場合は、ECC_Config_nonBinaryAlignedのシートを使用します。(i.MX 8M Plus LPDDR4 EVKは6GBなので、このケースに該当します)

  • Region 0~6の容量を指定します。(1/8, 1/16, 1/32, 1/64のいずれか)

  • ECC Memory Region 0の中のRegion 0~6、Other RegionのECC有効・無効を設定します。(PROTECTED, UNPROTECTEDのいずれか)

ECC Memory Region 1/2 は自動的に ECC Memory Region 0と同じ設定になります。

Region 0~6の容量を1/8に設定した場合の例です。

Keita_Nagashima_6-1765438674787.png
Keita_Nagashima_5-1765438582315.png
Keita_Nagashima_7-1765438743893.png

Fig. 8 DDR RPAでの設定 (1/8)

 

Region 0~6の容量を1/32に設定した場合の例です。

Keita_Nagashima_8-1765438820847.pngKeita_Nagashima_9-1765438875946.pngKeita_Nagashima_10-1765438920329.png

Fig. 9 DDR RPAでの設定 (1/32)

 

4. DDR Toolによるテストとlpddr4_timing.c/ddr4_timing.c生成

 

DDR ToolでDDR RPAで行った設定の動作確認ができます。

DDR stress testをパスしたら、U-Bootに組み込むlpddr4_timing.c/ddr4_timing.cを生成します。

 

5. U-BootのInline ECC実装

 

5.1. lpddr4_timing.c/ddr4_timing.cの置き換え

lpddr4_timing.c または ddr4_timing.c をDDR RPAとDDR Toolで生成したファイルに置き換えます。

 

5.2. Configの追加

U-BootのconfigファイルCONFIG_IMX8M_DRAM_INLINE_ECC=y を追加します。

Listing 1 uboot-imx/configs/imx8mp_evk_defconfig に追加
CONFIG_IMX8M_DRAM_INLINE_ECC=y

Note :

U-Bootのconfigファイル imx8mp_evk_inline_ecc_defconfig はLinux BSP 5.4で追加されましたが、適切にメンテされていないので非推奨です。 EVKでテストする場合は imx8mp_evk_defconfig にconfigを追加して使用したほうが安全です。

5.3. Linux reserved領域の変更

ソフトウェアからECC領域へのアクセスは禁止されています。 そのため、Linux kernel(等のシステム・ソフトウェア)がECC領域をreserved領域として扱うようにdevice treeを動的に変更します。 デフォルトはEVKのDDR容量(LPDDR4は6GB、DDR4は4GB)に合わせてハードコードされているので、 DDR容量がEVKと異なる場合はコードを修正する必要があります。

uboot-imx/board/freescale/imx8mp_evk/imx8mp_evk.cft_board_setup 関数でECC領域を実際のDDR容量に合わせて変更します。 例えば、DDR4の場合は、DDR容量4GBの想定でECC領域の開始アドレスとサイズがハードコードされています。

Listing 2 DDR4の容量4GBでハードコードされている部分
phys_addr_t ecc_start = 0x120000000;
size_t ecc_size = 0x20000000;

実際のDDR容量が2GBの場合、物理アドレス 0x40000000 ~ 0xc0000000 の上位アドレス 1/8 (256MB)をECC領域としてreserveします。

Listing 3 DDR容量2GBに変更する例
phys_addr_t ecc_start = 0xb0000000;
size_t ecc_size = 0x10000000;

imx8mp_evk.c を使用していない場合は、 ft_board_setup 関数と同等の処理を追加する必要があります。

 

5.4. Relocationの対応

DDR容量が2GB以下、かつ、OPTEEを組み込まない場合、U-BootはDDRの最上位アドレスにrelocationを試みますが、 ECC領域と重なっているため、relocation中にハングアップします。 それを回避するために、 imx8mp_evk.h のDDR容量定義 PHYS_SDRAM_SIZE からECC領域の容量(1/8)を減らします。

Listing 4 uboot-imx/include/configs/imx8mp_evk.h
-#define PHYS_SDRAM_SIZE         0x80000000
+#define PHYS_SDRAM_SIZE         0x70000000

 

5.5. ECC領域へのアクセス処理を除外

U-BootでECC領域にアクセスしているようなコードが他にもある場合は、ECC領域へのアクセスを除外する必要があります。 例えば、メモリテストでDDR全域にアクセスしているような場合は、ECC領域へのアクセスは行わないように変更してください。

参考: https://github.com/nxp-imx/uboot-imx/blob/lf-6.1.55-2.2.0/configs/imx8mp_evk_defconfig#L10-L11

 

6. Linuxでの動作確認

 

6.1. 起動ログの確認

Linux起動時にEDACドライバが組み込まれていることを確認します。(EDAC = Error Detection And Correction) i.MX 8M PlusのEDACのドライバは linux-imx/drivers/edac/synopsys_edac.c です。

Listing 5 起動ログの確認
root@imx8mp-lpddr4-evk:~# dmesg | grep EDAC
[    0.116733] EDAC MC: Ver: 3.0.0
[    1.874689] EDAC MC0: Giving out device to module 1 controller synps_ddr_controller: DEV synps_edac (INTERRUPT)

 

6.2. メモリマッピングの確認

コマンド cat /proc/iomem で、 5.3. Linux reserved領域の変更 で設定したとおりにECC領域がreservedになっていることを確認します。 以下はi.MX 8M Plus LPDDR4 EVK(DDR容量が6GB)の例です。

Listing 6 メモリマッピングの確認
root@imx8mp-lpddr4-evk:~# cat /proc/iomem | grep reserved
...
b0000000-bfffffff : reserved
...
130000000-13fffffff : reserved
...
1b0000000-1bfffffff : reserved

 

6.3. ECCエラー発生時の確認

アプリケーション・ノート AN13566 - ECC on i.MX 8 Series によると、i.MX 8M PlusのDDR ControllerにはECCエラーを意図的に発生させる機能はありません。

3.2.9 ECC error injection through software

The ECC error injection is a useful optional feature for system-level software validation. Unlike the Sideband ECC, there is no dedicated hardware support for it. However, errors can be injected through the software by unlocking the ECC region through the “ECC_REGION_PARITY_LOCK” register and overriding ECC parity bits. When the corresponding addresses are read from a protected memory region, ECC errors are generated as correctable or uncorrectable, depending on the type of error introduced.

NOTE: ECC data poisoning is not supported by the DDR controller. The reference manual will be updated to remove this functionality.

したがって、ECC領域のロックを解除し、コアからECC領域を変更することで擬似的にECCエラーが発生する状態を作ってテストを行います。 基本的な考え方は以下のようになります。

  1. DataAddrに8bytes値0xffffffff_ffffffffを書きます。DDRCはDDRに書き込みを行い、同時にECC 1byteも書き込みます。

  2. ECC regionをアンロックします。コアからECC領域へのアクセスが可能になります。

  3. DataAddrに対応するECC byteのアドレスを求め、ECCの1byteを読みます。

  4. 1bitだけ反転した値0xffffffff_fffffffeをDataAddrに書きます。ECC 1byteも更新されます。

  5. ECC 1byteに、3.で読んだECC byteの値を書き戻します。

  6. ECC regionをロックします。コアからECC領域へのアクセスが禁止されます。

  7. DataAddrの値を読みます。この時、ECCが矛盾しているため、Single-bit Error Correctionが動作して、訂正された8bytesの値、0xffffffff_ffffffffが読み出されます。また、Correctable Error interruptがコアに通知されます。

Note : 

DDRへのアクセスを発生させるため、non-cacheの領域でテストを行う必要があります。

Keita_Nagashima_11-1765439108812.png

Fig. 10 SEC(Single-bit Error Correction)のテスト方法

 

DED(Double-bit Error Detection)のデバッグも同じ方法で行うことができます。

 

7. 参考資料

 

 

8. 注意

 

  • 本資料はNXP製品を活用していただくための参考資料です。

  • 正式な仕様は製品マニュアル・アプリケーションノートを参照ください。

  • 使用ソフトウェアのバージョンなど諸条件の差異により、記載内容と実際の動作が異なる場合があります。

  • すべての機能検証を行ったものではありませんので、必ずご使用目的に適合した検証・試験を行ってください。