ciniml / rust-dap

CMSIS-DAP Rust implementation
Apache License 2.0
88 stars 10 forks source link

Initial support for JTAG interface #32

Closed tnishinaga closed 2 years ago

tnishinaga commented 2 years ago

やりたいこと

やったこと

動作確認方法

JTAG

  1. boards/rpi_pico ディレクトリ以下にて cargo run --features jtag でビルドしたコードをRaspberry Pi Picoに書き込む
  2. boards/rpi_pico/src/main.rs のピン定義を参考に、JTAG接続可能なデバイスのJTAGポートに接続する
    • IO11 -> TMS
    • IO18 -> TCK
    • IO10 -> TDI
    • IO19 -> TDO
    • IO9 -> nTRST
    • IO20 -> nSRST
  3. openocd -f interface/cmsis-dap.cfg -f <board name>.cfg のようにしてOpenOCDを立ち上げる
  4. telnet localhost 4444 でopenocdに接続し、reg コマンドでレジスタ一覧が表示されるのを確認する

SWD

bitbang

  1. boards/rpi_pico ディレクトリ以下にて cargo run --features swd,bitbang でビルドしたコードをRaspberry Pi Picoに書き込む
  2. デバッグ対象のPicoをもう1台用意し、IOとSWDを接続する
  3. openocdを動かし、DPが見つかるのを確認する
openocd -f interface/cmsis-dap.cfg \
-c 'transport select swd' \
-c 'adapter speed 1000' \
-c 'swd newdap rp2040.core0 cpu -dp-id 0x01002927 -instance-id 0' \
-c 'dap create rp2040_0.dap -chain-position rp2040.core0.cpu'

pio

cargo run --features swd でビルドする以外はbitbangと同様。

(私の環境ではPIOがうまくテストできないため、未検証です) PIOも動きました

ciniml commented 2 years ago

おっ、JTAGきた! なんかターゲットあったかな… ESP32-C3とか、GD32Vとかか。

ちなみにピン配置がこれなのって、既にボード作ってたりしますか? うちのデバッグボードはJTAG機能ないんですけど、Cortex-M Debug Connectorを付けてあるので、SWD共用のピン配にしてあるんですけども。

image
tnishinaga commented 2 years ago

ちなみにピン配置がこれなのって、既にボード作ってたりしますか?

自作のデバッグアダプタ用のピン配置になっています。 将来的にはピンを簡単に入れ替えられるようにすると良いと思いますが、今のところはexperimentalな機能なのでそのままにしています。

tnishinaga commented 2 years ago

SWDを試せる環境が昨日用意できず試せていないため、PRはdraft状態になっています

tnishinaga commented 2 years ago

OpenOCDを使ってSWDの検証も行いました。

SWDはOpenOCDから使うとSWJ_PINS関数がunimplementedなのでバグる問題がありましたが、直しました。

tnishinaga commented 2 years ago

なんかターゲットあったかな… ESP32-C3とか、GD32Vとかか。

Raspberry Pi 3とかあるなら config.txtenable_jtag_gpio=1 を追記して起動するだけでGPIOにJTAGが出てきます。 https://www.raspberrypi.com/documentation/computers/config_txt.html#enable_jtag_gpio

私もこの機能で有効化したJTAGポート経由でRasPiにつないでJTAGの動作確認をしています。

ciniml commented 2 years ago

あれ、SWJ_PINS無い問題、なんで今まで顕在化しなかったんだろう… (OpenOCD使ってる)

ciniml commented 2 years ago

とりあえずJTAGは手持ちのGD32VF103つないで動くの確認しました。

OpenOCDの出力

Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x6666:0x4444, serial=raspberry-pi-pico-jtag
Info : CMSIS-DAP: JTAG supported
Info : CMSIS-DAP: FW Version = 2.00
Info : CMSIS-DAP: Serial# = Piyo
Info : CMSIS-DAP: Interface Initialised (JTAG)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 1000 kHz
Info : cmsis-dap JTAG TLR_RESET
Info : cmsis-dap JTAG TLR_RESET
Info : JTAG tap: gd32vf103.cpu tap/device found: 0x1000563d (mfg: 0x31e (Andes Technology Corporation), part: 0x0005, ver: 0x1)
Info : JTAG tap: auto0.tap tap/device found: 0x790007a3 (mfg: 0x3d1 (GigaDevice Semiconductor (Beijing) Inc), part: 0x9000, ver: 0x7)
Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -irlen 5 -expected-id 0x790007a3"
Info : datacount=4 progbufsize=2
Info : Examined RISC-V core; found 1 harts
Info :  hart 0: XLEN=32, misa=0x40901105
Info : starting gdb server for gd32vf103.cpu on 3333
Info : Listening on port 3333 for gdb connections
Info : accepting 'telnet' connection on tcp/4444

telnetでのregの実行結果

> reg
===== RISC-V Registers
(0) zero (/32)
(1) ra (/32)
(2) sp (/32)
(3) gp (/32)
(4) tp (/32)
(5) t0 (/32)
(6) t1 (/32)
(7) t2 (/32)
(8) fp (/32)
(9) s1 (/32)
(10) a0 (/32)
(11) a1 (/32)
(12) a2 (/32)
(13) a3 (/32)
(14) a4 (/32)
(15) a5 (/32)
(16) a6 (/32)
(17) a7 (/32)
(18) s2 (/32)
(19) s3 (/32)
(20) s4 (/32)
(21) s5 (/32)
(22) s6 (/32)
(23) s7 (/32)
(24) s8 (/32)
(25) s9 (/32)
(26) s10 (/32)
(27) s11 (/32)
(28) t3 (/32)
(29) t4 (/32)
(30) t5 (/32)
(31) t6 (/32)
(32) pc (/32)
(72) utvt (/32)
(80) vcsr (/32)
(86) seed (/32)
(134) unxti (/32)
(135) uintstatus (/32)
(137) uscratchcsw (/32)
(138) uscratchcswl (/32)
(323) sedeleg (/32)
(324) sideleg (/32)
(328) stvt (/32)
(390) snxti (/32)
(391) sintstatus (/32)
(393) sscratchcsw (/32)
(394) sscratchcswl (/32)
(577) vsstatus (/32)
(581) vsie (/32)
(582) vstvec (/32)
(641) vsscratch (/32)
(642) vsepc (/32)
(643) vscause (/32)
(644) vstval (/32)
(645) vsip (/32)
(705) vsatp (/32)
(833) mstatus (/32)
(834) misa (/32)
(837) mie (/32)
(838) mtvec (/32)
(839) mcounteren (/32)
(840) mtvt (/32)
(849) mstatush (/32)
(865) mcountinhibit (/32)
(868) mhpmevent3 (/32)
(869) mhpmevent4 (/32)
(870) mhpmevent5 (/32)
(871) mhpmevent6 (/32)
(872) mhpmevent7 (/32)
(873) mhpmevent8 (/32)
(874) mhpmevent9 (/32)
(875) mhpmevent10 (/32)
(876) mhpmevent11 (/32)
(877) mhpmevent12 (/32)
(878) mhpmevent13 (/32)
(879) mhpmevent14 (/32)
(880) mhpmevent15 (/32)
(881) mhpmevent16 (/32)
(882) mhpmevent17 (/32)
(883) mhpmevent18 (/32)
(884) mhpmevent19 (/32)
(885) mhpmevent20 (/32)
(886) mhpmevent21 (/32)
(887) mhpmevent22 (/32)
(888) mhpmevent23 (/32)
(889) mhpmevent24 (/32)
(890) mhpmevent25 (/32)
(891) mhpmevent26 (/32)
(892) mhpmevent27 (/32)
(893) mhpmevent28 (/32)
(894) mhpmevent29 (/32)
(895) mhpmevent30 (/32)
(896) mhpmevent31 (/32)
(897) mscratch (/32)
(898) mepc (/32)
(899) mcause (/32)
(900) mtval (/32)
(901) mip (/32)
(902) mnxti (/32)
(903) mintstatus (/32)
(905) mscratchcsw (/32)
(906) mscratchcswl (/32)
(907) mtinst (/32)
(908) mtval2 (/32)
(993) pmpcfg0 (/32)
(994) pmpcfg1 (/32)
(995) pmpcfg2 (/32)
(996) pmpcfg3 (/32)
(1009) pmpaddr0 (/32)
(1010) pmpaddr1 (/32)
(1011) pmpaddr2 (/32)
(1012) pmpaddr3 (/32)
(1013) pmpaddr4 (/32)
(1014) pmpaddr5 (/32)
(1015) pmpaddr6 (/32)
(1016) pmpaddr7 (/32)
(1017) pmpaddr8 (/32)
(1018) pmpaddr9 (/32)
(1019) pmpaddr10 (/32)
(1020) pmpaddr11 (/32)
(1021) pmpaddr12 (/32)
(1022) pmpaddr13 (/32)
(1023) pmpaddr14 (/32)
(1024) pmpaddr15 (/32)
(1513) scontext (/32)
(1601) hstatus (/32)
(1603) hedeleg (/32)
(1604) hideleg (/32)
(1605) hie (/32)
(1606) htimedelta (/32)
(1607) hcounteren (/32)
(1608) hgeie (/32)
(1622) htimedeltah (/32)
(1668) htval (/32)
(1669) hip (/32)
(1670) hvip (/32)
(1675) htinst (/32)
(1729) hgatp (/32)
(1769) hcontext (/32)
(2017) tselect (/32)
(2018) tdata1 (/32)
(2019) tdata2 (/32)
(2020) tdata3 (/32)
(2021) tinfo (/32)
(2022) tcontrol (/32)
(2025) mcontext (/32)
(2027) mscontext (/32)
(2033) dcsr (/32)
(2034) dpc (/32)
(2035) dscratch0 (/32)
(2036) dscratch1 (/32)
(2881) mcycle (/32)
(2883) minstret (/32)
(2884) mhpmcounter3 (/32)
(2885) mhpmcounter4 (/32)
(2886) mhpmcounter5 (/32)
(2887) mhpmcounter6 (/32)
(2888) mhpmcounter7 (/32)
(2889) mhpmcounter8 (/32)
(2890) mhpmcounter9 (/32)
(2891) mhpmcounter10 (/32)
(2892) mhpmcounter11 (/32)
(2893) mhpmcounter12 (/32)
(2894) mhpmcounter13 (/32)
(2895) mhpmcounter14 (/32)
(2896) mhpmcounter15 (/32)
(2897) mhpmcounter16 (/32)
(2898) mhpmcounter17 (/32)
(2899) mhpmcounter18 (/32)
(2900) mhpmcounter19 (/32)
(2901) mhpmcounter20 (/32)
(2902) mhpmcounter21 (/32)
(2903) mhpmcounter22 (/32)
(2904) mhpmcounter23 (/32)
(2905) mhpmcounter24 (/32)
(2906) mhpmcounter25 (/32)
(2907) mhpmcounter26 (/32)
(2908) mhpmcounter27 (/32)
(2909) mhpmcounter28 (/32)
(2910) mhpmcounter29 (/32)
(2911) mhpmcounter30 (/32)
(2912) mhpmcounter31 (/32)
(3009) mcycleh (/32)
(3011) minstreth (/32)
(3012) mhpmcounter3h (/32)
(3013) mhpmcounter4h (/32)
(3014) mhpmcounter5h (/32)
(3015) mhpmcounter6h (/32)
(3016) mhpmcounter7h (/32)
(3017) mhpmcounter8h (/32)
(3018) mhpmcounter9h (/32)
(3019) mhpmcounter10h (/32)
(3020) mhpmcounter11h (/32)
(3021) mhpmcounter12h (/32)
(3022) mhpmcounter13h (/32)
(3023) mhpmcounter14h (/32)
(3024) mhpmcounter15h (/32)
(3025) mhpmcounter16h (/32)
(3026) mhpmcounter17h (/32)
(3027) mhpmcounter18h (/32)
(3028) mhpmcounter19h (/32)
(3029) mhpmcounter20h (/32)
(3030) mhpmcounter21h (/32)
(3031) mhpmcounter22h (/32)
(3032) mhpmcounter23h (/32)
(3033) mhpmcounter24h (/32)
(3034) mhpmcounter25h (/32)
(3035) mhpmcounter26h (/32)
(3036) mhpmcounter27h (/32)
(3037) mhpmcounter28h (/32)
(3038) mhpmcounter29h (/32)
(3039) mhpmcounter30h (/32)
(3040) mhpmcounter31h (/32)
(3137) cycle (/32)
(3138) time (/32)
(3139) instret (/32)
(3140) hpmcounter3 (/32)
(3141) hpmcounter4 (/32)
(3142) hpmcounter5 (/32)
(3143) hpmcounter6 (/32)
(3144) hpmcounter7 (/32)
(3145) hpmcounter8 (/32)
(3146) hpmcounter9 (/32)
(3147) hpmcounter10 (/32)
(3148) hpmcounter11 (/32)
(3149) hpmcounter12 (/32)
(3150) hpmcounter13 (/32)
(3151) hpmcounter14 (/32)
(3152) hpmcounter15 (/32)
(3153) hpmcounter16 (/32)
(3154) hpmcounter17 (/32)
(3155) hpmcounter18 (/32)
(3156) hpmcounter19 (/32)
(3157) hpmcounter20 (/32)
(3158) hpmcounter21 (/32)
(3159) hpmcounter22 (/32)
(3160) hpmcounter23 (/32)
(3161) hpmcounter24 (/32)
(3162) hpmcounter25 (/32)
(3163) hpmcounter26 (/32)
(3164) hpmcounter27 (/32)
(3165) hpmcounter28 (/32)
(3166) hpmcounter29 (/32)
(3167) hpmcounter30 (/32)
(3168) hpmcounter31 (/32)
(3265) cycleh (/32)
(3266) timeh (/32)
(3267) instreth (/32)
(3268) hpmcounter3h (/32)
(3269) hpmcounter4h (/32)
(3270) hpmcounter5h (/32)
(3271) hpmcounter6h (/32)
(3272) hpmcounter7h (/32)
(3273) hpmcounter8h (/32)
(3274) hpmcounter9h (/32)
(3275) hpmcounter10h (/32)
(3276) hpmcounter11h (/32)
(3277) hpmcounter12h (/32)
(3278) hpmcounter13h (/32)
(3279) hpmcounter14h (/32)
(3280) hpmcounter15h (/32)
(3281) hpmcounter16h (/32)
(3282) hpmcounter17h (/32)
(3283) hpmcounter18h (/32)
(3284) hpmcounter19h (/32)
(3285) hpmcounter20h (/32)
(3286) hpmcounter21h (/32)
(3287) hpmcounter22h (/32)
(3288) hpmcounter23h (/32)
(3289) hpmcounter24h (/32)
(3290) hpmcounter25h (/32)
(3291) hpmcounter26h (/32)
(3292) hpmcounter27h (/32)
(3293) hpmcounter28h (/32)
(3294) hpmcounter29h (/32)
(3295) hpmcounter30h (/32)
(3296) hpmcounter31h (/32)
(3667) hgeip (/32)
(3922) mvendorid (/32)
(3923) marchid (/32)
(3924) mimpid (/32)
(3925) mhartid (/32)
(4161) priv (/8)

gdbでの実行結果

(gdb) info reg
ra             0x1fffb3e4       0x1fffb3e4
sp             0x200013b0       0x200013b0
gp             0x20000a10       0x20000a10
tp             0x0      0x0
t0             0x28     40
t1             0x40     64
t2             0x48     72
fp             0x20000210       0x20000210
s1             0x2000027c       536871548
a0             0x79     121
a1             0x20     32
a2             0x0      0
a3             0x2      2
a4             0x40003000       1073754112
a5             0x2      2
a6             0x40003000       1073754112
a7             0x400    1024
s2             0xaaaa   43690
s3             0x20000ddc       536874460
s4             0x0      0
s5             0x20000278       536871544
s6             0x0      0
s7             0x0      0
--Type <RET> for more, q to quit, c to continue without paging--
tnishinaga commented 2 years ago

あれ、SWJ_PINS無い問題、なんで今まで顕在化しなかったんだろう… (OpenOCD使ってる)

27 を入れるまでは、以下のような動作するバグがあったためです。

27 まではcommand_byteをresponseに入れてからcommandのmatchを行っていました。

そのため、仮にそのcommandの実行に失敗したとしても、command_byteはresponseに残ります。

多くのCmsisDapコマンドのresponseは command_byte, status という組から始まるようになっています。 (SWJPinsは例外) そして、openocdはこのstatus部が0xffかどうかを判定しています(コードの場所がすぐ出てこず申し訳ないです)。

そのため、responseにcommand_byteが入った後、別のコマンドを処理して何らかの値がresponseに追加されて返送されれば、そのコマンドはstatus上では実行されたことになる可能性がありました。

特にSWJPinsは任意のu8を受け付けるので、問題が起こりづらいコマンドとなっています。