livaの雑記帳

OSとか作ってみたい

2017/3

 

書き溜めた知見(というよりは独り言)を転記

 

 

3/18

  • 割り込み周りのデバッグをする場合は、HPETを使おう
    • HPETならFSB割り込みとI/O APIC経由の割り込みの両方をサポート
    • PCIで割り込みが出ない場合、デバイスPCIバイス)ドライバのバグの可能性が捨てきれないが、単純なHPETを使う事で、問題の切り分けができる
  • ACPIから取得したPCIバイスIRQが間違ってるっぽい
    • FreeBSDと比較すると明らかに違う
  • DSDTの出力、FreeBSD
    • # acpidump -o dump.aml
      # iasl -d dump.aml

    • これでdump.dslが得られる
    • acpidump -dt dump.amlからのiasl -f dump.amlだとなんかエラーが出る
    • linux版はこっち
  • DSDTを眺めてたら、APIC modeの時とPIC modeの時で異なるPCIの割り込みテーブルを返している事に気づいた
    • DSDTによると、今実験中のマシンではAPIC modeではPCI Routing Table(_PRT)はPCI Interrupt Linkデバイスを返すのではなく、直接IRQを返す模様
      • ココらへんの話を理解するにはここ
    • ぐぐってみると、どうやら手動でAPIC modeに切り替えなければならないらしい
    • 戻り値の処理について、こんな事も書かれている
    • で、_PICメソッドを実行したんだけど、やっぱりPIC modeで返ってるような。。。
    • 実機の場合、_PICメソッドの戻り値はAE_SUCCESSになるはずで、freebsdでもそうなってるのだけど、残念な事にRaph_KernelからはAE_NOT_FOUNDが返ってくる
      • AcpiEnableSubsystem()等の前に実行してた。そりゃ動かないわ

    • FreeBSDIRQが一致した。バンザイ!
      • APICモードでもInterrupt Linkデバイスが帰るケースはあっても良いと思うのだけど、その時の実装はまだ微妙。。。
        • 面倒なのでまた何時かデバッグする
        • こういうのが積もりに積もった結果、今こうして泣きながらデバッグしている事はよくわかってる
  • これまでのまとめ
    • PCIの割り込み(Legacy)を有効にすると、めちゃくちゃ大量の割り込みが来る
    • PCI側かUHCI側でEOIを発行できてないのではないかと推測
    • いろいろ調べた結果、たしかにEOIやdeassertは発行していなかった
    • それでもめちゃくちゃ大量の割り込みが来る
    • PCIの割り込みをdisableにして、I/O APICの設定だけをしてみた
      • それでも割り込みが来た
    • 結論。PCI以外のハードウェアから割り込みが来てる
    • IRQ番号間違ってるのでは・・・?
    • ACPIからのIRQ取得を見直したら動いた
  • 最近、調べ事をしたら自分のブログに当たる事が多くなってきた
    • 以前の知見を脳内に復活させる事ができて大変良い
    • ので、これからもこまめに記録をつけていかねば

 

3/17

  • Level Triggerな割り込みの処理について
    • on I/O APIC
    • LinuxFreeBSDのソースを読むと、どうやらEOIレジスタがI/O APICにはついているらしい
      • そんなもの、I/O APICのデータシートにはない
      • ICH8のI/O APICの項目には確かに書かれてる
      • どうやらバージョンが0x20以上だと存在するらしい
      • で、0x20より小さい場合は、level triggerを一度edge triggerに変更し、また戻す事でEOI相当にするらしい。。。
        • なんだこのキモい動作

 

3/14

  • 昨日の続き
    • とある実機の話
      • PICの初期化をしないと15番に割り込みが入る
      • PICのベクタオフセットを設定するとそれだけずれる
      • これは恐らくPIC(8259A)からのSpurious Interrupt
      • PS/2キーボードからの割り込みはI/O APICのredirection tableの通りにやってくる
      • てことはやっぱりsymmetric I/O modeになってるっぽい
      • 8259からのSpurious Interruptは一回だけだから無視してOK?
      •  とりあえず、8259からの割り込みか、I/O APICからの割り込みかを区別した方が良い
        • これまではどうせ同じIRQだと思って、敢えて8259のベクタオフセットとI/O APICのredirection table上のベクタが重なるように設定していた
        • 今後の調査で8259からの割り込みがこの1回しか来ない事が分かれば、無視しても良さそう
    • symmetric I/O modeではLINT1:0はやっぱり初期化してなくても良いのでは説
      • 今までHPETからの割り込みのテストをマルチコアの初期化前(=virtual wire mode?)でやっていたから、LINT1:0の初期化が必要だった模様
      • むしろsymmetric I/O modeではLINT1:0をマスクしないと変な割り込みが来る
    • またしてもHPETからのFSB割り込みが来なくなった。なんで???
    • 割り込み周りを修正してたら、これまで8042(PS/2キーボード、エミュレーションモード)から割り込みが来なかったマシンでも割り込みが来るようになってしまった
      • 数ヶ月の努力、水疱に帰す
      • I/O APICの設定がちょっとおかしい
        • CPU0に向けて割り込みを発生させているつもりなのに、CPU1で割り込みが入る
          • 1回目の割り込みはCPU0で発生し、2回目の割り込みはCPU1で発生する
          • 割り込みの分散が起きている模様
          • でも、Destination ModeはPhysicalなので、割り込みが分散するはずがないのだが。。。
        • Delivery ModeがLowだったので、これをFixedにしたら直った
          • Loweset Priorityって勝手に割り込み分散するんだろうか
          • いずれにせよ、最近のアーキテクチャではLowest Priorityは使えないらしいという事をどこかで読んだので、今後は全ての割り込みはFixedにする事にする
    • PCI
      • これによればPCI割り込み(not MSI)はlevel trigger, low activeに設定するのが良いらしい
        • I/O APICの設定の話
        • けど、ICH8のデータシート内のAPICの項目ではこの値は常に0なんだよなぁ

 

3/13

  • MP Specificationを改めて読み返してみる
    • 3.6.2.2 Virtual Wire Modeを読むと、8259経由で割り込み転送する場合はLINT0:1を使う事が明記されている。

      • LINT0:1をプログラムしてなくて動かなかった事の理由かなぁ

      • でもそれだと今はVirtual Wire ModeかつI/O APICを使えてないという事になる
      • どうやったらSymmetric I/O modeにできるんだ?
      • やはりsymmetric I/O modeだとLINT0:1はマスクしてても問題ないような気がするので、symmetric I/O modeになってないのかもしれない
      • Appendix Bの方法の通りに初期化しているので、実はsymmetric I/O modeになっているのではないか、という説
      • マルチコアの初期化をデバドラの前に持ってくる事で、symmetric I/O mode状態で割り込みの設定ができるはずだと信じ、そうなるようにした

 

3/12

  • ベアメタルプログラミングをやっていながら、これまでLINT1とLINT0をマスクしていた事に気づく
  • とりあえずAPIC経由のHPET割り込みは来るようになった。直接の解決要因がよくわからない
    • Tn_32MODE_CNFを立て忘れた説が濃厚

    • FSB経由はまだ来ない
  • TN_INT_TYPE_CNFが上がってたので、下げたらFSB経由でも割り込みが来た
    • まあそりゃlevel triggerで来るわけはないのだけど、このフラグ以前から立ってたかなぁ・・・?
  • 結局LINT1:0の初期化忘れが問題だったっぽい
    • というわけで、この2つはマスクせずに、NMIとExtIntが届くようにしましょう
  • Tn_FSB_EN_CNFってR/Wなフラグだと思うんだけど、書き込んでもフラグが下がらないマシンがある・・・ような・・・?

 

3/11

  • とある物の実装をしていて、割り込み周りが実は全く動いてないのではないかという事で調査中
    • 実機の話。QEMUでは完璧に動いている
    • まずはRTCからの割り込みを無効化する
  • いい加減実機でのデバッグの進捗がなさすぎるので、freebsd環境を構築し、レジスタ値の比較をする事にした
    • USB3.0メモリに構築したけど、本当はSSDを使った方が良いんだよなぁ
    • 自分用、freebsdカーネルを高速にコンパイルするコマンド
      • make -DNO_CLEAN -j8 kernel KERNCONF=GENERIC INSTALL=”install -C”

      • install -Cって効果あるんだろうか・・・
      • このコマンドでもUSBメモリではおそすぎてイライラしたので、HDDに変えたら爆速になった

 

3/5