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;
    }
}
Example #3
0
/*
 * 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;
}