Save 37% off PRO during our Black Friday Sale! »

JTAGでarmプロセッサをデバッグする話/KernelVM Online4

JTAGでarmプロセッサをデバッグする話/KernelVM Online4

KernelVM online 4の発表資料です。

Bdd3fb3269e67bbc512f2530c409a926?s=128

Toshifumi NISHINAGA

November 20, 2021
Tweet

Transcript

  1. JTAGでarmプロセッサを デバッグする話 Toshifumi NISHINAGA (CV: ついなちゃん) @tnishinaga 2021-11-20 KernelVM Online

    4 https://speakerdeck.com/tnishinaga/kernelvm-online4 https://github.com/tnishinaga/kvmonline4_jtag 1
  2. ⾃⼰紹介 • 組み込みがすき • 修⼠卒社会⼈5年⽬くらいエンジニア • CVついなちゃんになった 2

  3. 本資料への質問 • 発表中にTwitter で投稿の最後に 「#kernelvm @tnishinaga」 をつけて質問してください • (すぐに回答できる質問であれば)発表と並⾏してお答えします 3

  4. 発表テキスト • ⾳声読み上げが聞き取りづらい⽅のため、発表テキストを公開 します。 • URLはtwitterでつぶやきます 4

  5. 感謝 • retrageさん • レビューしていただきありがとうございます! • 桜花ちゃん • Rustコードのアドバイスありがとうございます! •

    hikaliumさん • bingen開発ありがとうございます! • https://github.com/hikalium/bingen • なひたふさん • JTAGに関する様々な情報公開ありがとうございます! 5
  6. はじまり 6

  7. JTAGとは? • JTAG(ジェイタグ、英語: Joint Test Action Group)は、集積 回路や基板の検査、デバッグなどに使える、バウンダリスキャ ンテストやテストアクセスポートの標準 IEEE

    1149.1 の通称で ある。 • wikipedia(https://ja.wikipedia.org/wiki/JTAG)より引⽤ 7
  8. バウンダリスキャン • ICのピンの状態を取得したり、制 御する技術 • I/Oピンの⼿前にいるScan Cell (シフトレジスタ)の値を使って ポートの状態を読み書き制御する •

    参考 • http://www.tokudenkairo.co.jp/jta g/tech/techbas2.html 8 図はXJTAGのサイト「図1 JTAG対応デバイスの概念図」より引⽤ https://www.xjtag.com/ja/about-jtag/jtag-a-technical-overview/
  9. CPUデバッグ gdb OpenOCD JTAG Interface Target gdb server USB JTAG

    9
  10. イメージの乖離。理解の溝。 • 以下2つがJTAGを使ってできることは知っている • ICのピンの状態の取得、制御 • CPUデバッグ • しかし両者のイメージが乖離している •

    ICの状態調べる技術でどうやってCPUデバッグするの……? 10
  11. CPUデバッグ gdb OpenOCD JTAG Interface Target gdb server USB JTAG

    ここで何をやっている? 11
  12. イメージの乖離。理解の溝。 • 以下2つがJTAGを使ってできることは知っている • ICのピンの状態の取得、制御 • CPUデバッグ • しかし両者のイメージが乖離している •

    ICの状態調べる技術でどうやってCPUデバッグするの……? • 本発表ではJTAGでCPUデバッグする⽅法を調べ、この乖離を 縮める 12
  13. 本発表の進め⽅ • JTAGでCPUデバッグを⾏う上で、作者が疑問に思ったことの 解決を⽬標にしつつ調査していく • 都度Rustのプログラムを作って動作確認する • 作者はプログラムを作るために調査するのが⼀番理解が深まる性質の ため 13

  14. 本⽇の⽬標 • JTAGの通信は何をやっているの? • JTAGインターフェースに必要な機能はなに? • どうやってCPUデバッグするの? • レジスタ値の取得はどうやるの? •

    メモリの読み書きはどうやるの? • breakpointはどうやって仕掛けるの? • step実⾏はどうやるの? 14 ※: 灰⾊部は未完
  15. 概要 15

  16. CPUレジスタ取得までの概要と資料 16 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  17. 参考資料 • JTAG関連 • MITOUJTAGのサイト • ⽇本語で最もJTAGを詳しく解説しているサイト (⼤変お世話になりました) • http://www.tokudenkairo.co.jp/jtag/whatisjtag.html

    • http://www.tokudenkairo.co.jp/jtag/tech/index.html • Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, Version F • https://developer.arm.com/documentation/ihi0031/latest • Arm® Architecture Reference Manual Armv8, for A-profile architecture, Version G.b • https://developer.arm.com/documentation/ddi0487/gb/ 17
  18. JTAG 18

  19. この節で説明する部分 19 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  20. 再掲: JTAGとは? • JTAG(ジェイタグ、英語: Joint Test Action Group)は、集積 回路や基板の検査、デバッグなどに使える、バウンダリスキャ ンテストやテストアクセスポートの標準

    IEEE 1149.1 の通称で ある。 • wikipedia(https://ja.wikipedia.org/wiki/JTAG)より引⽤ 20
  21. JTAG対応ICの概要 • 以下で構成されている • テスト信号接続⽤のポート(TAP) • TDI等 • TAP制御⽤のTAPコントローラー •

    JTAGテスト⽤レジスタ • Instruction Register等 • バウンダリスキャン⽤のセル • 各ピンの状態を取れる • (本資料では扱わない) 21 図はXJTAGのサイト「図1 JTAG対応デバイスの概念図」より引⽤ https://www.xjtag.com/ja/about-jtag/jtag-a-technical-overview/
  22. Test Access Port(TAP)の信号線 22 • TMS(Test Mode Select) • TAP

    State Machineの状態遷移 を⾏うコマンド線 • TCK(Test Clock) • 信号の基準になるクロック • ⽴ち上がりエッジ • TDI(Test Data In) • インターフェース側からデバイ スに送る信号 • TDO(Test Data Out) • デバイスからインターフェース 側に送る信号 JTAG Interface Target TMS TCK TDI TDO TMS TCK TDI TDO
  23. その他信号線(オプション) • TRST • TAPステートマシンをリセットするためのピン • (※これを使わないとリセットできないターゲットがいるらしい) • SRST •

    システムリセットを⾏うためのピン • 対応していないターゲットもある • RTCK • TCKの周波数をターゲットの動作周波数に合わせるために使うピン • ARMコア⽤の機能 • Vref • ターゲットの電源電圧を取得するためのピン。信号線ではない。 • 信号電圧を決めるために使う 23 ※ http://www.tokudenkairo.co.jp/jtag/adv2018/02.php
  24. テスト⽤レジスタとの値交換⽅法 • TDIとTDOの間にあるシフト レジスタ経由で送受信する • レジスタ⻑や中⾝はTAPコン トローラの状態やセットした 命令に依存する • TDIとTDOをつなぐと複数デ

    バイスを数珠つなぎにできる • Raspberry Pi 3B+の接続先は1 つのみ 24 TCK TDO TDI JTAG chain for programmable devices, Vindicator, CC-BY https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A1%E3 %82%A4%E3%83%AB:Jtag_chain.svg
  25. JTAGテストの通信概要 • JTAGテスト時の通信は基本以下2つの操作の繰り返し • 命令セット(Instruction Register(IR)に書き込む) • データ読み書き(Data Register(DR)を読み書きする) •

    DRの中⾝はセットした命令に依存 • 各操作はTAPステートマシンを制御して⾏う 25
  26. TAP State Machine 26 • 概要 • TAPコントローラーの持つス テートマシン •

    TMS(とクロック)で制御する • 状態遷移 • 命令系(IR)とデータ系(DR)に分 かれている • Shift-*でレジスタの値を交換し、 Update-*で⼊⼒を確定する • TMSを5回以上送るとどの時点 からでもResetに⾏ける 図は http://www.tokudenkairo.co.jp/jtag/tech/techmid1_4.html より引⽤
  27. Instruction Register(IR) • 命令を⼊れるレジスタ • レジスタ⻑は不定 • ARMの場合は4または8bit • 2種類の命令がある

    • パブリック命令 • IEEE1149.1で決められている命令 • 必須命令 と 実装依存のオプション命令 がある • プライベート命令 • 各社が独⾃に作った命令 • 仕様が公開されてることもされていないこともある • (CPUデバッグでは主にプライベート命令を使う。詳しくは後述) • 命令に対応するビットは設計依存 • BYPASSとEXTESTのみ固定 27
  28. Data Register(DR) • データの⼊っているレジスタ • レジスタ⻑は命令依存 28

  29. パブリック命令の例 • BYPASS • 必須命令 • どのデバイスでも全ビットHでBYPASSになる • DRを1bitにしてTDIの⼊⼒をそのままTDOにバイパスする •

    ターゲット以外にはBYPASSをセットしておくと安全 • IDCODE • オプション命令 • TAP識別⽤IDをDRにセットする • TAPステートをResetにするとIRにIDCODE命令がセットされる • Reset後にDRを読み出すとIDCODEが取れる 29
  30. 例: IRに命令を書き込む • 0 : Reset -> Run • 1

    : Run -> Select DR • 1 : Select DR -> Select IR • 0 : Select IR -> Capture IR • 0 : Capture IR -> Shift IR • TMS:0のままTDIから命令ビット列 を送り込む • 最終ビットはTMS:1にしながら送 る(Shift IR -> Exit1 IR) • 1: Exit1 IR -> Update IR • 0: Update IR -> Run 30
  31. 例: IDCODE取得 • やること • IRにIDCODEをセットする • ARMのIDCODE命令は0b1110 • DRからIDCODEを読み出す

    • ARMの場合は32bit 31
  32. IDCODE命令のセット 1. Shift-IRステートに進める 2. TDIから0b1110を送る • LSB first • 4bit⽬はTMSをHにしながら送る

    3. Update-IRを経由してRunステートに戻る • Resetまで⾏くとセットされた命令が消えるので注意 32
  33. テスト環境 • JTAG Interface • Olimex ARM-USB-TINY-H • JTAG接続対象 •

    Raspberry Pi 3B+ 33 JTAG Interface Target JTAG
  34. JTAG InterfaceとRaspberry Piの接続 34 JTAG Interface Target TMS TCK TDI

    TDO TRST IO27 IO25 IO26 IO24 IO22
  35. Raspberry Piの設定 • config.txt に以下を書き込んでJTAGポートを有効化する • enable_jtag_gpio=1 • 64bit化もする •

    arm_64bit=1 35
  36. IDCODE命令のセットの波形 36

  37. DRからIDCODEを読み出す 1. Shift-DRステートに進める 2. TDOから32bit読み出す • TDIはLにする • LSB firstで送られてくる

    • 32bit⽬はTMSをHにしながら読み込む 3. Update-DRを経由してRunステートに戻る 37
  38. DR読み込みの波形 38

  39. この節のまとめ • JTAGはCPUデバッグ等に使われるIEEE1149.1標準の通称 • 信号線は7本(オプション含む) • TCK, TMS, TDI, TDO,TRST,

    SRST, RTCK, (Vref) • TAPコントローラーはステートマシンをもち、TMSで制御する • IRで命令発⾏、DRでデータをやり取りする • パブリック命令とプライベート命令がある • CPUデバッグは主にプライベート命令を使う(後述) 39
  40. JTAG Interface 40

  41. この節で説明する部分 41 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  42. JTAG Interface • JTAGの信号を出すための物理イン ターフェイス • GPIOが7ポート程度あればJTAG Interfaceになれる • 速度はGPIOスピードに依存

    • ⾼速通信するためのJTAG専⽤機能を 持つインターフェースもある 42 ARM-USB-TINY-H
  43. JTAG Interface例 • ARM-USB-TINY-H • お値段5000円 • FTDI FT2232H 搭載

    • https://strawberry- linux.com/catalog/items?code=15045 43 ARM-USB-TINY-H
  44. FT2232H • FTDI社の2回路USBシリアル/パラレル変換IC • モード切り替えで各ピンの機能が変わる • チップ単体は700円程度 • 半導体不⾜で今は買えない 44

  45. FT2232のモード • SyncBitBang • ⼀部ピンをGPIOとして使えるモード • ピン状態のWrite時に同期してReadが⾏われる • (JTAG通信を⾏うにはMPSSEと⽐較して)低速だけど制御は簡単 •

    MPSSE • SPI,JTAG等の通信を半⾃動で⾏うモード • コマンドを送ると通信を⾏い、⼊⼒を返す • (SyncBitBangと⽐較して)⾼速(max 30MHz) 45
  46. FT2232HLのピン配置 • A*BUSとB*BUSの2回路搭載 • 各BUSはモードによって機能が 変わる • SyncBitBang(Sync-BB) • *DBUSがGPIOになる

    • MPSSE • *DBUSに各通信⽤ピンが割り当てら れる • *DBUS4以降と*CBUSはGPIO 46 図はdatasheetより引⽤ http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf
  47. ARM-USB-TINY-Hの配線 FT2232 JTAG ADBUS0 TCK ADBUS1 TDI ADBUS2 TDO ADBUS3

    TMS ADBUS7 RTCK ACBUS0 TRST ACBUS1 SRST 47
  48. safe-ftdi • FTDIチップと通信するlibftdiライブラリのrust wrapper • https://github.com/cr1901/safe-ftdi • SyncBitBang, MPSSEどちらにも対応 48

  49. safe-ftdiを 使った制御 サンプル (SyncBB) 49

  50. 実⾏結果 50

  51. この節のまとめ • JTAG InterfaceはJTAG信号をやり取りするインターフェース • JTAG InterfaceはGPIOが7つあれば作れる • FT2232を使うとUSB接続のJTAG Interfaceが作れる

    • rustならsafe-ftdiでftdiデバイスを扱える 51
  52. ARM Debug Interface(ADI) v5.0 52

  53. この節で説明する部分 53 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  54. ARM Debug Interface(ADI) • Armのデバイスをデバッグするための インターフェース規格 • TAP以降から、メモリ空間にアクセス するまでの仕組みを定義 •

    以下のインターフェースのどちらかを ⽤いて制御する • JTAG • Serial Wire Debug(SWD) • JTAGよりデバッグ線の本数が少ない • なひたふさんの記事が詳しい http://www.tokudenkairo.co.jp/jtag/adv2 018/08.php 54
  55. ADIで定められていること(抜粋) • Debug Port(DP)の仕様 • サポートするパブリック命令とプライベート命令 • プライベート命令の仕様 • Access

    Port(AP)の仕様 • Memory Access Port(MEM-AP)の仕様 • ROM Tableの仕様 56
  56. DPとAP • Debug Port(DP) • AP選択やデータのやり取り をするポート • DPACC命令でアクセスする •

    Access Port(AP) • バス等へのアクセスポート • APACC命令でアクセスする • Debug Access Port(DAP) • DPとAPをセットにしたもの 57 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, A1-25 より引⽤
  57. MEM-AP • デバッグ⽤のメモリ空間にア クセスするAP • APの⼀種 • メモリマップされたデバッグ ユニットのレジスタアクセス 等に使う

    58 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, C2-151 より引⽤
  58. (DP|AP)ACC命令 • DPまたはAPにアクセスするプライ ベート命令 • DPACC: 0b1011, APACC: 0b1010 •

    DRは35bitの共通フォーマット • 送信 • [34:3] : data • [2:1] : レジスタオフセットアドレスの[3:2]bit • [0] : Read(1) or Write(0) • 受信 • [34:3] : 前回発⾏した命令の返答データ • [2:0] : 前回発⾏した命令のACK 59 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, B3-97 より引⽤
  59. (DP|AP)ACCを⽤いたレジスタ読み書き • レジスタの読み書きは命令を2度発⾏して⾏う(※) • 1度⽬ • 書き込み: RnWを0にしてdataをDRに送る • 読み込み:

    RnWを1にしてDRに送る • 2度⽬ • 読み出すと0を返すDP RDBUFFレジスタを読み出して各返答を取得する • ACKの結果によっては再度命令を発⾏する • 書き込み: DRにACKがセットされているので読み込む • 読み込み: DRに読みだした値とACKがセットされているので読み込む 60 ※パイプライン処理もできる
  60. ACKの種類 • OK/FAULT: 0b010 • 発⾏された命令の実⾏が完了したことを⽰す • エラーが起きてないかはDP CTRL/STATレジスタを参照 •

    WAIT: 0b001 • 前回発⾏した命令がまだ完了していないことを⽰す 61
  61. Debug Portレジスタたち • CTRL/STAT • 電源管理制御や転送状態確認等を⾏うレジ スタ • SELECT •

    APやAP内のバンクを選択するレジスタ • RDBUFF • 読み出すと0を返すレジスタ • *ACC命令の返答を得る際に使う 62 ※DPバージョンによってレジスタ数やアドレスが変わる 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, C2-151 より引⽤
  62. DP CTRL/STATレジスタ • *PWRUPREQ, *PWRUPACK • システムやデバッグブロックの電源をONにするビット • 状態は*PWRACKの⽅で確認 •

    *PWRUPREQを両⽅ONにしないとAPアクセスができない • その他 • 通信モードの選択や通信エラー状態等を確認する 63 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, B2-56 より引⽤
  63. DP SELECTレジスタ • APSEL • APACC命令でアクセスするAPを選択する • APBANKSEL • APACC命令でアクセスするAPのバンク(オフセットの上位4bit)を設定する

    • DPBANKSEL • DPバージョンによってはアクセス先のレジスタが変わる 64 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, B2-70より引⽤
  64. 主要なAPレジスタたち その1 • CSW(0x00) • デバッグアクセス許可や転送データサイズ等を設定する32bitレジスタ • TAR(0x04 - 0x08)

    • BDレジスタ等でアクセスするメモリアドレスを指定する32bitレジス タ • 64bitアドレス指定はloとhiに分けて⾏う • BD0-3(0x10 - 0x1C) • TAR[31:4]アドレスの中⾝を読み書きする32bit x 4つのレジスタ 65
  65. 主要なAPレジスタたち その2 • BASE(0xF0, 0xF8) • ROMテーブルやデバッグコンポーネントのベースアドレスの⼊った 32bitレジスタ • 64bitアドレス指定はloとhiに分けて⾏う

    • IDR(0xFC) • APの識別IDが書かれた32bitレジスタ 66
  66. AP CSW • DbgSwEnable • デバッグアクセスを許可する • 無効時はAPレジスタ返答が変になる • DeviceEn

    • APが有効なときに1になる。Read Only 67 図は Arm® Debug Interface Architecture Specification ADIv5.0 to ADIv5.2, C2-180より引⽤
  67. Tips: DP/APの初期設定 • DP CTRL/STATレジスタで以下を1にする • CSYSPWRUPREQ • CDBGPWRUPREQ •

    AP CSWレジスタで以下を1にする • DbgSwEnable 68
  68. 例: AP IDR(0xFC)を読み出す • 前提条件 • AP番号は0 • DPバージョンはDPv0 •

    ⼿順 • DP SELECTでAPを0、AP Bankを0xF(※)に設定する • AP IDRを読み出す 69 ※ APレジスタアドレスの上位4bitはSELECTのバンクで設定する
  69. 例: AP IDR(0xFC)を読み出す 70 DPACC: APSEL: 0x00, APBANKSEL: 0x0F, DPBANKSEL:

    0x00, A: SELECT(0b10), RnW: 0 debugger target Unknown Ack: OK/FAULT DPACC: A: RDBUFF(0b11), RnW: 1 DATA: 0, Ack: OK/FAULT APACC: A: IDR(0b11), RnW: 1 DATA: 0x24770002, Ack: OK/FAULT DPACC: A: RDBUFF(0b11), RnW: 1
  70. 例: AP IDR(0xFC)を 読み出すコード 71

  71. 実⾏結果 72 • AP IDRレジスタから0x2477002が正しく得られた • (openocdでdap info 0した結果と⽐較すると結果が正しいかわかる)

  72. 例: MEM-APを使ったメモリアクセス • MEM-APを使ってデバッグユニットのMPIDRレジスタにアク セスしてみる • MEM-APでメモリマップされたレジスタにアクセスする⼿順の 基本は以下 • AP

    TARでアクセス先のメモリアドレスをセット • AP BDレジスタでメモリを読み書き • (上記⼿順の合間にDP SELECTでAP選択とバンク選択が⼊る) 73
  73. 例: MPIDR取得 コード 74

  74. 実⾏結果 • MIDRの値が得られた • (うまく⾏ってない時は前回書き込んだ値や0が返ってくる) 75

  75. ROM Table • MEM-APのメモリにマップされてるコンポーネントの情報が書 かれているテーブル • ここに書かれてないものもある • テーブルの開始アドレスはBASEADDRレジスタが⽰す •

    (調べきれてないので解説はここまで) 76
  76. 例: ROMテーブルの確認 • openocd の ”dap info 0” コマンドで調べられる 77

    > dap info 0 (省略) ROMTABLE[0x0] = 0x10003 Component base address 0x80010000 Peripheral ID 0x04004bbd03 Designer is 0x23b, ARM Ltd Part is 0xd03, Cortex-A53 Debug (Debug Unit) Component class is 0x9, CoreSight component Type is 0x15, Debug Logic, Processor
  77. この節のまとめ • DAPとは(DP | AP)ACCプライベート命令を使ってやり取りす る • デバッグ制御⽤のレジスタはメモリマップされている • アクセスはMEM-APの仕様に沿って⾏う

    • MEM-APへのアクセスは基本以下の2⼿順で⾏う • TARでメモリアドレス設定 • BDでメモリアクセス 78
  78. CPU Debug 79

  79. この節で説明する部分 80 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP
  80. CPU Debug • Break pointやレジスタ書き換え等を⾏う機能 • Debug UnitとしてメモリマップされているレジスタをMEM- AP経由で制御して使う 81

  81. CPU Debug制御の⽅法 • 各コアのDebug unitとCTIのレジスタを制御して⾏う • Debug unitのレジスタはMEM-AP経由でアクセスする • レジスタがAPのメモリアドレス空間にマップされている

    82
  82. Debug unit及びCTIのベースアドレス • openocd の ”dap info 0” コマンドで調べられる •

    CTIのアドレスは出てこないのでネットの情報を調べる • 各コアのベースアドレス( 4 core ) • Debug unit • [0x80010000, 0x80012000, 0x80014000, 0x80016000] • CTI • [0x80018000, 0x80019000, 0x8001a000, 0x8001b000] 83
  83. レジスタ取得までの準備 • 初期化 • OS Lockの解除 • プロセッサをHaltしてDebug modeに する

    • HDEの有効化 • CTIからのHalt発⾏ • プロセッサからレジスタの値を取得す る 84
  84. OS Lockの解除 • 特定の値を書き込むとデバッグレジスタをロックできる機能 • 参考 • https://developer.arm.com/documentation/ddi0379/a/Debug-Register- Reference/Operating-system-save-and-restore-registers/OS-Lock-Access- Register--OSLAR-

    • OSLAR_EL1レジスタに0を書き込んで初期化 • 忘れるとレジスタの値が書き換わらなくてハマる 85
  85. プロセッサをHaltしてDebug modeにする • HDEビットでHalting debug Modeを有効化する • Cross Trigger Interface経由で

    プロセッサコアをHaltする 86
  86. プロセッサをHaltしてDebug modeにする • HDEビットでHalting debug Modeを有効化する • Cross Trigger Interface経由で

    プロセッサコアをHaltする 87
  87. Halting Debug Modeの有効化 • CPUレジスタアクセス等を⾏うには以下の2つが必要 • プロセッサをHaltする • プロセッサをdebug stateにする

    • Halting Debug有効時、Halt命令でdebug modeに⼊る • Halting Debug有効化はEDSCRレジスタのHDEビットで制御 88
  88. EDSCRレジスタ • デバッグステート取得と制御⽤のデバッグレジスタ • 主要なフィールド • HDE: Halting debugを有効にする •

    RW: ELとExecution stateを確認する • STATUS: Debug stateを確認する 89 図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H9-7584 より引⽤
  89. プロセッサをHaltしてDebug modeにする • HDEビットでHalting debug Modeを有効化する • Cross Trigger Interface経由で

    プロセッサコアをHaltする 90
  90. Cross Trigger Interface(CTI) • Halt等のTrigger eventをプロセッサに 送るためのインターフェース • まだあんまり詳しくない 91

    図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H5-7422 より引⽤
  91. プロセッサコアのHalt • CTI経由でプロセッサにHalt指⽰を送る とHaltする • Halt指⽰の送り⽅ • CTIGATE[0]を0にしてch0のイベントを CTMに流さないようにする •

    CTIOUTEN0[0]を1にしてch0イベントに対 してDebug requestトリガーがイベントを ⽣成するようにする • CTIAPPPULSE[0]を1にしてチャンネルイベ ントをch0に⽣成する • 詳細はARMv8アーキテクチャマニュアルの 「Example H5-1 Halting a single PE」参照 92 図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H5-7422 より引⽤
  92. 検証: コアをDebug stateにする • HDEを有効にする • CTIからHaltを発⾏する • EDSCRレジスタのRWフィールドを確認 •

    成功すれば0b110x(Debug state) になる • 参考 • https://developer.arm.com/documentation/ddi0595/2021-03/External- Registers/EDSCR--External-Debug-Status-and-Control-Register 93
  93. HDE 有効化 94

  94. Halt 95

  95. 実⾏結果 • HDEが1になった • RWが0b1100(Debug State)になっている 96

  96. CPUレジスタ値アクセスのやり⽅ • 基本的には以下の2つのデバッグレ ジスタを使う • EDITR • DBGDTR 97

  97. DBGDTR • デバッガとプロセッサコア間で データを交換するためのレジスタ • 同⼀レジスタにデバッガからもコ ア側からもアクセスできる • コア側からはシステムレジスタとし てアクセスする

    98 図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H4-7404 より引⽤
  98. EDITR • デバッガから命令のopcodeを書き込むと コアで実⾏するレジスタ • 実⾏完了はEDSCRのITEビットでチェック • opcodeはLittle Endianのバイナリで書き 込む

    99 図は Arm® Architecture Reference Manual Armv8, for A-profile architecture, H4-7404 より引⽤
  99. 例: CPUレジスタ値の取得 • ⽬的 • レジスタx1の値をデバッガで読み出す • ⼿順 • EDITRに

    “msr DBGDTR_EL0, x1” のopcodeを書き込む • プロセッサが命令を実⾏し、DBGDTRにx1の値を書き込む • DBGDTRから値を読み出す 100
  100. Raspberry Piで動かすプログラム 101

  101. InitとHalt 102 • フラグ初期化を追加

  102. 命令実⾏と読み出し 103 • x1レジスタの値をDBGDTRに ⼊れる命令を発⾏ • msr DBGDTR_EL0, x1 •

    DBGDTRをデバッガで読み出す • 64bit値はTX,RXから32bitずつ取 り出す ※bingenは命令からopcodeを⽣成するcrate(@hikaliumさん製)
  103. 実⾏結果 • x1の値(0x01の繰り返し)が取得できている 104

  104. この節のまとめ • CPU DebugはDebug unitとCTIを使う • レジスタ取得は以下の2⼿順で⾏う • 命令実⾏ •

    システムレジスタ経由で値を交換 105
  105. 今⽇のまとめ 106

  106. CPUレジスタ取得までのまとめ 107 JTAG Interface TAP DAP Debug Unit Cross Trigger

    Interface Processor Core Halt opcode data TMS TCK TDI TDO DPACC APACC Memory mapped Register access Processor IEEE 1149.1 Arm Debug Interface Architecture Specification ARMv8 Arm Architecture Reference Manual MEM-AP