0

私はザイリンクスの QEMU ビルドで実行されるプログラムに取り組んでいます。この質問にはというタグが付けられていますが、実際には 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ますr30xFF000000メモリ ビューを使用すると、 の値があることがわかります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 を介してメモリにアクセスすることはありません。物事が異なってマッピングされる可能性。ただし、ザイリンクスのデモ コードは同じアクションを適切に実行します。

だから、私が試したことの要約:

  1. 逆アセンブリがレジスタの場所からロード/ストアする必要があることを確認します。
  2. 手順を実行して、周辺機器レジスタにアクセスするための CPU レジスタの値が正しいことを確認します。
  3. デバッガーを介して直接メモリと変数にアクセスしました。
  4. QEMU がペリフェラルをエミュレートすることをザイリンクス コードで確認します。
  5. MPU設定確認済み(領域は非共有、アクセス制限無し)

他に何を試せばいいのかわからず、基本的に困惑しています。QEMU は、少なくとも gdb インターフェイスを介して、ペリフェラル レジスタを適切にシミュレートしているように見えるので、CPU が読み書きするのはかなり簡単だと思います。QEMU を開発プラットフォームとして使用するなど、私にとって新しいことはたくさんあります。

4

0 に答える 0