--- hw/xfree86/os-support/bus/Pci.c.orig 2007-09-05 18:48:26.000000000 -0600 +++ hw/xfree86/os-support/bus/Pci.c 2007-10-20 09:13:30.000000000 -0600 @@ -210,6 +210,10 @@ #include "xf86_OSproc.h" #include "Pci.h" +/* WB: start */ +#include "xf86_OSlib.h" +/* WB: end */ + #define PCI_MFDEV_SUPPORT 1 /* Include PCI multifunction device support */ #define PCI_BRIDGE_SUPPORT 1 /* Include support for PCI-to-PCI bridges */ @@ -238,6 +242,9 @@ unsigned char * buf, int len, PciBiosType BiosType ); static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len); +/* WB: start */ +static int freebsdpciOsHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len); +/* WB: end */ int xf86MaxPciDevs = 0; @@ -266,7 +273,6 @@ if (DEBUGPCI >= xf86Verbose) xf86Verbose = DEBUGPCI; #endif - ARCH_PCI_INIT(); #if defined(ARCH_PCI_OS_INIT) if (pciNumBuses <= 0) @@ -1324,6 +1330,12 @@ PCITAG *pTag; int i; + /* WB: call the new routine to read the video BIOS */ + n = freebsdpciOsHandleBIOS(Tag, basereg, buf, len); + if (n) + return n; + /* WB: end */ + /* fall back to the old code if the OS code fails */ if (pciOSHandleBIOS) { n = pciOSHandleBIOS(Tag, basereg, buf, len); @@ -1415,3 +1427,46 @@ } #endif /* INCLUDE_XF86_NO_DOMAIN */ + +/* WB: FreeBSD video BIOS read code, 2007-10-20 */ + +/* This uses /dev/mem to read the BIOS instead of the old X code that */ +/* doesn't work on many Matrox cards (and possibly others). */ + +/* When the Xorg port starts using libpciaccess on FreeBSD, this patch */ +/* will be obsolete. Maybe that'll be the Xorg 7.4 port, maybe later. */ + +/* This patch works for me with the Xorg 7.3 (1.4.1) port, a Matrox */ +/* G450 AGP dualhead card, and FreeBSD i386 6.2-STABLE: */ +/* FreeBSD speedy.wonkity.com 6.2-STABLE FreeBSD 6.2-STABLE #0: Wed Oct */ +/* 10 12:48:47 MDT 2007 root@speedy.wonkity.com:/usr/obj/usr/src/sy */ +/* s/SPEEDY i386 */ + +/* What will probably not work: more than one video card (unless they */ +/* have an identical BIOS), CPUs other than i386. */ + +/* RUNNING THIS CODE SIGNIFIES THAT YOU HAVE EXAMINED THE */ +/* CODE AND UNDERSTAND WHAT IT DOES AND ANY RISKS IT TAKES. */ + +int freebsdpciOsHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len) { + int fd; + int ret; + CARD32 romaddr = 0xc0000; + + fd = open("/dev/mem", O_RDONLY); + if (fd == -1) { + ErrorF("WB: Can't open /dev/mem to read BIOS\n"); + return 0; + } + + basereg = 0x0; + + ErrorF("WB: Reading %dK from /dev/mem address %#x\n", len/1024, romaddr); + lseek(fd, romaddr, SEEK_SET); + ret = read(fd, buf, len); + close(fd); + if (ret < len) + ErrorF("WB: BIOS returned only %dK of %dK attempted\n", ret/1024, len/1024); + return ret; +} +/* WB: end */