diff options
Diffstat (limited to 'xorg-server/hw/xfree86/common/xf86pciBus.c')
-rw-r--r-- | xorg-server/hw/xfree86/common/xf86pciBus.c | 601 |
1 files changed, 34 insertions, 567 deletions
diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c index 5b29a1511..df62e0766 100644 --- a/xorg-server/hw/xfree86/common/xf86pciBus.c +++ b/xorg-server/hw/xfree86/common/xf86pciBus.c @@ -41,23 +41,17 @@ #include "Pci.h" #include "xf86.h" #include "xf86Priv.h" -#include "xf86Resources.h" /* Bus-specific headers */ #include "xf86Bus.h" #define XF86_OS_PRIVS -#define NEED_OS_RAC_PROTOS #include "xf86_OSproc.h" -#include "xf86RAC.h" /* Bus-specific globals */ Bool pciSlotClaimed = FALSE; -static struct pci_device ** xf86PciVideoInfo = NULL; /* PCI probe for video hw */ - -/* PCI classes that get included in xf86PciVideoInfo */ #define PCIINFOCLASSES(c) \ ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \ || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \ @@ -81,23 +75,7 @@ static struct pci_device ** xf86PciVideoInfo = NULL; /* PCI probe for video hw * (((c) & 0x00ffff00) \ == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8))) -/* - * PCI classes for which potentially destructive checking of the map sizes - * may be done. Any classes where this may be unsafe should be omitted - * from this list. - */ -#define PCINONSYSTEMCLASSES(c) PCIALWAYSPRINTCLASSES(c) - -/* - * PCI classes that use RAC - */ -#define PCISHAREDIOCLASSES(c) \ - ( (((c) & 0x00ffff00) \ - == ((PCI_CLASS_PREHISTORIC << 16) | (PCI_SUBCLASS_PREHISTORIC_VGA << 8))) \ - || IS_VGA(c) ) - - -_X_EXPORT void +void xf86FormatPciBusNumber(int busnum, char *buffer) { /* 'buffer' should be at least 8 characters long */ @@ -108,241 +86,6 @@ xf86FormatPciBusNumber(int busnum, char *buffer) } /* - * IO enable/disable related routines for PCI - */ -#define pArg ((pciArg*)arg) -#define SETBITS PCI_CMD_IO_ENABLE -static void -pciIoAccessEnable(void* arg) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciIoAccessEnable: 0x%05lx\n", *(PCITAG *)arg); -#endif - pArg->ctrl |= SETBITS | PCI_CMD_MASTER_ENABLE; - pci_device_cfg_write_u32(pArg->dev, pArg->ctrl, PCI_CMD_STAT_REG); -#endif -} - -static void -pciIoAccessDisable(void* arg) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciIoAccessDisable: 0x%05lx\n", *(PCITAG *)arg); -#endif - pArg->ctrl &= ~SETBITS; - pci_device_cfg_write_u32(pArg->dev, pArg->ctrl, PCI_CMD_STAT_REG); -#endif -} - -#undef SETBITS -#define SETBITS (PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE) -static void -pciIo_MemAccessEnable(void* arg) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciIo_MemAccessEnable: 0x%05lx\n", *(PCITAG *)arg); -#endif - pArg->ctrl |= SETBITS | PCI_CMD_MASTER_ENABLE; - pci_device_cfg_write_u32(pArg->dev, pArg->ctrl, PCI_CMD_STAT_REG); -#endif -} - -static void -pciIo_MemAccessDisable(void* arg) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciIo_MemAccessDisable: 0x%05lx\n", *(PCITAG *)arg); -#endif - pArg->ctrl &= ~SETBITS; - pci_device_cfg_write_u32(pArg->dev, pArg->ctrl, PCI_CMD_STAT_REG); -#endif -} - -#undef SETBITS -#define SETBITS (PCI_CMD_MEM_ENABLE) -static void -pciMemAccessEnable(void* arg) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciMemAccessEnable: 0x%05lx\n", *(PCITAG *)arg); -#endif - pArg->ctrl |= SETBITS | PCI_CMD_MASTER_ENABLE; - pci_device_cfg_write_u32(pArg->dev, pArg->ctrl, PCI_CMD_STAT_REG); -#endif -} - -static void -pciMemAccessDisable(void* arg) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciMemAccessDisable: 0x%05lx\n", *(PCITAG *)arg); -#endif - pArg->ctrl &= ~SETBITS; - pci_device_cfg_write_u32(pArg->dev, pArg->ctrl, PCI_CMD_STAT_REG); -#endif -} -#undef SETBITS -#undef pArg - - -/* move to OS layer */ -#define MASKBITS (PCI_PCI_BRIDGE_VGA_EN | PCI_PCI_BRIDGE_MASTER_ABORT_EN) -static void -pciBusAccessEnable(BusAccPtr ptr) -{ -#if 0 - struct pci_device * const dev = ptr->busdep.pci.dev; - uint16_t ctrl; - -#ifdef DEBUG - ErrorF("pciBusAccessEnable: bus=%d\n", ptr->busdep.pci.bus); -#endif - pci_device_cfg_read_u16( dev, & ctrl, PCI_PCI_BRIDGE_CONTROL_REG ); - if ((ctrl & MASKBITS) != PCI_PCI_BRIDGE_VGA_EN) { - ctrl = (ctrl | PCI_PCI_BRIDGE_VGA_EN) & - ~(PCI_PCI_BRIDGE_MASTER_ABORT_EN | PCI_PCI_BRIDGE_SECONDARY_RESET); - pci_device_cfg_write_u16(dev, ctrl, PCI_PCI_BRIDGE_CONTROL_REG); - } -#endif -} - -/* move to OS layer */ -static void -pciBusAccessDisable(BusAccPtr ptr) -{ -#if 0 - struct pci_device * const dev = ptr->busdep.pci.dev; - uint16_t ctrl; - -#ifdef DEBUG - ErrorF("pciBusAccessDisable: bus=%d\n", ptr->busdep.pci.bus); -#endif - pci_device_cfg_read_u16( dev, & ctrl, PCI_PCI_BRIDGE_CONTROL_REG ); - if (ctrl & MASKBITS) { - ctrl &= ~(MASKBITS | PCI_PCI_BRIDGE_SECONDARY_RESET); - pci_device_cfg_write_u16(dev, ctrl, PCI_PCI_BRIDGE_CONTROL_REG); - } -#endif -} -#undef MASKBITS - -static void -pciSetBusAccess(BusAccPtr ptr) -{ -#if 0 -#ifdef DEBUG - ErrorF("pciSetBusAccess: route VGA to bus %d\n", ptr->busdep.pci.bus); -#endif - - if (!ptr->primary && !ptr->current) - return; - - if (ptr->current && ptr->current->disable_f) - (*ptr->current->disable_f)(ptr->current); - ptr->current = NULL; - - /* walk down */ - while (ptr->primary) { /* No enable for root bus */ - if (ptr != ptr->primary->current) { - if (ptr->primary->current && ptr->primary->current->disable_f) - (*ptr->primary->current->disable_f)(ptr->primary->current); - if (ptr->enable_f) - (*ptr->enable_f)(ptr); - ptr->primary->current = ptr; - } - ptr = ptr->primary; - } -#endif -} - -/* move to OS layer */ -static void -savePciState( struct pci_device * dev, pciSavePtr ptr ) -{ -#if 0 - int i; - - pci_device_cfg_read_u32( dev, & ptr->command, PCI_CMD_STAT_REG ); - - for ( i = 0; i < 6; i++ ) { - pci_device_cfg_read_u32( dev, & ptr->base[i], - PCI_CMD_BASE_REG + (i * 4) ); - } - - pci_device_cfg_read_u32( dev, & ptr->biosBase, PCI_CMD_BIOS_REG ); -#endif -} - -/* move to OS layer */ -#if 0 -static void -restorePciState( struct pci_device * dev, pciSavePtr ptr) -{ - int i; - - /* disable card before setting anything */ - pci_device_cfg_write_bits(dev, PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE, 0, - PCI_CMD_STAT_REG); - - pci_device_cfg_write_u32(dev, ptr->biosBase, PCI_CMD_BIOS_REG); - - for ( i = 0; i < 6; i++ ) { - pci_device_cfg_write_u32(dev, ptr->base[i], - PCI_CMD_BASE_REG + (i * 4)); - } - - pci_device_cfg_write_u32(dev, ptr->command, PCI_CMD_STAT_REG); -} -#endif - -/* move to OS layer */ -static void -savePciBusState(BusAccPtr ptr) -{ -#if 0 - struct pci_device * const dev = ptr->busdep.pci.dev; - uint16_t temp; - - pci_device_cfg_read_u16( dev, & temp, PCI_PCI_BRIDGE_CONTROL_REG ); - ptr->busdep.pci.save.control = temp & ~PCI_PCI_BRIDGE_SECONDARY_RESET; - - /* Allow master aborts to complete normally on non-root buses */ - if ( ptr->busdep.pci.save.control & PCI_PCI_BRIDGE_MASTER_ABORT_EN ) { - temp = ptr->busdep.pci.save.control & ~PCI_PCI_BRIDGE_MASTER_ABORT_EN; - pci_device_cfg_read_u16( dev, & temp, PCI_PCI_BRIDGE_CONTROL_REG ); - } -#endif -} - -/* move to OS layer */ -#define MASKBITS (PCI_PCI_BRIDGE_VGA_EN | PCI_PCI_BRIDGE_MASTER_ABORT_EN) -static void -restorePciBusState(BusAccPtr ptr) -{ -#if 0 - struct pci_device * const dev = ptr->busdep.pci.dev; - uint16_t ctrl; - - /* Only restore the bits we've changed (and don't cause resets) */ - pci_device_cfg_read_u16( dev, & ctrl, PCI_PCI_BRIDGE_CONTROL_REG ); - - if ((ctrl ^ ptr->busdep.pci.save.control) & MASKBITS) { - ctrl &= ~(MASKBITS | PCI_PCI_BRIDGE_SECONDARY_RESET); - ctrl |= ptr->busdep.pci.save.control & MASKBITS; - pci_device_cfg_write_u16(dev, ctrl, PCI_PCI_BRIDGE_CONTROL_REG); - } -#endif -} -#undef MASKBITS - - -/* * xf86Bus.c interface */ @@ -353,6 +96,7 @@ xf86PciProbe(void) int num = 0; struct pci_device *info; struct pci_device_iterator *iter; + struct pci_device ** xf86PciVideoInfo = NULL; if (!xf86scanpci()) { @@ -371,6 +115,12 @@ xf86PciProbe(void) xf86PciVideoInfo[num - 1] = info; pci_device_probe(info); +#ifdef HAVE_PCI_DEVICE_IS_BOOT_VGA + if (pci_device_is_boot_vga(info)) { + primaryBus.type = BUS_PCI; + primaryBus.id.pci = info; + } +#endif info->user_data = 0; } } @@ -464,250 +214,16 @@ xf86PciProbe(void) } } -void -initPciState(void) -{ - unsigned i; - pciAccPtr pcaccp; - - if (xf86PciVideoInfo == NULL) { - return; - } - - for (i = 0 ; xf86PciVideoInfo[i] != NULL ; i++) { - struct pci_device * const pvp = xf86PciVideoInfo[i]; - - if (pvp->user_data == 0) { - pcaccp = xnfalloc( sizeof( pciAccRec ) ); - pvp->user_data = (intptr_t) pcaccp; - - pcaccp->arg.dev = pvp; - pcaccp->ioAccess.AccessDisable = pciIoAccessDisable; - pcaccp->ioAccess.AccessEnable = pciIoAccessEnable; - pcaccp->ioAccess.arg = &pcaccp->arg; - pcaccp->io_memAccess.AccessDisable = pciIo_MemAccessDisable; - pcaccp->io_memAccess.AccessEnable = pciIo_MemAccessEnable; - pcaccp->io_memAccess.arg = &pcaccp->arg; - pcaccp->memAccess.AccessDisable = pciMemAccessDisable; - pcaccp->memAccess.AccessEnable = pciMemAccessEnable; - pcaccp->memAccess.arg = &pcaccp->arg; - - pcaccp->ctrl = PCISHAREDIOCLASSES(pvp->device_class); - - savePciState(pvp, &pcaccp->save); - pcaccp->arg.ctrl = pcaccp->save.command; - } - } -} - -/* - * initPciBusState() - fill out the BusAccRec for a PCI bus. - * Theory: each bus is associated with one bridge connecting it - * to its parent bus. The address of a bridge is therefore stored - * in the BusAccRec of the bus it connects to. Each bus can - * have several bridges connecting secondary buses to it. Only one - * of these bridges can be open. Therefore the status of a bridge - * associated with a bus is stored in the BusAccRec of the parent - * the bridge connects to. The first member of the structure is - * a pointer to a function that open access to this bus. This function - * receives a pointer to the structure itself as argument. This - * design should be common to BusAccRecs of any type of buses we - * support. The remeinder of the structure is bus type specific. - * In this case it contains a pointer to the structure of the - * parent bus. Thus enabling access to a specific bus is simple: - * 1. Close any bridge going to secondary buses. - * 2. Climb down the ladder and enable any bridge on buses - * on the path from the CPU to this bus. - */ - -void -initPciBusState(void) -{ - static const struct pci_id_match bridge_match = { - PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, - (PCI_CLASS_BRIDGE << 16), 0x0000ff0000, 0 - }; - struct pci_device *dev; - struct pci_device_iterator *iter; - BusAccPtr pbap, pbap_tmp; - - iter = pci_id_match_iterator_create(& bridge_match); - while((dev = pci_device_next(iter)) != NULL) { - const uint8_t subclass = (dev->device_class >> 8) & 0x0ff; - int primary; - int secondary; - int subordinate; - - - pci_device_get_bridge_buses(dev, &primary, &secondary, &subordinate); - - pbap = xnfcalloc(1,sizeof(BusAccRec)); - pbap->busdep.pci.bus = secondary; - pbap->busdep.pci.primary_bus = primary; - pbap->busdep_type = BUS_PCI; - pbap->busdep.pci.dev = dev; - - pbap->set_f = pciSetBusAccess; - - switch (subclass) { - case PCI_SUBCLASS_BRIDGE_HOST: - pbap->type = BUS_PCI; - break; - case PCI_SUBCLASS_BRIDGE_PCI: - case PCI_SUBCLASS_BRIDGE_CARDBUS: - pbap->type = BUS_PCI; - pbap->save_f = savePciBusState; - pbap->restore_f = restorePciBusState; - pbap->enable_f = pciBusAccessEnable; - pbap->disable_f = pciBusAccessDisable; - savePciBusState(pbap); - break; - } - pbap->next = xf86BusAccInfo; - xf86BusAccInfo = pbap; - } - - pci_iterator_destroy(iter); - - for (pbap = xf86BusAccInfo; pbap; pbap = pbap->next) { - pbap->primary = NULL; - - if (pbap->busdep_type == BUS_PCI - && pbap->busdep.pci.primary_bus > -1) { - pbap_tmp = xf86BusAccInfo; - while (pbap_tmp) { - if (pbap_tmp->busdep_type == BUS_PCI && - pbap_tmp->busdep.pci.bus == pbap->busdep.pci.primary_bus) { - /* Don't create loops */ - if (pbap == pbap_tmp) - break; - pbap->primary = pbap_tmp; - break; - } - pbap_tmp = pbap_tmp->next; - } - } - } -} - -void -PciStateEnter(void) -{ -#if 0 - unsigned i; - - if (xf86PciVideoInfo == NULL) - return; - - for ( i = 0 ; xf86PciVideoInfo[i] != NULL ; i++ ) { - pciAccPtr paccp = (pciAccPtr) xf86PciVideoInfo[i]->user_data; - - if ( (paccp != NULL) && paccp->ctrl ) { - savePciState(paccp->arg.dev, &paccp->save); - restorePciState(paccp->arg.dev, &paccp->restore); - paccp->arg.ctrl = paccp->restore.command; - } - } -#endif -} - -void -PciBusStateEnter(void) -{ -#if 0 - BusAccPtr pbap = xf86BusAccInfo; - - while (pbap) { - if (pbap->save_f) - pbap->save_f(pbap); - pbap = pbap->next; - } -#endif -} - -void -PciStateLeave(void) -{ -#if 0 - unsigned i; - - if (xf86PciVideoInfo == NULL) - return; - - for ( i = 0 ; xf86PciVideoInfo[i] != NULL ; i++ ) { - pciAccPtr paccp = (pciAccPtr) xf86PciVideoInfo[i]->user_data; - - if ( (paccp != NULL) && paccp->ctrl ) { - savePciState(paccp->arg.dev, &paccp->restore); - restorePciState(paccp->arg.dev, &paccp->save); - } - } -#endif -} - -void -PciBusStateLeave(void) -{ -#if 0 - BusAccPtr pbap = xf86BusAccInfo; - - while (pbap) { - if (pbap->restore_f) - pbap->restore_f(pbap); - pbap = pbap->next; - } -#endif -} - -void -DisablePciAccess(void) -{ -#if 0 - unsigned i; - - if (xf86PciVideoInfo == NULL) - return; - - for ( i = 0 ; xf86PciVideoInfo[i] != NULL ; i++ ) { - pciAccPtr paccp = (pciAccPtr) xf86PciVideoInfo[i]->user_data; - - if ( (paccp != NULL) && paccp->ctrl ) { - pciIo_MemAccessDisable(paccp->io_memAccess.arg); - } - } -#endif -} - -void -DisablePciBusAccess(void) -{ -#if 0 - BusAccPtr pbap = xf86BusAccInfo; - - while (pbap) { - if (pbap->disable_f) - pbap->disable_f(pbap); - if (pbap->primary) - pbap->primary->current = NULL; - pbap = pbap->next; - } -#endif -} - /* * If the slot requested is already in use, return -1. * Otherwise, claim the slot for the screen requesting it. */ -_X_EXPORT int +int xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp, int chipset, GDevPtr dev, Bool active) { EntityPtr p = NULL; - pciAccPtr paccp = (pciAccPtr) d->user_data; - BusAccPtr pbap = xf86BusAccInfo; - const unsigned bus = PCI_MAKE_BUS(d->domain, d->bus); - int num; if (xf86CheckPciSlot(d)) { @@ -721,25 +237,6 @@ xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp, p->inUse = FALSE; if (dev) xf86AddDevToEntity(num, dev); - /* Here we initialize the access structure */ - p->access = xnfcalloc(1,sizeof(EntityAccessRec)); - if (paccp != NULL) { - p->access->fallback = & paccp->io_memAccess; - p->access->pAccess = & paccp->io_memAccess; - paccp->ctrl = TRUE; /* mark control if not already */ - } - else { - p->access->fallback = &AccessNULL; - p->access->pAccess = &AccessNULL; - } - - p->busAcc = NULL; - while (pbap) { - if (pbap->type == BUS_PCI && pbap->busdep.pci.bus == bus) - p->busAcc = pbap; - pbap = pbap->next; - } - pciSlotClaimed = TRUE; if (active) { @@ -753,11 +250,30 @@ xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp, } /* + * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim. + */ +void +xf86UnclaimPciSlot(struct pci_device *d) +{ + int i; + + for (i = 0; i < xf86NumEntities; i++) { + const EntityPtr p = xf86Entities[i]; + + if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) { + /* Probably the slot should be deallocated? */ + p->bus.type = BUS_NONE; + return; + } + } +} + +/* * Parse a BUS ID string, and return the PCI bus parameters if it was * in the correct format for a PCI bus id. */ -_X_EXPORT Bool +Bool xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func) { /* @@ -831,7 +347,7 @@ xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func) * Compare a BUS ID string with a PCI bus id. Return TRUE if they match. */ -_X_EXPORT Bool +Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func) { int ibus, idevice, ifunc; @@ -848,7 +364,7 @@ xf86ComparePciBusString(const char *busID, int bus, int device, int func) * is PCI and bus, dev and func numbers match. */ -_X_EXPORT Bool +Bool xf86IsPrimaryPci(struct pci_device *pPci) { return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci)); @@ -857,7 +373,7 @@ xf86IsPrimaryPci(struct pci_device *pPci) /* * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity. */ -_X_EXPORT struct pci_device * +struct pci_device * xf86GetPciInfoForEntity(int entityIndex) { EntityPtr p; @@ -873,7 +389,7 @@ xf86GetPciInfoForEntity(int entityIndex) * xf86CheckPciMemBase() checks that the memory base value matches one of the * PCI base address register values for the given PCI device. */ -_X_EXPORT Bool +Bool xf86CheckPciMemBase( struct pci_device * pPci, memType base ) { int i; @@ -888,7 +404,7 @@ xf86CheckPciMemBase( struct pci_device * pPci, memType base ) * Check if the slot requested is free. If it is already in use, return FALSE. */ -_X_EXPORT Bool +Bool xf86CheckPciSlot(const struct pci_device *d) { int i; @@ -904,52 +420,3 @@ xf86CheckPciSlot(const struct pci_device *d) } -void -pciConvertRange2Host(int entityIndex, resRange *pRange) -{ - struct pci_device *const pvp = xf86GetPciInfoForEntity(entityIndex); - const PCITAG tag = PCI_MAKE_TAG(PCI_MAKE_BUS(pvp->domain, pvp->bus), - pvp->dev, pvp->func); - - if (pvp == NULL) { - return; - } - - if (!(pRange->type & ResBus)) - return; - - switch(pRange->type & ResPhysMask) { - case ResMem: - switch(pRange->type & ResExtMask) { - case ResBlock: - pRange->rBegin = pciBusAddrToHostAddr(tag,PCI_MEM, pRange->rBegin); - pRange->rEnd = pciBusAddrToHostAddr(tag,PCI_MEM, pRange->rEnd); - break; - case ResSparse: - pRange->rBase = pciBusAddrToHostAddr(tag,PCI_MEM_SPARSE_BASE, - pRange->rBegin); - pRange->rMask = pciBusAddrToHostAddr(tag,PCI_MEM_SPARSE_MASK, - pRange->rEnd); - break; - } - break; - case ResIo: - switch(pRange->type & ResExtMask) { - case ResBlock: - pRange->rBegin = pciBusAddrToHostAddr(tag,PCI_IO, pRange->rBegin); - pRange->rEnd = pciBusAddrToHostAddr(tag,PCI_IO, pRange->rEnd); - break; - case ResSparse: - pRange->rBase = pciBusAddrToHostAddr(tag,PCI_IO_SPARSE_BASE - , pRange->rBegin); - pRange->rMask = pciBusAddrToHostAddr(tag,PCI_IO_SPARSE_MASK - , pRange->rEnd); - break; - } - break; - } - - /* Set domain number */ - pRange->type &= ~(ResDomain | ResBus); - pRange->type |= pvp->domain << 24; -} |