読者です 読者をやめる 読者になる 読者になる

HoppeSoft

やわらかコーディング

OS自作入門のその後(PCI編その1)

てぃーてつです。

今回はネットワークそのほか諸々を実装するために
PCI(Peripheral Component Interconnect)を認識してみようと思います。
※例のごとく質問などは私にお願いします

そもそもPCIって何者だよって方はWikipediaを参照してください。
Peripheral Component Interconnect - Wikipedia

PC組み立てたことある人はすぐにピンとくるのかもしれない。


さてシリアル通信編でも参考にさせていただいたOSDev.org
PCI - OSDev Wiki

ここに疑似コードがありますので、はりぼてOS向け(というよりC言語)に書き下します。

/* PCI */
unsigned short PCIConfigReadWord(unsigned char bus, unsigned char slot, unsigned char func, unsigned char offset)
{
  unsigned int address;
  unsigned int lbus = (unsigned int)bus;
  unsigned int lslot = (unsigned int)slot;
  unsigned int lfunc = (unsigned int)func;
  unsigned short tmp = 0;

  /* コンフィギュレーションアドレスを作成 */
  address = (unsigned int)((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) | ((unsigned int)0x80000000));

  /* アドレスの書き出し*/
  io_out32(0xCF8, address);
  /* データの読み込み */
  tmp = (unsigned short)((io_in32(0xCFC) >> ((offset & 2) * 8)) & 0xFFFF);
  return(tmp);
}

unsigned short PCICheckVendor(unsigned char bus, unsigned char slot)
{
  unsigned short vendor, device;
  /* 最初のコンフィギュレーションを読み込むテスト */
  /* ベンダーなし(0xFFFF)の場合、デバイスは存在しないことになる */
  if((vendor = PCIConfigReadWord(bus, slot, 0, 0)) != 0xFFFF)
  {
    device = PCIConfigReadWord(bus, slot, 0, 2);
  }
  return(vendor);
}

コメントは疑似コードにあったものを訳したものなのでガバガバかもしれません()
あとはPCICheckVendorで任意のbusとslotを指定してあげるとベンダIDが返ってきます。
バイスIDを知りたい場合はreturnでdeviceを返してあげてください。

前回せっかくシリアル通信ができるようにしたので、
ベンダIDを調べるテストをしてみました。
なおシリアル通信で文字列を送信する関数は、前回の一文字送る関数を
文字数分だけ繰り返すように組みました。

init_serial(COM1);
sprintf(s, "%x",PCICheckVendor(0,0));
write_serial_string(COM1, s);

charの配列sにsprintfでフォーマットは16進の%xにして書き込み。
これをwrite_serial_string(文字数分COMポートに送り付ける関数)する。
busとslotはとりあえず0に設定してみました。

ちなみにぼくのおすすめのテスト方法は、close_console直後に
使いたい関数をインジェクトする、です。
コンソールを閉じた直後、とタイミングが任意かつ明確で、組み込むのも簡単。

さて例のごとくTera Termでシリアルを受けてみます。

f:id:titets38:20170401144214p:plain

既視感バリバリの数字。。
数字だけじゃ確信持てないのでPCIのデータベースを見てみましょう

PCI Vendor and Device Lists

Vendor Searchの欄に数字を入れてSearchボタン押しましょう。
なおデバイスIDの場合はその下です。

8086でベンダーサーチ……
やっぱりインテルじゃねーか!!!!!


その2に続く(たぶん)