Subject: Re: PCI on Compaq deskpro 4000 ?
To: Manuel BOUYER <bouyer@antioche.lip6.fr>
From: Matthias Drochner <drochner@zelux6.zel.kfa-juelich.de>
List: port-i386
Date: 10/17/1997 15:05:52
Excerpts from netbsd: 16-Oct-97 Re: PCI on Compaq deskpro 4.. "Perry E.
Metzger"@pierm (813)
> We could always make using the BIOS an option....
Probably not for 1.3.
(What we can do, is to put the BIOS call into the bootloader and pass
the result.)
But I can't believe that we are not able to write some code which can probe the
hardware properly.
The patch below changes the probe order, mode 1 will be probed first. The
mode 1 probe is made a bit stronger.
Can you give it a try?
best regards
Matthias
Index: pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/pci/pci_machdep.c,v
retrieving revision 1.28
diff -c -2 -r1.28 pci_machdep.c
*** pci_machdep.c 1997/06/06 23:29:17 1.28
--- pci_machdep.c 1997/10/17 12:12:53
***************
*** 337,352 ****
#endif
#else
if (pci_mode != -1)
return pci_mode;
/*
! * We try to divine which configuration mode the host bridge wants. We
! * try mode 2 first, because our probe for mode 1 is likely to succeed
! * for mode 2 also.
! *
! * XXX
! * This should really be done using the PCI BIOS.
*/
outb(PCI_MODE2_ENABLE_REG, 0);
outb(PCI_MODE2_FORWARD_REG, 0);
--- 337,397 ----
#endif
#else
+ u_int32_t sav, val;
+
if (pci_mode != -1)
return pci_mode;
/*
! * We try to divine which configuration mode the host bridge wants.
*/
+ sav = inl(PCI_MODE1_ADDRESS_REG);
+ /*
+ * Check:
+ * 1. bit 31 ("enable") can be set
+ * 2. byte/word access does not affect register
+ */
+ outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
+ outb(PCI_MODE1_ADDRESS_REG + 3, 0);
+ outw(PCI_MODE1_ADDRESS_REG + 2, 0);
+ val = inl(PCI_MODE1_ADDRESS_REG);
+ if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
+ #ifdef DEBUG
+ printf("pci_mode_detect: mode 1 enable failed\n");
+ #endif
+ #ifdef PCI_PROBETEST
+ /*
+ * FreeBSD gives a second chance - test if bit 0
+ * cannot be written. In Intel documentation, this
+ * is marked as "reserved" - but these chipsets
+ * should have passed the first test.
+ */
+ outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE | 1);
+ val = inl(PCI_MODE1_ADDRESS_REG);
+ if ((val & 0x80fffffd) != PCI_MODE1_ENABLE) {
+ #ifdef DEBUG
+ printf("pci_mode_detect: bit 1 writable\n");
+ #endif
+ goto not1;
+ }
+ #else
+ goto not1;
+ #endif /* PCI_PROBETEST */
+ }
+ outl(PCI_MODE1_ADDRESS_REG, 0);
+ val = inl(PCI_MODE1_ADDRESS_REG);
+ if ((val & 0x80fffffc) != 0)
+ goto not1;
+ return (pci_mode = 1);
+ not1:
+ outl(PCI_MODE1_ADDRESS_REG, sav);
+
+ /*
+ * This mode 2 check is quite weak (and known to give false
+ * positives on some Compaq machines).
+ * However, this doesn't matter, because this is the
+ * last test, and simply no PCI devices will be found if
+ * this happens.
+ */
outb(PCI_MODE2_ENABLE_REG, 0);
outb(PCI_MODE2_FORWARD_REG, 0);
***************
*** 355,369 ****
goto not2;
return (pci_mode = 2);
-
not2:
- outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
- if (inl(PCI_MODE1_ADDRESS_REG) != PCI_MODE1_ENABLE)
- goto not1;
- outl(PCI_MODE1_ADDRESS_REG, 0);
- if (inl(PCI_MODE1_ADDRESS_REG) != 0)
- goto not1;
- return (pci_mode = 1);
- not1:
return (pci_mode = 0);
#endif
--- 400,405 ----