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 ----