Index: programs/Xserver/hw/xfree86/common/xf86Priv.h =================================================================== RCS file: /work/cvsdir/cvs/xc/programs/Xserver/hw/xfree86/common/xf86Priv.h,v retrieving revision 1.1.1.26 diff -u -p -r1.1.1.26 xf86Priv.h --- programs/Xserver/hw/xfree86/common/xf86Priv.h 23 Jan 2006 11:15:21 -0000 1.1.1.26 +++ programs/Xserver/hw/xfree86/common/xf86Priv.h 9 Mar 2006 11:20:37 -0000 @@ -155,6 +155,7 @@ void xf86AddDevToEntity(int entityIndex, extern void xf86PostPreInit(void); extern void xf86PostScreenInit(void); extern memType getValidBIOSBase(PCITAG tag, int num); +extern memType getEmptyPciRange(PCITAG tag, int base_reg); extern int pciTestMultiDeviceCard(int bus, int dev, int func, PCITAG** pTag); /* xf86Config.c */ Index: programs/Xserver/hw/xfree86/common/xf86pciBus.c =================================================================== RCS file: /work/cvsdir/cvs/xc/programs/Xserver/hw/xfree86/common/xf86pciBus.c,v retrieving revision 1.1.1.57 diff -u -p -r1.1.1.57 xf86pciBus.c --- programs/Xserver/hw/xfree86/common/xf86pciBus.c 13 Sep 2005 10:31:26 -0000 1.1.1.57 +++ programs/Xserver/hw/xfree86/common/xf86pciBus.c 9 Mar 2006 11:20:37 -0000 @@ -1516,29 +1516,117 @@ xf86ReallocatePciResources(int entityInd /* * BIOS releated */ -memType -getValidBIOSBase(PCITAG tag, int num) +static resPtr +getOwnResources(pciVideoPtr pvp, resPtr mem) +{ + resRange range; + int i; + /* Make sure we don't conflict with our own mem resources */ + for (i = 0; i < 6; i++) { + if (!pvp->memBase[i]) + continue; + P_M_RANGE(range,TAG(pvp),pvp->memBase[i],pvp->size[i], + ResExcMemBlock); + mem = xf86AddResToList(mem,&range,-1); + } + return mem; +} + +static void +getPciRangesForMapping(pciVideoPtr pvp, resPtr *map, resPtr *avoid) { - pciVideoPtr pvp = NULL; PciBusPtr pbp; - resPtr m = NULL; - resPtr tmp, avoid, mem = NULL; + resPtr tmp; + + *avoid = xf86DupResList(pciAvoidRes); + + pbp = xf86PciBus; + while (pbp) { + if (pbp->secondary == pvp->bus) { + if (pbp->preferred_pmem) + tmp = xf86DupResList(pbp->preferred_pmem); + else + tmp = xf86DupResList(pbp->pmem); + *map = xf86JoinResLists(*map,tmp); + if (pbp->preferred_mem) + tmp = xf86DupResList(pbp->preferred_mem); + else + tmp = xf86DupResList(pbp->mem); + *map = xf86JoinResLists(*map,tmp); + tmp = *map; + while (tmp) { + tmp->block_end = min(tmp->block_end,PCI_MEM32_LENGTH_MAX); + tmp = tmp->next; + } + } else if ((pbp->primary == pvp->bus) && + (pbp->secondary >= 0) && + (pbp->primary != pbp->secondary)) { + tmp = xf86DupResList(pbp->preferred_pmem); + *avoid = xf86JoinResLists(*avoid, tmp); + tmp = xf86DupResList(pbp->pmem); + *avoid = xf86JoinResLists(*avoid, tmp); + tmp = xf86DupResList(pbp->preferred_mem); + *avoid = xf86JoinResLists(*avoid, tmp); + tmp = xf86DupResList(pbp->mem); + *avoid = xf86JoinResLists(*avoid, tmp); + } + pbp = pbp->next; + } + pciConvertListToHost(pvp->bus,pvp->device,pvp->func, *avoid); + pciConvertListToHost(pvp->bus,pvp->device,pvp->func, *map); +} + +static memType +findPciRange(PCITAG tag, resPtr m, resPtr avoid, CARD32 size) +{ resRange range; - memType ret; + CARD32 alignment = (1 << size) - 1; + + while (m) { + range = xf86GetBlock(RANGE_TYPE(ResExcMemBlock, xf86GetPciDomain(tag)), + PCI_SIZE(ResMem, tag, 1 << size), + m->block_begin, m->block_end, + PCI_SIZE(ResMem, tag, alignment), + avoid); + if (range.type != ResEnd) { + return M2B(tag, range.rBase); + } + m = m->next; + } + return 0; +} + +pciVideoPtr +getPciVideoPtr(tag) +{ int n = 0; - int i; - CARD32 biosSize, alignment; + pciVideoPtr pvp = NULL; if (!xf86PciVideoInfo) return 0; while ((pvp = xf86PciVideoInfo[n++])) { if (pciTag(pvp->bus,pvp->device,pvp->func) == tag) - break; + return pvp; } + return NULL; +} + +memType +getValidBIOSBase(PCITAG tag, int num) +{ + pciVideoPtr pvp = NULL; + memType ret; + CARD32 biosSize; + resPtr mem = NULL; + resPtr avoid = NULL, m = NULL; + resRange range; + + pvp = getPciVideoPtr(tag); + if (!pvp) return 0; biosSize = pvp->biosSize; - alignment = (1 << biosSize) - 1; + if (biosSize > 24) biosSize = 24; @@ -1549,15 +1637,8 @@ getValidBIOSBase(PCITAG tag, int num) /* In some cases the BIOS base register contains the size mask */ if ((memType)(-1 << biosSize) == PCIGETROM(pvp->biosBase)) return 0; - /* Make sure we don't conflict with our own mem resources */ - for (i = 0; i < 6; i++) { - if (!pvp->memBase[i]) - continue; - P_M_RANGE(range,TAG(pvp),pvp->memBase[i],pvp->size[i], - ResExcMemBlock); - mem = xf86AddResToList(mem,&range,-1); - } - P_M_RANGE(range, TAG(pvp),pvp->biosBase,biosSize,ResExcMemBlock); + mem = getOwnResources(pvp,mem); + P_M_RANGE(range, tag, pvp->biosBase,biosSize,ResExcMemBlock); ret = pvp->biosBase; break; case ROM_BASE_MEM0: @@ -1568,7 +1649,7 @@ getValidBIOSBase(PCITAG tag, int num) case ROM_BASE_MEM5: if (!pvp->memBase[num] || (pvp->size[num] < biosSize)) return 0; - P_M_RANGE(range, TAG(pvp),pvp->memBase[num],biosSize, + P_M_RANGE(range, tag ,pvp->memBase[num],biosSize, ResExcMemBlock); ret = pvp->memBase[num]; break; @@ -1580,59 +1661,15 @@ getValidBIOSBase(PCITAG tag, int num) } /* Now find the ranges for validation */ - avoid = xf86DupResList(pciAvoidRes); - pbp = xf86PciBus; - while (pbp) { - if (pbp->secondary == pvp->bus) { - if (pbp->preferred_pmem) - tmp = xf86DupResList(pbp->preferred_pmem); - else - tmp = xf86DupResList(pbp->pmem); - m = xf86JoinResLists(m,tmp); - if (pbp->preferred_mem) - tmp = xf86DupResList(pbp->preferred_mem); - else - tmp = xf86DupResList(pbp->mem); - m = xf86JoinResLists(m,tmp); - tmp = m; - while (tmp) { - tmp->block_end = min(tmp->block_end,PCI_MEM32_LENGTH_MAX); - tmp = tmp->next; - } - } else if ((pbp->primary == pvp->bus) && - (pbp->secondary >= 0) && - (pbp->primary != pbp->secondary)) { - tmp = xf86DupResList(pbp->preferred_pmem); - avoid = xf86JoinResLists(avoid, tmp); - tmp = xf86DupResList(pbp->pmem); - avoid = xf86JoinResLists(avoid, tmp); - tmp = xf86DupResList(pbp->preferred_mem); - avoid = xf86JoinResLists(avoid, tmp); - tmp = xf86DupResList(pbp->mem); - avoid = xf86JoinResLists(avoid, tmp); - } - pbp = pbp->next; - } - pciConvertListToHost(pvp->bus,pvp->device,pvp->func, avoid); - if (mem) - pciConvertListToHost(pvp->bus,pvp->device,pvp->func, mem); - + getPciRangesForMapping(pvp,&m,&avoid); + if (!ret) { /* Return a possible window */ - while (m) { - range = xf86GetBlock(RANGE_TYPE(ResExcMemBlock, xf86GetPciDomain(tag)), - PCI_SIZE(ResMem, TAG(pvp), 1 << biosSize), - m->block_begin, m->block_end, - PCI_SIZE(ResMem, TAG(pvp), alignment), - avoid); - if (range.type != ResEnd) { - ret = M2B(TAG(pvp), range.rBase); - break; - } - m = m->next; - } + ret = findPciRange(tag,m,avoid,biosSize); } else { #if !defined(__ia64__) /* on ia64, trust the kernel, don't look for overlaps */ + if (mem) + pciConvertListToHost(pvp->bus,pvp->device,pvp->func, mem); if (!xf86IsSubsetOf(range, m) || ChkConflict(&range, avoid, SETUP) || (mem && ChkConflict(&range, mem, SETUP))) @@ -1645,6 +1682,22 @@ getValidBIOSBase(PCITAG tag, int num) return ret; } +memType +getEmptyPciRange(PCITAG tag, int base_reg) +{ + resPtr avoid = NULL, m = NULL; + memType ret; + + pciVideoPtr pvp = getPciVideoPtr(tag); + if (!pvp) return 0; + getPciRangesForMapping(pvp,&m,&avoid); + ret = findPciRange(tag,m,avoid,pvp->size[base_reg]); + xf86FreeResList(avoid); + xf86FreeResList(m); + + return ret; +} + /* * xf86Bus.c interface */ Index: programs/Xserver/hw/xfree86/dummylib/Imakefile =================================================================== RCS file: /work/cvsdir/cvs/xc/programs/Xserver/hw/xfree86/dummylib/Imakefile,v retrieving revision 1.1.1.8 diff -u -p -r1.1.1.8 Imakefile --- programs/Xserver/hw/xfree86/dummylib/Imakefile 13 Sep 2005 10:31:34 -0000 1.1.1.8 +++ programs/Xserver/hw/xfree86/dummylib/Imakefile 9 Mar 2006 11:20:38 -0000 @@ -8,6 +8,7 @@ INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86O SRCS = \ fatalerror.c \ getvalidbios.c \ + getemptypci.c \ logvwrite.c \ pcitestmulti.c \ verrorf.c \ @@ -32,6 +33,7 @@ SRCS = \ OBJS = \ fatalerror.o \ getvalidbios.o \ + getemptypci.o \ logvwrite.o \ pcitestmulti.o \ verrorf.o \ Index: programs/Xserver/hw/xfree86/dummylib/getemptypci.c =================================================================== RCS file: programs/Xserver/hw/xfree86/dummylib/getemptypci.c diff -N programs/Xserver/hw/xfree86/dummylib/getemptypci.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ programs/Xserver/hw/xfree86/dummylib/getemptypci.c 9 Mar 2006 11:20:38 -0000 @@ -0,0 +1,19 @@ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" + +/* + * Utility functions required by libxf86_os. + */ + +memType +getEmptyPciRange(PCITAG tag, int base_reg) +{ + return 0; +} Index: programs/Xserver/hw/xfree86/os-support/bus/Pci.c =================================================================== RCS file: /work/cvsdir/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v retrieving revision 1.1.1.60 diff -u -p -r1.1.1.60 Pci.c --- programs/Xserver/hw/xfree86/os-support/bus/Pci.c 25 Nov 2005 10:05:28 -0000 1.1.1.60 +++ programs/Xserver/hw/xfree86/os-support/bus/Pci.c 9 Mar 2006 11:20:40 -0000 @@ -1068,6 +1068,20 @@ xf86scanpci(int flags) return pci_devp; } +pciConfigPtr +xf86GetPciConfigFromTag(PCITAG Tag) +{ + pciConfigPtr pDev; + int i = 0; + + for (i = 0 ; (pDev = pci_devp[i]) && i <= MAX_PCI_DEVICES; i++) { + if (Tag == pDev->tag) + return pDev; + } + + return NULL; /* Bad data */ +} + CARD32 pciCheckForBrokenBase(PCITAG Tag,int basereg) { @@ -1160,13 +1174,18 @@ handlePciBIOS(PCITAG Tag, int basereg, /* if we use a mem base save it and move it out of the way */ if (b_reg >= 0 && b_reg <= 5) { + memType emptybase; savebase = pciReadLong(Tag, PCI_MAP_REG_START+(b_reg<<2)); xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]" " for device %i:%i:%i\n", basereg, (int)PCI_BUS_FROM_TAG(Tag), (int)PCI_DEV_FROM_TAG(Tag), (int)PCI_FUNC_FROM_TAG(Tag)); + if (!(emptybase = getEmptyPciRange(Tag,b_reg))) { + xf86Msg(X_ERROR,"Cannot find empty range to map base to\n"); + return 0; + } pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), - (CARD32)~0); + emptybase); } /* Set ROM base address and enable ROM address decoding */ pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr Index: programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h =================================================================== RCS file: /work/cvsdir/cvs/xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h,v retrieving revision 1.1.1.33 diff -u -p -r1.1.1.33 xf86Pci.h --- programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h 27 Apr 2005 16:00:07 -0000 1.1.1.33 +++ programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h 9 Mar 2006 11:20:40 -0000 @@ -780,6 +780,7 @@ int xf86ReadPciBIOSByType(unsigned int xf86GetAvailablePciBIOSTypes(PCITAG Tag, int basereg, PciBiosType *Buf); pciConfigPtr *xf86scanpci(int flags); +pciConfigPtr xf86GetPciConfigFromTag(PCITAG Tag); extern int pciNumBuses; Index: programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c =================================================================== RCS file: /work/cvsdir/cvs/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c,v retrieving revision 1.1.1.10 diff -u -p -r1.1.1.10 lnx_pci.c --- programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c 25 Nov 2005 10:05:30 -0000 1.1.1.10 +++ programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c 9 Mar 2006 11:20:40 -0000 @@ -201,6 +201,8 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int s fn = devfn & 0x7; if (tag == pciTag(bus,dev,fn)) { /* ok now look through all the BAR values of this device */ + pciConfigPtr pDev = xf86GetPciConfigFromTag(tag); + for (ndx=0; ndx<7; ndx++) { unsigned long savePtr; /* @@ -208,11 +210,9 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int s * memory attributes */ if (ndx == 6) - savePtr = (0xFFFFFFF0) & - pciReadLong(tag, PCI_CMD_BIOS_REG); + savePtr = PCIGETROM(pDev->pci_baserom); else /* this the ROM bar */ - savePtr = (0xFFFFFFF0) & - pciReadLong(tag, PCI_CMD_BASE_REG + (0x4 * ndx)); + savePtr = (0xFFFFFFF0) & (&pDev->pci_base0)[ndx]; /* find the index of the incoming base */ if (base >= savePtr && base <= (savePtr + size[ndx])) {