VIAのデュアルコア Nano X2 U4025搭載 ZBOX nano VD01 (5)
2012/01/21(土) 19:17 NetBSD はてブ情報 はてブに登録 はてブ数

さて、ZBOX nano VD01の起動しない問題、続々々々編です。

pci_modeを1にすることで無事に起動することが確認できたわけですが、修正自体はチェックロジックを潰すという非常に行儀の悪いものでした。

sys/arch/x86/pci/pci_machdep.cのpci_mode_detect関数をよく見ると、前半になにやらquirkという文字が。

どうやらここで特定のチップセットに対してpci_modeを設定しているようです。pci_conf_read関数を実行して得られたidとpcim1_quirk_tblテーブルに格納されたidを比較し、合致すれば後の処理を行わずにpci_modeを返しています。
518 pci_mode_detect(void)
中略
533 	pci_mode = 1; /* assume this for now */
534 	/*
535 	 * catch some known buggy implementations of mode 1
536 	 */
537 	for (i = 0; i < __arraycount(pcim1_quirk_tbl); i++) {
538 		pcitag_t t;
539 
540 		if (!pcim1_quirk_tbl[i].tag)
541 			break;
542 		t.mode1 = pcim1_quirk_tbl[i].tag;
543 		idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */
544 		if (idreg == pcim1_quirk_tbl[i].id) {
545 #ifdef DEBUG
546 			printf("known mode 1 PCI chipset (%08x)\n",
547 			       idreg);
548 #endif
549 			return (pci_mode);
550 		}
551 	}
中略
593 }
つまり、pcim1_quirk_tblという配列にZBOX nano VD01向けの情報を入れれば良いはずです。

pcim1_quirk_tblは、sys/arch/x86/pci/pci_machdep.cで次のように定義されています。
179 #define _qe(bus, dev, fcn, vend, prod) \
180 	{_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
181 struct {
182 	uint32_t tag;
183 	pcireg_t id;
184 } pcim1_quirk_tbl[] = {
185 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
186 	/* XXX Triflex2 not tested */
187 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
188 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
189 	/* Triton needed for Connectix Virtual PC */
190 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
191 	/* Connectix Virtual PC 5 has a 440BX */
192 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
193 	/* Parallels Desktop for Mac */
194 	_qe(0, 2, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_VIDEO),
195 	_qe(0, 3, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_TOOLS),
196 	/* SIS 740 */
197 	_qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_740),
198 	/* SIS 741 */
199 	_qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741),
200 	{0, 0xffffffff} /* patchable */
201 };
どうやら、PCIデバイスのベンダIDと製品IDが必要のようです。

ZBOX nano VD01はVIA製品ですからベンダID=0x1106まではすぐにわかるのですが、製品IDがわかりません。

とりあえず、このロジックの部分にidregを表示させるprintfを挿入して確認したところ製品IDは0x0410でした。

sys/dev/pci/pcidevsを見ても0x0410は存在しないため、新たに追加が必要だということになります。

追加は簡単なのですが、製品名として何を指定すればよいのでしょう。ZBOX nano VD01の使用を見るとチップセットがVX900Hだそうです。とはいえ、これで正しいのかよくわからないので、VIAのWebページからVX900 Series Programming Manualをダウンロードして確認してみたところ、P18にDevice IDの記載があります。ここに0410hと記載されているので、製品名としてはVX900でよさそうです。

ということで、sys/dev/pci/pcidevsの4591行目の後ろにVX900の記述を加えました。
4583 /* VIA Technologies products, from http://www.via.com.tw/ */
中略
4591 product VIATECH	VT8371_HB	0x0391	VT8371 (Apollo KX133) Host Bridge
     product VIATECH	VX900	0x0410	VX900
4592 product VIATECH VT8501_MVP4	0x0501	VT8501 (Apollo MVP4) Host Bridge
さらに、sys/arch/x86/pci/pci_machdep.cのpcim1_quirk_tblにVX900の定義を追加しました。
198 	/* SIS 741 */
199 	_qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741),
    	/* VIA technology VX900 */
    	_qe(0, 0, 0, PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VX900),
200 	{0, 0xffffffff} /* patchable */
201 };
これでうまく動いてくれているようで、ブート時に次のメッセージが表示されるようになりました。
known mode 1 PCI chipset (04101106)
これが正しい修正なのかはわかりませんが、だいぶマシになったかなと思います。

開始当初は、traceすらできない状況でしたが、まさに紆余曲折ありましたが、なんとか動かすことができてよかったです。

わかる人が見れば、最初のpci_make_tagのところで、pci_modeが1じゃないぞ、フツーpci_modeが1だからquirkつかって強制的にpci_modeを1にすれば動きそうだな。ぐらいの最短距離で動かせたかもしれませんね。

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0766/tb/