static void print_460gx_sac(pciConfigPtr pcr) { CARD32 tmp; /* Print generalities */ printf(" STATUS 0x%04x COMMAND 0x%04x\n", pcr->pci_status, pcr->pci_command); printf(" CLASS 0x%02x 0x%02x 0x%02x REVISION 0x%02x\n", pcr->pci_base_class, pcr->pci_sub_class, pcr->pci_prog_if, pcr->pci_rev_id); tmp = pcr->pci_user_config; pcr->pci_user_config = 0; print_default_class(pcr); pcr->pci_user_config = tmp; /* Only print what XFree86 might be interested in */ if (pcr->busnum == 0) { if ((pcr->devnum != 0x10) || (pcr->funcnum != 0)) return; /* Get Chipset Bus Number */ cbn_460gx = (unsigned int)pciReadByte(pcr->tag, 0x0040); printf(" CBN 0x%02x CBUSES 0x%02x\n", cbn_460gx, pciReadByte(pcr->tag, 0x0044)); return; } if ((pcr->busnum != cbn_460gx) || (pcr->funcnum != 0)) return; switch (pcr->devnum) { case 0: printf(" F16NUM 0x%02x F16CPL 0x%02x DEVNPRES 0x%08lx\n", pciReadByte(pcr->tag, 0x0060), pciReadByte(pcr->tag, 0x0078), (long)pciReadLong(pcr->tag, 0x0070)); return; case 0x10: printf(" TOM 0x%04x IORD 0x%04x\n", pciReadWord(pcr->tag, 0x0050), pciReadWord(pcr->tag, 0x008E)); /* Fall through */ case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: printf(" BUSNO 0x%02x SUBNO 0x%02x\n", pciReadByte(pcr->tag, 0x0048), pciReadByte(pcr->tag, 0x0049)); printf(" VGASE 0x%02x PCIS 0x%02x IOR 0x%02x\n", pciReadByte(pcr->tag, 0x0080), pciReadByte(pcr->tag, 0x0084), pciReadByte(pcr->tag, 0x008C)); /* Fall through */ default: return; } }
static void print_460gx_sac(pciConfigPtr pcr) { CARD32 tmp; tmp = pcr->pci_user_config; pcr->pci_user_config = 0; print_header_type_0(pcr); pcr->pci_user_config = tmp; /* Only print what XFree86 might be interested in */ if (pcr->busnum == 0) { if ((pcr->devnum != 0x10) || (pcr->funcnum != 0)) return; /* Get Chipset Bus Number */ cbn_460gx = (unsigned int)pciReadByte(pcr->tag, 0x0040); printf(" CBN 0x%02x CBUSES 0x%02x\n", cbn_460gx, pciReadByte(pcr->tag, 0x0044)); return; } if ((pcr->busnum != cbn_460gx) || (pcr->funcnum != 0)) return; switch (pcr->devnum) { case 0: printf(" F16NUM 0x%02x F16CPL 0x%02x DEVNPRES 0x%08lx\n", pciReadByte(pcr->tag, 0x0060), pciReadByte(pcr->tag, 0x0078), (long)pciReadLong(pcr->tag, 0x0070)); return; case 0x10: printf(" TOM 0x%04x IORD 0x%04x\n", pciReadWord(pcr->tag, 0x0050), pciReadWord(pcr->tag, 0x008E)); /* Fall through */ case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: printf(" BUSNO 0x%02x SUBNO 0x%02x\n", pciReadByte(pcr->tag, 0x0048), pciReadByte(pcr->tag, 0x0049)); printf(" VGASE 0x%02x PCIS 0x%02x IOR 0x%02x\n", pciReadByte(pcr->tag, 0x0080), pciReadByte(pcr->tag, 0x0084), pciReadByte(pcr->tag, 0x008C)); /* Fall through */ default: return; } }
/* * This checks for, and validates, the presence of the 460GX chipset, and sets * cbn_460gx to a positive value accordingly. This function returns TRUE if * the chipset scan is to be stopped, or FALSE if the scan is to move on to the * next chipset. */ Bool xf86PreScan460GX(void) { pciBusInfo_t *pBusInfo; PCITAG tag; CARD32 tmp; int i, devno; /* Bus zero should already be set up */ if (!(pBusInfo = pciBusInfo[0])) { cbn_460gx = -1; return FALSE; } /* First look for a 460GX's primary host bridge */ tag = PCI_MAKE_TAG(0, 0x10, 0); if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) { cbn_460gx = -1; return FALSE; } /* Get CBN (Chipset bus number) */ if (!(cbn_460gx = (unsigned int)pciReadByte(tag, CBN))) { /* Sanity check failed */ cbn_460gx = -1; return TRUE; } if (pciNumBuses <= cbn_460gx) pciNumBuses = cbn_460gx + 1; /* Set up bus CBN */ if (!pciBusInfo[cbn_460gx]) { pciBusInfo[cbn_460gx] = xnfalloc(sizeof(pciBusInfo_t)); *pciBusInfo[cbn_460gx] = *pBusInfo; } tag = PCI_MAKE_TAG(cbn_460gx, 0, 0); if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) { /* Sanity check failed */ cbn_460gx = -1; return TRUE; } /* * Find out which CBN devices the firmware thinks are present. Of these, * we are only interested in devices 0x10 through 0x17. */ cbdevs_460gx = pciReadLong(tag, DEVNPRES); for (i = 0, devno = 0x10; devno <= 0x17; i++, devno++) { tag = PCI_MAKE_TAG(cbn_460gx, devno, 0); if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) { /* Sanity check failed */ cbn_460gx = -1; return TRUE; } if (devno == 0x10) iord_460gx = pciReadWord(tag, IORD); busno_460gx[i] = (unsigned int)pciReadByte(tag, BUSNO); subno_460gx[i] = (unsigned int)pciReadByte(tag, SUBNO); pcis_460gx[i] = pciReadByte(tag, PCIS); ior_460gx[i] = pciReadByte(tag, IOR); has_err_460gx[i] = err_460gx[i] = 0; /* Insurance */ tag = PCI_MAKE_TAG(cbn_460gx, devno, 1); tmp = pciReadLong(tag, PCI_ID_REG); switch (tmp) { case DEVID(INTEL, 460GX_PXB): case DEVID(INTEL, 460GX_WXB): if (cbdevs_460gx & (1 << devno)) { /* Sanity check failed */ cbn_460gx = -1; return TRUE; } /* * XXX I don't have WXB docs, but PCI register dumps indicate that * the registers we are interested in are consistent with those of * the PXB. */ err_460gx[i] = pciReadByte(tag, ERRCMD); has_err_460gx[i] = 1; break; case DEVID(INTEL, 460GX_GXB_1): if (cbdevs_460gx & (1 << devno)) { /* Sanity check failed */ cbn_460gx = -1; return TRUE; } /* * XXX GXB isn't documented to have an ERRCMD register, nor any * other means of failing master aborts. For now, assume master * aborts are always allowed to complete normally. */ break; default: if (((CARD16)(tmp + 1U) <= (CARD16)1U) && (cbdevs_460gx & (1U << devno))) break; /* Sanity check failed */ cbn_460gx = -1; return TRUE; } } /* Allow master aborts to complete normally */ for (i = 0, devno = 0x10; devno <= 0x17; i++, devno++) { if (!(err_460gx[i] & 0x01)) continue; pciWriteByte(PCI_MAKE_TAG(cbn_460gx, devno, 1), ERRCMD, err_460gx[i] & ~0x01); } /* * The 460GX spec says that any access to busses higher than CBN will be * master-aborted. It seems possible however that this is not the case in * all 460GX implementations. For now, limit the bus scan to CBN, unless * we have already found a higher bus number. */ for (i = 0; subno_460gx[i] < cbn_460gx; ) { if (++i < 8) continue; pciMaxBusNum = cbn_460gx + 1; break; } return TRUE; }