1. はじめに
Cyclone® V SoC / Arria® V SoC および Arria® 10 SoC は、Arm® Cortex®-A9 デュアルコア・プロセッサーを搭載しており、本資料ではそれぞれのコアをそれぞれ CPU0、CPU1 と記載します。
ブートフローにおける U-boot までは CPU0 で動作し、CPU1 を起動する操作を行わなければ、
CPU1 はリセット状態となります。
マルチコア対応の OS を使用する場合はブートアップ・コード内で CPU1 の起動が行われますが、
OS 未使用もしくはマルチコア非対応 OS の場合はユーザーにより明示的に CPU1 を起動するコードの実装が必要となります。
この記事ではユーザーが明示的にデュアルコアを起動する際の手順について説明しています。
尚、Cyclone® V SoC / Arria® V SoC と Arria® 10 SoC では、フローに多少の差があります。
この記事では Cyclone® V SoC / Arria® V SoC について説明しています。
2. CPU1 の起動手順
起動の手順としては下図 1 のようになります。
最初に CPU0 が起動し、その後 CPU0 が CPU1 を起動させます。
CPU0 は CPU1 を起動させるために、以下のレジスターを設定する必要があります。
- remap レジスター
- L2 Cache Address Filtering レジスター
- cpu1startaddr レジスター
- mpumodrst レジスター (CPU1 のリセット解除)
【図 1】 CPU1 の起動手順
3. 設定するレジスター
この章では CPU1 が設定するレジスター(remap、L2 Cache Address Filtering、cpu1startaddr、mpumodrst)について説明します。
3-1. remap レジスター
remap レジスターは 0x0 番地にマッピングするメモリーの指定と、HPS-FPGA ブリッジのアドレス空間を有効化する設定を行うレジスターです。
remap レジスターの 1 ビット目(ビット 0)の設定により、MPU から見た 0x00000000~0x00100000 の領域に、BootROM か On Chip RAM を選択することができます。
CPU1 が起動したとき BootROM が見えるように、このレジスターを設定する必要がありますので、CPU0 で reamp レジスターの 1 ビット目を以下のように設定します。
- reamp [0] = 0x0
reamp レジスターの詳細については下記資料をご参照ください。
参考資料: Cyclone® V HPS Memory Map、remap
【図 2】remap レジスター・アドレスマップ
3-2. L2 Cache Address Filtering レジスター
L2 Cache Address Filtering レジスターは、L2 Cache のカテゴリーにあるレジスターで、MPU アドレス空間上のどこの番地を SDRAM として見せるかを設定するレジスターです。
L2 Cache Address Filtering レジスターは、以下の 2 つのレジスターとして構成され、SDRAM を見せる領域の Start Address と End Address を指定する仕組みになっています。
- L2 Cache Address Filtering Start Register(Address: 0xFFFEFC00)
- L2 Cache Address Filtering End Register(Address: 0xFFFEFC04)
CPU1 が起動するとき 0x00000000~0x00100000 の領域は、BootROM が見えなければなりません。
そのため、この領域は SDRAM が見えないように下記のように設定します。
- Address Filtering Start Register(Address: 0xFFFEFC00)= 0x00100001
L2 Cache Address Filtering レジスターの仕様については、下記資料で紹介していますのでご覧ください。
参考資料: SoC FPGA のブート前後における SDRAM 領域のアドレスマッピング設定状態
"3. Address Filtering レジスターの仕様" の章をご覧ください。
3-3. cpu1startaddr レジスター
cpu1startaddr レジスターは CPU1 がジャンプするエントリーポイント(スタートアドレス)を登録するレジスターです。
この 32bit のレジスターでエントリーポイントのアドレスを設定します。
cpu1startaddr レジスターの詳細については下記資料をご参照ください。
参考資料: Cyclone® V HPS Memory Map、cpu1startaddr
【図 3】 cpu1startaddr レジスター・アドレスマップ
3-4. mpumodrst レジスター
mpumodrst レジスターは CPU などのリセットを制御するレジスターです。
CPU1 はこの mpumodrst レジスターによりリセット解除されます。
mpumodrst レジスターの 2 ビット目(ビット 1)が CPU1 のリセット解除なので、下記のように設定します。
- mpumodrst [1] = 0x0
mpumodrst レジスターの詳細については下記資料をご参照ください。
参考資料: Cyclone® V HPS Memory Map、mpumodrst
【図 4】 mpumodrst レジスター・アドレスマップ
4. サンプルコード
前の章で紹介したレジスターの設定を行うサンプルコードをご紹介します。
この内容は、CPU1 を起動するために CPU0 に実装するコード例になります。
【図 5】 レジスター設定のサンプルコード
5. 注意点
CPU1 のリセット解除前に CPU1 の実行バイナリーを事前にメモリーへ格納しておく必要があります。
格納の仕方は自由ですが今回は一例として、SD カードの FAT 領域に格納している CPU0 / CPU1 の実行バイナリーを、SDRAM へ展開し実行するフローをご紹介します。
===============
1. SD カードの FAT 領域に CPU0 と CPU1 の実行バイナリーを格納します。
2. U-boot を実行し、コマンドラインを準備します。
3. 下記コマンドで CPU0 と CPU1 の実行バイナリーを SDRAM へ展開します。
fatload mmc 0 0x00900000 cpu1_main.bin
fatload mmc 0 0x00200000 cpu0_main.bin
4. 下記コマンドで CPU0 のコードを実行します。
go 0x00200000
===============
ポイント:
コマンド引数のアドレス(CPU0、CPU1 のバイナリーの配置)はあくまで一例です。
ここでは、CPU0 用アプリケーションのエントリーポイントが 0x00200000。
cpu1startaddr レジスターに設定する CPU1 のエントリーポイントが 0x00900000 となる構成を
前提とした例となります。
6. おわりに
この記事では 2 コア目の起動方法についてご紹介しました。
実際に 2 コア目を起動する際には、remap レジスター、L2 Cache Address Filtering レジスター、cpu1startaddr レジスター、mpumodrst レジスターを CPU0 のプログラムコード内で設定する必要がありますので、この記事を参考にしていただければと思います。