私はザイリンクスの QEMU ビルドで実行されるプログラムに取り組んでいます。この質問にはzynqというタグが付けられていますが、実際には QEMU の Zynq MP、特に Cortex-R5 をターゲットにしています。
私のバックグラウンドはマイクロコントローラーと Cortex-M にあるため、これは大きな飛躍であり、慣れていない多くの機能 (MPU、AXI、追加のキャッシュ) があります。ハード ペリフェラルの 1 つ (低電力ドメイン) のペリフェラル レジスタにアクセスするドライバを作成しています。reginsert
これらのレジスタのビットへのアクセスを簡素化するために、関数を作成しました。
void reginsert(uint32_t base, uint32_t offset,
uint32_t mask, uint32_t data)
{
uint32_t volatile * reg = (uint32_t volatile *)(base + offset);
uint32_t regdata;
/* This section actually happens in a critical section for atomicity,
* but I've trimmed that out for brevity */
regdata = *reg;
*reg = (regdata & ~mask) | data;
/* End of critical section */
}
まったくエキサイティングな機能ではありません。私にとって、それはまた簡単です。
私は次のように関数を呼び出します:
/* Magic number provided by Xilinx, I don't actually plan to keep it as such a
* magical number, but for now while trying things to debug. */
reginsert(XPAR_PSU_UART_0_BASEADDR, XUARTPS_CR_OFFSET, 0x3C, 0);
追加情報:
#define XPART_PSU_UART_0_BASEADDR 0xFF000000
#define XUARTPS_CR_OFFSET 0x00000000
コードをステップ実行すると、この関数がレジスタのアドレスを として正しく計算する0xFF000000
ことがわかります。ザイリンクス SDK デバッガー (gdb ベース) で の値を表示すると、これを確認できますreg
。また、アセンブリをステップ実行すると、レジスタr3
に適切なアドレスが読み込まれていることがわかります。
実行が到達したとき:
regdata = *reg;
分解には次のものがあります。
ldr r3, [r3]
そして乗り込み0x00000000
ますr3
。0xFF000000
メモリ ビューを使用すると、 の値があることがわかります0x00000114
。変数ビューを見ると*reg
、同じ値 ( 0x00000114
) を持っていることがわかります。ローカル コピーがマスクされてから書き戻される行に進むと、次のような指示になります。
str r2, [r3] ; r3 has been reloaded with the register address,
; and r2 contains the read-modify-write data.
これを通り過ぎると、0x00000000
(正しい値ではありませんが) の値が書き込まれているはずですが、実際には (メモリまたは変数ビューを介して) 値が変更されていないことがわかります。これらのビューのいずれかで、値を手動で変更でき、正しく書き込まれます。
Zynq MP のバス アーキテクチャがこのビルドの QEMU でどの程度完全にエミュレートされているかはわかりませんが、シリコンにはデバッグ アクセス用とプロセッサ アクセス用に別々のメモリ ポートがあり、CPU を介してメモリにアクセスすることはありません。物事が異なってマッピングされる可能性。ただし、ザイリンクスのデモ コードは同じアクションを適切に実行します。
だから、私が試したことの要約:
- 逆アセンブリがレジスタの場所からロード/ストアする必要があることを確認します。
- 手順を実行して、周辺機器レジスタにアクセスするための CPU レジスタの値が正しいことを確認します。
- デバッガーを介して直接メモリと変数にアクセスしました。
- QEMU がペリフェラルをエミュレートすることをザイリンクス コードで確認します。
- MPU設定確認済み(領域は非共有、アクセス制限無し)
他に何を試せばいいのかわからず、基本的に困惑しています。QEMU は、少なくとも gdb インターフェイスを介して、ペリフェラル レジスタを適切にシミュレートしているように見えるので、CPU が読み書きするのはかなり簡単だと思います。QEMU を開発プラットフォームとして使用するなど、私にとって新しいことはたくさんあります。