FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-Vのトレースフォーマット仕様書が公開されたので読んでみる(5. パケットフォーマット)

RISC-V トレースフォーマットの勉強。続き。

github.com

github.com

1章ずつ、翻訳ではなく日本語でサマライズしていく形式で進めていく。


5. トレースエンコーダの出力パケット

トレースエンコーダでは、以下の情報を含まなければならない。

  • パケットタイプ
  • パケットのバイト長
  • パケットのペイロード

UltraSoCのメッセージインフラストラクチャとArmのトレースバスについて例を示す。図5.1はUltraSoCのインフラストラクチャである。

  • ヘッダバイトには5ビットのフィールドでペイロードのバイト長を示している。次の2ビットは「フロー」(宛先ルーティングID)、そして1ビットでオプションの16bitタイムスタンプが付加されているかを示している。
  • インデックスフィールドはパケットのソースを示している。ビット幅はシステム依存であり、トレースエンコーダによって出力される初期値はゼロである。
  • オプションの2バイトのタイムスタンプが含まれる。
  • パケットのペイロードが含まれる。

trace_packet_format

Arm Trace Bus(ATB)ではパケットのソースはATIDバスフィールドによって表現され、「フロー」に相当するものは存在しない。

  • 5ビットのフィールドでペイロードのバイト数を表現する。
  • 1ビットのフィールドで16bitタイムスタンプが付加されているかどうかを示す。
  • オプションの2バイトのタイムスタンプ
  • パケットのペイロード

5.1 Format 3 パケット

Format 3パケットは同期操作に使用される。コンテキストとサポート情報を通知するために使用される。4つのサブフォーマットが含まれる。

5.2 Format 3 サブフォーマット0:同期

命令を識別するためのすべての情報が入っている。最初にトレースされる命令のために送られる。再同期タイマにより再同期がスケジュールされる場合にも送信される。

フィールド名 ビット幅 説明
format 2 11(sync) : 同期
subformat 2 00(start) : トレース開始、もしくは再同期
branch 1 分岐命令を示しており、分岐が成立した場合には場合は0を設定する。分岐命令ではないか、分岐が成立しなかった場合には1を設定する。
privilege privilece_width_p 命令のPrivilegeレベルを示す
context context_width_pもしくはif_context_pが1の場合は0 命令コンテキスト
address iaddress_width_p - iaddress_lsb_p 完全な命令アドレス。アドレスのアライメントはiaddress_lsb_pによって決定される。

5.2.1 Format 3 Branchフィールド

分岐命令の場合、BranchフィールドビットはTaken/Not Takenを示す。このビットを削除することで効率は若干向上し、分岐の状態は「キャリーオーバー」され次のte_instパケットに引き継がれる。しかしこのような方針を取った場合には問題が発生することがある。最初のトレース命令がジャンプ命令で、その直後に例外が発生したものとする。Format 3パケットは2つの連続した命令で生成される。2番目のパケットには分岐のマップが含まれておらず、従って最初の分岐命令の結果を通知する方法がない。

  • 同じサイクルに2つのパケットを生成する必要があり、エンコーダの複雑性が上がってしまう。
  • トレースを生成するためのアルゴリズムが複雑化してしまう。

5.3 Format 3 サブフォーマット1 : 例外

このパケットにも命令を完全に識別するための情報が含まれている。このパケットは例外後に通知され、例外ハンドラ亜土れうを通知と同様に、例外要因や例外発生元の命令情報についても含まれる。

暗黙的例外モードが有効である場合、アドレスは除外される。

フィールド名 ビット幅 説明
format 2 11(sync) : 同期
subformat 2 01(例外) : 例外要因及びトラップハンドラアドレス
branch 1 分岐命令を示しており、分岐が成立した場合には場合は0を設定する。分岐命令ではないか、分岐が成立しなかった場合には1を設定する。
privilege privilece_width_p 命令のPrivilegeレベルを示す
context context_width_pもしくはif_context_pが1の場合は0 命令コンテキスト
ecause ecause_width_p 例外要因
interrupt 1 割り込み
address iaddress_width_p - iaddress_lsb_p 完全な命令アドレス。アドレスのアライメントはiaddress_lsb_pによって決定される。
tvalepc iaddress_width_p ecauseが2かつinterruptが0(不定命令例外)の場合は例外アドレス、それ以外の場合はトラップ値

5.3.1 Format 3 tvalepcフィールド

このフィールドは不定命令例外のアドレスもしくはそれ以外の時はトラップ値が格納される。これは実行に失敗した命令のアドレスはすべての場合において通知されることを示す。トラップ値はハードウェアブレークポイントにおいてもトリガされたアドレスが格納される。またはページフォルトおよび命令フェッチ・ロード・ストアミスアラインについても同様であるが、不定命令例外についてはオペコードが格納される。

5.4 Format 3 サブフォーマット2 : コンテキスト

このパケットにはコンテキストの情報のみが含まれる。このパケットはコンテキストの切り替えが発生した場合に通知される。

フィールド名 ビット幅 説明
format 2 11(sync) : 同期
subformat 2 10(例外) : コンテキスト変更
privilege privilece_width_p 命令のPrivilegeレベルを示す
context context_width_p 命令コンテキスト

5.5 Format 3 サブフォーマット : サポート

このパケットではデコーダをサポートするための情報が含まれている。

  • トレースの有効無効
  • オペレーティングモードの変更
  • 1つ以上のパケットが送信できなかった(例えば、パケット転送インフラストラクチャによるバックプレッシャによる)

5.5.1 Format 3 サブフォーマット3 qual_status field

トレースが終了すると、エンコーダは最後にトレースされた命令のアドレスを報告し、これにFormat 3 サブフォーマット3(サポート情報)パケットが続く。トレースが終了したことを示すために、ended_repends_updの2つのコードが提供されている。これは、セクション5.6.2で詳細に説明されているものとまったく同じ曖昧なケースに関連しており、原則として、そのセクションで説明されているメカニズムを使用して、最後にトレースされた命令がlooplabelにあるときを明確にすることができる。

  • ended__rep トレースが終了しない場合、前のパケットが送信されていないことを示す。これは最初のループイタレーションのループラベルを実行した後トレーシングがストップしたことを示す。

  • ended__upd 推論不可能なPCジャンプにより、とりあえず前のパケットが発行されたことを示す。これは2番目のループイタレーションの後にトレースがストップしたことを示す。

フィールド名 ビット幅 説明
format 2 11(sync) : 同期
subformat 2 11(例外) : デコーダのサポートパケット
enable 1 エンコーダが有効の場合1が設定される。
encoder__mode N トレースアルゴリズムを指定する。詳細とビット数は依存している。下剤では分岐トレースモードのみが定義されており、値は0である。
qual__status 2 資格情報を示す。
00(no__change) : フィルタの資格は変更なし。
01(ended__rep) : 資格が終了する。これまでのte__instが明示的に転送され最後の資格命令であることを示す。
10(trace__lost) : 1つ以上のパケットをロストした。
11(ended__upd) : 資格が終了する。過去のte__instはとりあえず送信される。
options N ランタイムのコンフィグレーションビットの値である。ビット数は実装に依存する。
- シーケンシャルな予測可能ジャンプ:シーケンシャルな予測化のうなジャンプのターゲットをレポートしない
- 暗黙的なリターン:リターンアドレスを通知しない
- 暗黙的な例外:format 3のアドレスを通知しない、トラップベクタをecauseから決定できる場合に、サブフォーマット1のte__instパケットを送信しない。

5.6 Format 2 パケット

このパケットには命令アドレスしか含まれず、命令のアドレスを通知しなければならないときだけ使用される。

フィールド名 ビット幅 説明
format 2 10(addr-only) : アドレス差分および分岐命令の情報は含まれない。
address iaddress_width_p - iaddress_lsb_p 命令アドレス差分
notify 1
updiscon 1
irreport 1
irdepth return_stack_size_p + (return_stack_size_p > 0 ? 1 : 0) + call_counter_size

5.6.1 Format 2 notifyフィールド

このフィールドは殆どの場合はaddressフィールドのMSBと同じ値が設定される。trigger[2]入力が1に設定されたことにより通知リクエストが行われた結果をカバーするためのビットである。

5.6.2 Format 2 notify と updisconフィールdお

このビットは殆ど圧縮されて効率に影響はない。notifyは殆ど場合addressフィールドのMSBと同一であり、updisconは通常はnotifyの同じである。このビットはデコーダソフトウェアが曖昧性によりプログラムを再構成することができなかった場合に使用される。以下のようなコードを考える。

looplabel - 4: opcode A
looplabel : opcode B
looplabel + 4: opcode C
:
looplabel + N: JALR # Jump to looplabel

これは、次の反復への間接的なジャンプバックを伴うループです。これは推測不可能な不連続であり、フォーマット 1 または 2 のパケットで報告されます。しかし、ループへの最初のエントリは、looplabel 4 の命令からのフォールスルーであり、明示的には報告されないことに注意してください。これは、プログラムの実行パスを再構築する際に、ループラベルのアドレスが2回発生することを意味します。一見すると、デコーダは、1 回目にループラベルに到達したときに、これが実行の終わりではないと判断できるように見えますが、それは前の命令が不連続を引き起こすような命令ではなかったからです。したがって、JALRに到達するまで実行パスの再構築を続けることができ、そこからlooplabelでのオペコードBが最後のリタイア命令であることを推論することができます。しかし、このアプローチがうまくいかない状況もあります。例えば、looplabel + 4 に例外がある場合を考えてみましょう。この場合、デコーダは、エンコーダからの追加情報がないと、これが 1 回目と 2 回目のループの繰り返しで発生したかどうかを判断できません。これが updiscon フィールドの目的です。詳細はこちらを参照してください。

  1. コードは1回目のループの繰り返しの最後まで実行され、エンコーダはJALRに続いてフォーマット1/2でlooplabelを報告し、2回目のループを実行し続けます。 この場合、 updiscon == notify となります。次のパケットはフォーマット1/2になります。
  2. コードは 1 回目のループの反復の最後まで実行され、looplabel にジャンプしますが、2 回目の反復で looplabel + 4 で例外、特権の変更、または再同期が発生します。この場合、エンコーダはJALRに続いてフォーマット1/2でlooplabelを報告し、updateiscon == !notifyで次のパケットはフォーマット3になります。
  3. looplabelの1回目の実行直後に例外が発生します。この場合、エンコーダはフォーマット 0/1/1/2 を使用して、updiscon == notify でループラベルを報告し、次のパケットはフォーマット 3 となります。
  4. Hartは、エンコーダにlooplabelでの命令の破棄を通知するように要求します。この場合、エンコーダはlooplabelの1回目の実行をnotify == !address[MSB]で報告し、それ以降の実行をnotify == address[MSB]で報告します(JALRの結果、いずれにしても報告されていたでしょうから)。