xf86_pci.c

来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 1,218 行 · 第 1/3 页

C
1,218
字号
			((CARD32)func << 8);	}	break;    case 2:	if (cardnum < PCI_CONFIG2_MAXDEV) {	    tag.cfg2.port    = 0xc000 | ((CARD16)cardnum << 8);	    tag.cfg2.enable  = 0xf0 | (func << 1);	    tag.cfg2.forward = bus;	}	break;    }    return tag;}static pciTagRecpcibusFTag(pciTagRec tag, CARD8 func){    if (func > 7) {	return tag;    }    switch (pciConfigType) {    case 1:	tag.cfg1 &= ~0x700UL;	tag.cfg1 |= ((CARD32)func << 8);	break;    case 2:	tag.cfg2.enable = 0xf0 | (func << 1);	break;    }    return tag;}CARD32pcibusRead(pciTagRec tag, CARD32 reg){    CARD32 addr, data = 0;    if (!tag.cfg1) {	return 0xffffffff;    }#if !defined(__alpha__)    switch (pciConfigType) {    case 1:	addr = tag.cfg1 | (reg & 0xfc);	outl(PCI_MODE1_ADDRESS_REG, addr);	data = inl(PCI_MODE1_DATA_REG);	outl(PCI_MODE1_ADDRESS_REG, 0);	break;    case 2:	addr = tag.cfg2.port | (reg & 0xfc);	outb(PCI_MODE2_ENABLE_REG, tag.cfg2.enable);	outb(PCI_MODE2_FORWARD_REG, tag.cfg2.forward);	data = inl((CARD16)addr);	outb(PCI_MODE2_ENABLE_REG, 0);	outb(PCI_MODE2_FORWARD_REG, 0);	break;    }#else /* !__alpha__ */    pciconfig_read(BUS(tag.cfg1), DFN(tag.cfg1), reg, 4, &data);#endif /* !__alpha__ */    return data;}CARD16pciReadWord(pciTagRec tag, CARD32 reg){    CARD32 addr;    CARD16 data = 0;    if (!tag.cfg1) {	return 0xff;    }#if !defined(__alpha__)    switch (pciConfigType) {    case 1:	addr = tag.cfg1 | (reg & 0xfc);	outl(PCI_MODE1_ADDRESS_REG, addr);	data = inw(PCI_MODE1_DATA_REG);	outl(PCI_MODE1_ADDRESS_REG, 0);	break;    case 2:	addr = tag.cfg2.port | (reg & 0xfc);	outb(PCI_MODE2_ENABLE_REG, tag.cfg2.enable);	outb(PCI_MODE2_FORWARD_REG, tag.cfg2.forward);	data = inw((CARD16)addr);	outb(PCI_MODE2_ENABLE_REG, 0);	outb(PCI_MODE2_FORWARD_REG, 0);	break;    }#else /* !__alpha__ */    pciconfig_read(BUS(tag.cfg1), DFN(tag.cfg1), reg, 2, &data);#endif /* !__alpha__ */    return data;}CARD8pciReadByte(pciTagRec tag, CARD32 reg){    CARD32 addr;    CARD8 data = 0;    if (!tag.cfg1) {	return 0xff;    }#if !defined(__alpha__)    switch (pciConfigType) {    case 1:	addr = tag.cfg1 | (reg & 0xfc);	outl(PCI_MODE1_ADDRESS_REG, addr);	data = inb(PCI_MODE1_DATA_REG);	outl(PCI_MODE1_ADDRESS_REG, 0);	break;    case 2:	addr = tag.cfg2.port | (reg & 0xfc);	outb(PCI_MODE2_ENABLE_REG, tag.cfg2.enable);	outb(PCI_MODE2_FORWARD_REG, tag.cfg2.forward);	data = inb((CARD16)addr);	outb(PCI_MODE2_ENABLE_REG, 0);	outb(PCI_MODE2_FORWARD_REG, 0);	break;    }#else /* !__alpha__ */    pciconfig_read(BUS(tag.cfg1), DFN(tag.cfg1), reg, 1, &data);#endif /* !__alpha__ */    return data;}voidpcibusWrite(pciTagRec tag, CARD32 reg, CARD32 data){    CARD32 addr;    if (!tag.cfg1) {	return;    }#if !defined(__alpha__)    switch (pciConfigType) {    case 1:	addr = tag.cfg1 | (reg & 0xfc);	outl(PCI_MODE1_ADDRESS_REG, addr);	outl(PCI_MODE1_DATA_REG, data);	outl(PCI_MODE1_ADDRESS_REG, 0);	break;    case 2:	addr = tag.cfg2.port | (reg & 0xfc);	outb(PCI_MODE2_ENABLE_REG, tag.cfg2.enable);	outb(PCI_MODE2_FORWARD_REG, tag.cfg2.forward);	outl((CARD16)addr, data);	outb(PCI_MODE2_ENABLE_REG, 0);	outb(PCI_MODE2_FORWARD_REG, 0);	break;    }#else /* !__alpha__ */    addr = data;    pciconfig_write(BUS(tag.cfg1), DFN(tag.cfg1), reg, 4, &addr);#endif /* !__alpha__ */}voidpciWriteWord(pciTagRec tag, CARD32 reg, CARD16 data){    CARD32 addr;    if (!tag.cfg1) {	return;    }#if !defined(__alpha__)    switch (pciConfigType) {    case 1:	addr = tag.cfg1 | (reg & 0xfc);	outl(PCI_MODE1_ADDRESS_REG, addr);	outw(PCI_MODE1_DATA_REG, data);	outl(PCI_MODE1_ADDRESS_REG, 0);	break;    case 2:	addr = tag.cfg2.port | (reg & 0xfc);	outb(PCI_MODE2_ENABLE_REG, tag.cfg2.enable);	outb(PCI_MODE2_FORWARD_REG, tag.cfg2.forward);	outw((CARD16)addr, data);	outb(PCI_MODE2_ENABLE_REG, 0);	outb(PCI_MODE2_FORWARD_REG, 0);	break;    }#else /* !__alpha__ */    addr = data;    pciconfig_write(BUS(tag.cfg1), DFN(tag.cfg1), reg, 2, &addr);#endif /* !__alpha__ */}voidpciWriteByte(pciTagRec tag, CARD32 reg, CARD8 data){    CARD32 addr;    if (!tag.cfg1) {	return;    }#if !defined(__alpha__)    switch (pciConfigType) {    case 1:	addr = tag.cfg1 | (reg & 0xfc);	outl(PCI_MODE1_ADDRESS_REG, addr);	outb(PCI_MODE1_DATA_REG, data);	outl(PCI_MODE1_ADDRESS_REG, 0);	break;    case 2:	addr = tag.cfg2.port | (reg & 0xfc);	outb(PCI_MODE2_ENABLE_REG, tag.cfg2.enable);	outb(PCI_MODE2_FORWARD_REG, tag.cfg2.forward);	outb((CARD16)addr, data);	outb(PCI_MODE2_ENABLE_REG, 0);	outb(PCI_MODE2_FORWARD_REG, 0);	break;    }#else /* !__alpha__ */    addr = data;    pciconfig_write(BUS(tag.cfg1), DFN(tag.cfg1), reg, 1, &addr);#endif /* !__alpha__ */}static voidpciEnableIO(int scrnIndex){    /* This is enough to ensure that full I/O is enabled */    unsigned pciIOPorts[] = { PCI_MODE1_ADDRESS_REG };    int numPciIOPorts = sizeof(pciIOPorts) / sizeof(pciIOPorts[0]);    xf86ClearIOPortList(scrnIndex);    xf86AddIOPorts(scrnIndex, numPciIOPorts, pciIOPorts);    xf86EnableIOPorts(scrnIndex);}static voidpciDisableIO(int scrnIndex){    xf86DisableIOPorts(scrnIndex);    xf86ClearIOPortList(scrnIndex);}static BoolpciMfDev(CARD8 bus, CARD8 cardnum){    pciTagRec tag0, tag1;    CARD32 id0, id1;    /* Detect a multi-function device that complies to the PCI 2.0 spec */    tag0 = pcibusTag(bus, cardnum, 0);    if (pcibusRead(tag0, PCI_HEADER_MISC) & PCI_HEADER_MULTIFUNCTION)	return TRUE;    /*     * Now, to find non-compliant devices...     * If there is a valid ID for function 1 and the ID for func 0 and 1     * are different, or the base0 values of func 0 and 1 are differend,     * then assume there is a multi-function device.     */    tag1 = pcibusTag(bus, cardnum, 1);    id1 = pcibusRead(tag1, PCI_ID_REG);    if (id1 != 0xffffffff) {	id0 = pcibusRead(tag0, PCI_ID_REG);	if (id0 != id1)	    return TRUE;	if (pcibusRead(tag0, PCI_MAP_REG_START)	    != pcibusRead(tag1, PCI_MAP_REG_START))	    return TRUE;    }    return FALSE;}pciConfigPtr *xf86scanpci(int scrnIndex){    pciConfigRec pcr;    int pcibusidx, pcinumbus, pcibuses[16];    int idx = 0;    if (pci_devp[0])	return pci_devp;    pciEnableIO(scrnIndex);    /* Check for a PCI bus, and find the config type */    pcibusSetup();    if (pciConfigType == 0)	return (pciConfigPtr *)NULL;    pcibusidx = 0;    pcibuses[0] = 0;    pcinumbus = 1;    do {	for (pcr._cardnum = 0; pcr._cardnum < pciMaxDevice; pcr._cardnum++) {	    int maxfunc = 0;	    pciTagRec tag;	    pcr._bus = pcibuses[pcibusidx];	    if (pciMfDev(pcr._bus, pcr._cardnum))		maxfunc = 7;	    tag = pcibusTag(pcr._bus, pcr._cardnum, 0);	    for (pcr._func = 0; pcr._func <= maxfunc; pcr._func++) {		tag = pcibusFTag(tag, pcr._func);		pcr._device_vendor = pcibusRead(tag, PCI_ID_REG);		if (pcr._device_vendor == 0xffffffff)	/* nothing there */		    continue;		pcr._status_command = pcibusRead(tag, PCI_CMD_STAT_REG);		pcr._class_revision = pcibusRead(tag, PCI_CLASS_REG);		pcr._bist_header_latency_cache =			pcibusRead(tag, PCI_HEADER_MISC);		pcr._base0 = pcibusRead(tag, PCI_MAP_REG_START);		pcr._base1 = pcibusRead(tag, PCI_MAP_REG_START + 0x04);		pcr._base2 = pcibusRead(tag, PCI_MAP_REG_START + 0x08);		pcr._base3 = pcibusRead(tag, PCI_MAP_REG_START + 0x0c);		pcr._base4 = pcibusRead(tag, PCI_MAP_REG_START + 0x10);		pcr._base5 = pcibusRead(tag, PCI_MAP_REG_START + 0x14);		pcr.rsvd1  = pcibusRead(tag, PCI_MAP_REG_START + 0x18);		pcr.rsvd2  = pcibusRead(tag, PCI_MAP_REG_START + 0x1C);		pcr._baserom = pcibusRead(tag, PCI_MAP_ROM_REG);		pcr._max_min_ipin_iline = pcibusRead(tag, PCI_INTERRUPT_REG);		pcr._user_config = pcibusRead(tag, PCI_REG_USERCONFIG);		/* Check for PCI-PCI bridges */		if (pcr._base_class == PCI_CLASS_BRIDGE &&		    pcr._sub_class == PCI_SUBCLASS_BRIDGE_PCI) {		    if (pcr._secondary_bus_number > 0) {			pcibuses[pcinumbus++] = pcr._secondary_bus_number;		    }		}		if (idx >= MAX_PCI_DEVICES)		    continue;		if ((pci_devp[idx] = (pciConfigPtr)xalloc(sizeof(pciConfigRec)))		    == (pciConfigPtr)NULL) {		    pciDisableIO(scrnIndex);		    return (pciConfigPtr *)NULL;		}		memcpy(pci_devp[idx++], &pcr, sizeof(pciConfigRec));		pci_devp[idx] = (pciConfigPtr)NULL;		if (xf86Verbose > 1) {		    ErrorF("PCI: Bus 0x%x Card 0x%02x Func 0x%x ID 0x%04x,"			   "0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n",			   pcr._bus, pcr._cardnum, pcr._func, pcr._vendor,			   pcr._device, pcr._rev_id, pcr._base_class,			   pcr._sub_class);		}	    }	}    } while (++pcibusidx < pcinumbus);    pciDisableIO(scrnIndex);    return pci_devp;}voidxf86writepci(int scrnIndex, int bus, int cardnum, int func, int reg,	     CARD32 mask, CARD32 value){    pciTagRec tag;    CARD32 data;    pciEnableIO(scrnIndex);    /* Check for a PCI bus, and find the config type */    pcibusSetup();    if (pciConfigType == 0)	return;    tag = pcibusTag(bus, cardnum, func);    data = pcibusRead(tag, reg) & ~mask | (value & mask);    pcibusWrite(tag, reg, data);    if (xf86Verbose > 2) {	ErrorF("PCI: xf86writepci: Bus=0x%x Card=0x%x Func=0x%x Reg=0x%02x "	       "Mask=0x%08x Val=0x%08x\n",	       bus, cardnum, func, reg, mask, value);    }    pciDisableIO(scrnIndex);}voidxf86cleanpci(){    int idx = 0;    while (pci_devp[idx])	xfree((pointer)pci_devp[idx++]);    pci_devp[0] = (pciConfigPtr)NULL;}#endif /* USE_OLD_PCI_CODE */	/* } */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?