私が海外でPi5発売されてから楽しみにしていたことの一つは「RP1に搭載されているPIOが使えるか」です。
画像は https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf のFigure2,pp.6 より引用(一部加筆)
海外でのPi5発売とほぼ同時期に公開されたRP1のマニュアルをみると、Cortex-M3コアにPIOが接続されている様子が示されていました。 また、同マニュアルのpp.12よりRP1のコアクロックは200MHzらしいです。 (PicoのRP2040と同じなら)PIOはコアクロックと同じ速度で動くはずなので、理論値で最大100MHzくらいの信号を出力できるかもしれず、ワクワクしていました。
時が経ち2024年2月13日、ついにPi5が日本でも発売され、嬉しいことに1台購入することができました。 そこで早速RP1のPIOを使う方法を調べてみたのですが、どうやら今のところ使えなさそうとわかりました。
以下、調べたことをつらつらと書いていきます。
(PIOについては手前味噌ですが こちらの資料 をご参照ください)
なぜPIOは使えないのか
一言で言えば「PIO制御用ペリフェラルがPCIeから見えるメモリにmapされていないから」らしいです。
Pi5でPIOが使えるかはMichaelBellさんがすでに調査して共有してくれています。
rp1-hacking/PIO.md at main · MichaelBell/rp1-hacking · GitHub
こちらには以下のように書かれています。
The PIO registers are accessible at address 0xf000_0000 from the RP1. Additionally the FIFOs (only) are accessible at 0x40178000 and hence from Linux (at 0x1f_00178000). rp1-hacking/PIO.md at main · MichaelBell/rp1-hacking · GitHub より引用
つまり、LinuxからはPIOのFIFOしかアクセスできず、PIOの制御レジスタはRP1のプロセッサからしかアクセスできないメモリにいるようです。 本当にそうなっているのでしょうか?
メモリマップの調査
PCIeデバイスの制御は、デバイスの持つメモリをホストのメモリにマップし、そこにアクセスして行います(参考: https://osdev.jp/wiki/PCI-Memo)。
RP1はPCIe経由で接続されているので、RP1のメモリもホストのメモリの何処かにマップされています。
どこにマップされているかは、以下の起動時のログやドライバを眺めたり、mmapして実際にメモリを読んでみると、 RP1の 0x4000_0000
がホストの 0x1F_0000_0000
にマウントされているとわかります。
[ 1.767860] pci 0000:01:00.0: BAR 1: assigned [mem 0x1f00000000-0x1f003fffff] [ 1.775026] pci 0000:01:00.0: BAR 2: assigned [mem 0x1f00400000-0x1f0040ffff] [ 1.782192] pci 0000:01:00.0: BAR 0: assigned [mem 0x1f00410000-0x1f00413fff] ... [ 1.836165] rp1 0000:01:00.0: bar0 len 0x4000, start 0x1f00410000, end 0x1f00413fff, flags, 0x40200 [ 1.845252] rp1 0000:01:00.0: bar1 len 0x400000, start 0x1f00000000, end 0x1f003fffff, flags, 0x40200 [ 1.854518] rp1 0000:01:00.0: enabling device (0000 -> 0002) [ 1.861119] rp1 0000:01:00.0: chip_id 0x20001927
- linux/drivers/mfd/rp1.c at 77fc1fbcb5c013329af9583307dd1ff3cd4752aa · raspberrypi/linux · GitHub
- linux/include/dt-bindings/mfd/rp1.h at 77fc1fbcb5c013329af9583307dd1ff3cd4752aa · raspberrypi/linux · GitHub
具体的には以下のように調べていきました。
- dmesgより、RP1のメモリは
0x1f00410000
と0x1f00000000
にマップされていそう - dmesgと
mfd/rp1.c
より、chip_idはbase + RP1_SYSINFO_BASE
を読んで取得していそう つまり、どっちかのメモリのoffset 0番地をmmapして読み込んで
0x20001927
が得られたほうがRP1の0x4000_0000
にマップされているはず0x1F_0000_0000
を読んだときに0x20001927が見えたので0x4000.0000(proc addr) <-> 0x1f_0000_0000(Linux VA?)
で確定
Linuxから見えるPIOレジスタ?のチェック
RP1のマニュアルによるとPIOはRP1のメモリの0x40178000
にマップされているらしいです。
そこでLinuxから 0x1f_0017_8000
にアクセスしたところ、こんな値が読めました。
(余談: このメモリは32bitずつしか読み込めないです。8bitずつ読み込むと上位24bitが0xffになります。なぜ...?)
# 左が 0x40178000 からのoffset、右が読み込んだ32bit値 map ok read pio registers 0x000000 : 00000000 0x000004 : 00000000 0x000008 : 00000000 0x00000c : 00000000 0x000010 : 418c2041 0x000014 : 2d8ef0c6 0x000018 : 42c753b3 0x00001c : d61f584b 0x000020 : 70696f33 0x000024 : 00000000 0x000028 : 00000001 0x00002c : 00000000 0x000030 : 00000000 0x000034 : 00000000 0x000038 : 00000001
MichaelBellさんの調査結果より、RP1のPIOのFSTATレジスタはオフセット0x04にいるはずです。 このレジスタには何らかの値が入っているはずなので、0が読み出されるのはなにか変です。 よって、少なくともこのアドレスにPIOの制御レジスタがないことは確かそうです。
0xF000_0000 にあると言われているPIOレジスタはLinuxから読めないのか
RP1のマニュアルの「Table 1. Address Map summary」と「Table 2. Peripheral Address Map」を見る限り 0xF000_0000
は外部に見えるアドレスが割り当てられてなさそうなので、厳しそうです。
画像は https://datasheets.raspberrypi.com/rp1/rp1-peripherals.pdf のTable 1. Address Map summary,pp.7 より引用
以上より、今のところPIOはLinuxから簡単に扱えなさそうという結論になりました。
MichaelBellさんはどうやってPIOを使おうとしているか
フォーラムでの投稿やgithubのコードを見る限りでは、G33katWorkさんのRP1リバースエンジニアリングの成果を元にRP1でPIOを制御するコードを動かそうとされているようです。
GitHub - G33KatWork/RP1-Reverse-Engineering: Experiments on the RP1
rp1-hacking/launch_core1 at main · MichaelBell/rp1-hacking · GitHub
まだコードをきちんと理解できていないのですが、どうもShared SRAMに自作のコードを置いたあと、WatchDogを制御してリセットをかけてRP1のCore1で自作コードを動かしているみたいです。
このやり方についてRaspberry Pi エンジニアのjdbさんは以下のように言われています。
You are free to hack around with the hardware, but for anyone else wanting to experiment with this, heed these warnings: The RP1 firmware expects unfettered access to the entirety of shared SRAM, starting at 0x2000_0000. Arbitrary modification of any part of the memory region may cause side-effects up to and including loss of data and hardware damage. Using RP1 and PIO on Raspberry Pi 5 - Raspberry Pi Forums より引用
意訳すると「やるのは自由だけど、壊れるかもしれないから気をつけてね」という感じでしょうか。
その後の投稿で「core1もそのうち使えるようにする」と言われているので、それを気長に待つと良いのかなと思います。 (こういうHackやるようにメモリ1Gだけどお手頃価格なPi5出たら嬉しいなー)
おしまい
以上です。