⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciide.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef PMONvoidamd756_chip_map(sc, pa)	struct pciide_softc *sc;	struct pci_attach_args *pa;{	struct pciide_channel *cp;	pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc,				    sc->sc_tag, PCI_CLASS_REG));	int channel;	pcireg_t chanenable;	bus_size_t cmdsize, ctlsize;	if (pciide_chipen(sc, pa) == 0)		return;	printf(": DMA");	pciide_mapreg_dma(sc, pa);	if (sc->sc_dma_ok)		sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |			     WDC_CAPABILITY_MODE;	sc->sc_wdcdev.PIO_cap = 4;	sc->sc_wdcdev.DMA_cap = 2;	sc->sc_wdcdev.UDMA_cap = 4;	sc->sc_wdcdev.set_modes = amd756_setup_channel;	sc->sc_wdcdev.channels = sc->wdc_chanarray;	sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;	chanenable = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_CHANSTATUS_EN);	pciide_print_channels(sc->sc_wdcdev.nchannels, interface);	for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {		cp = &sc->pciide_channels[channel];		if (pciide_chansetup(sc, channel, interface) == 0)			continue;		if ((chanenable & AMD756_CHAN_EN(channel)) == 0) {			printf("%s: %s ignored (disabled)\n",			    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);			continue;		}		pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,		    pciide_pci_intr);		if (pciiide_chan_candisable(cp))			chanenable &= ~AMD756_CHAN_EN(channel);		pciide_map_compat_intr(pa, cp, channel, interface);		if (cp->hw_ok == 0)			continue;		amd756_setup_channel(&cp->wdc_channel);	}	pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_CHANSTATUS_EN,	    chanenable);	return;}voidamd756_setup_channel(chp)	struct channel_softc *chp;{	u_int32_t udmatim_reg, datatim_reg;	u_int8_t idedma_ctl;	int mode, drive;	struct ata_drive_datas *drvp;	struct pciide_channel *cp = (struct pciide_channel*)chp;	struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;	idedma_ctl = 0;	datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_DATATIM);	udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, AMD756_UDMA);	datatim_reg &= ~AMD756_DATATIM_MASK(chp->channel);	udmatim_reg &= ~AMD756_UDMA_MASK(chp->channel);	/* setup DMA if needed */	pciide_channel_dma_setup(cp);	for (drive = 0; drive < 2; drive++) {		drvp = &chp->ch_drive[drive];		/* If no drive, skip */		if ((drvp->drive_flags & DRIVE) == 0)			continue;		/* add timing values, setup DMA if needed */		if (((drvp->drive_flags & DRIVE_DMA) == 0 &&		    (drvp->drive_flags & DRIVE_UDMA) == 0)) {			mode = drvp->PIO_mode;			goto pio;		}		if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&		    (drvp->drive_flags & DRIVE_UDMA)) {			/* use Ultra/DMA */			drvp->drive_flags &= ~DRIVE_DMA;			udmatim_reg |= AMD756_UDMA_EN(chp->channel, drive) |			    AMD756_UDMA_EN_MTH(chp->channel, drive) |			    AMD756_UDMA_TIME(chp->channel, drive,				amd756_udma_tim[drvp->UDMA_mode]);			/* can use PIO timings, MW DMA unused */			mode = drvp->PIO_mode;		} else {			/* use Multiword DMA */			drvp->drive_flags &= ~DRIVE_UDMA;			/* mode = min(pio, dma+2) */			if (drvp->PIO_mode <= (drvp->DMA_mode +2))				mode = drvp->PIO_mode;			else				mode = drvp->DMA_mode + 2;		}		idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);pio:		/* setup PIO mode */		if (mode <= 2) {			drvp->DMA_mode = 0;			drvp->PIO_mode = 0;			mode = 0;		} else {			drvp->PIO_mode = mode;			drvp->DMA_mode = mode - 2;		}		datatim_reg |=		    AMD756_DATATIM_PULSE(chp->channel, drive,			amd756_pio_set[mode]) |		    AMD756_DATATIM_RECOV(chp->channel, drive,			amd756_pio_rec[mode]);	}	if (idedma_ctl != 0) {		/* Add software bits in status register */		bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,		    IDEDMA_CTL + (IDEDMA_SCH_OFFSET * chp->channel),		    idedma_ctl);	}	pciide_print_modes(cp);	pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_DATATIM, datatim_reg);	pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_UDMA, udmatim_reg);}#endif#ifndef PMONvoidapollo_chip_map(sc, pa)	struct pciide_softc *sc;	struct pci_attach_args *pa;{	struct pciide_channel *cp;	pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc,				    sc->sc_tag, PCI_CLASS_REG));	int channel;	u_int32_t ideconf;	bus_size_t cmdsize, ctlsize;	if (pciide_chipen(sc, pa) == 0)		return;	printf(": DMA");	pciide_mapreg_dma(sc, pa);	if (sc->sc_dma_ok) {		sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA;		if (sc->sc_pp->ide_product == PCI_PRODUCT_VIATECH_VT82C586A_IDE)			sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;	}	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA32 | WDC_CAPABILITY_MODE;	sc->sc_wdcdev.PIO_cap = 4;	sc->sc_wdcdev.DMA_cap = 2;	sc->sc_wdcdev.UDMA_cap = 2;	sc->sc_wdcdev.set_modes = apollo_setup_channel;	sc->sc_wdcdev.channels = sc->wdc_chanarray;	sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16;	pciide_print_channels(sc->sc_wdcdev.nchannels, interface);		WDCDEBUG_PRINT(("apollo_chip_map: old APO_IDECONF=0x%x, "	    "APO_CTLMISC=0x%x, APO_DATATIM=0x%x, APO_UDMA=0x%x\n",	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF),	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_CTLMISC),	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM),	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)),	    DEBUG_PROBE);	for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {		cp = &sc->pciide_channels[channel];		if (pciide_chansetup(sc, channel, interface) == 0)			continue;		ideconf = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_IDECONF);		if ((ideconf & APO_IDECONF_EN(channel)) == 0) {			printf("%s: %s ignored (disabled)\n",			    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);			continue;		}		pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,		    pciide_pci_intr);		if (cp->hw_ok == 0)			continue;		if (pciiide_chan_candisable(cp)) {			ideconf &= ~APO_IDECONF_EN(channel);			pci_conf_write(sc->sc_pc, sc->sc_tag, APO_IDECONF,				    ideconf);		}		pciide_map_compat_intr(pa, cp, channel, interface);		if (cp->hw_ok == 0)			continue;		apollo_setup_channel(&sc->pciide_channels[channel].wdc_channel);	}	WDCDEBUG_PRINT(("apollo_chip_map: APO_DATATIM=0x%x, APO_UDMA=0x%x\n",	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM),	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA)), DEBUG_PROBE);}voidapollo_setup_channel(chp)	struct channel_softc *chp;{	u_int32_t udmatim_reg, datatim_reg;	u_int8_t idedma_ctl;	int mode, drive;	struct ata_drive_datas *drvp;	struct pciide_channel *cp = (struct pciide_channel*)chp;	struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;	idedma_ctl = 0;	datatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_DATATIM);	udmatim_reg = pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA);	datatim_reg &= ~APO_DATATIM_MASK(chp->channel);	udmatim_reg &= ~AP0_UDMA_MASK(chp->channel);	/* setup DMA if needed */	pciide_channel_dma_setup(cp);	for (drive = 0; drive < 2; drive++) {		drvp = &chp->ch_drive[drive];		/* If no drive, skip */		if ((drvp->drive_flags & DRIVE) == 0)			continue;		/* add timing values, setup DMA if needed */		if (((drvp->drive_flags & DRIVE_DMA) == 0 &&		    (drvp->drive_flags & DRIVE_UDMA) == 0)) {			mode = drvp->PIO_mode;			goto pio;		}		if ((chp->wdc->cap & WDC_CAPABILITY_UDMA) &&		    (drvp->drive_flags & DRIVE_UDMA)) {			/* use Ultra/DMA */			drvp->drive_flags &= ~DRIVE_DMA;			udmatim_reg |= APO_UDMA_EN(chp->channel, drive) |			    APO_UDMA_EN_MTH(chp->channel, drive) |			    APO_UDMA_TIME(chp->channel, drive,				apollo_udma_tim[drvp->UDMA_mode]);			/* can use PIO timings, MW DMA unused */			mode = drvp->PIO_mode;		} else {			/* use Multiword DMA */			drvp->drive_flags &= ~DRIVE_UDMA;			/* mode = min(pio, dma+2) */			if (drvp->PIO_mode <= (drvp->DMA_mode +2))				mode = drvp->PIO_mode;			else				mode = drvp->DMA_mode + 2;		}		idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);pio:		/* setup PIO mode */		if (mode <= 2) {			drvp->DMA_mode = 0;			drvp->PIO_mode = 0;			mode = 0;		} else {			drvp->PIO_mode = mode;			drvp->DMA_mode = mode - 2;		}		datatim_reg |=		    APO_DATATIM_PULSE(chp->channel, drive,			apollo_pio_set[mode]) |		    APO_DATATIM_RECOV(chp->channel, drive,			apollo_pio_rec[mode]);	}	if (idedma_ctl != 0) {		/* Add software bits in status register */		bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,		    IDEDMA_CTL + (IDEDMA_SCH_OFFSET * chp->channel),		    idedma_ctl);	}	pciide_print_modes(cp);	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM, datatim_reg);	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA, udmatim_reg);}#endifvoidcmd_channel_map(pa, sc, channel)	struct pci_attach_args *pa;	struct pciide_softc *sc;	int channel;{	struct pciide_channel *cp = &sc->pciide_channels[channel];	bus_size_t cmdsize, ctlsize;	u_int8_t ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CTRL);	pcireg_t interface =	    PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG));	sc->wdc_chanarray[channel] = &cp->wdc_channel;	cp->name = PCIIDE_CHANNEL_NAME(channel);	cp->wdc_channel.channel = channel;	cp->wdc_channel.wdc = &sc->sc_wdcdev;	if (channel > 0) {		cp->wdc_channel.ch_queue =		    sc->pciide_channels[0].wdc_channel.ch_queue;	} else {		cp->wdc_channel.ch_queue =		    malloc(sizeof(struct channel_queue), M_DEVBUF, M_NOWAIT);	}	if (cp->wdc_channel.ch_queue == NULL) {		printf(		    "%s: %s cannot allocate memory for command queue",		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);		return;	}	/*	 * with a CMD PCI64x, if we get here, the first channel is enabled:	 * there's no way to disable the first channel without disabling	 * the whole device	 */	 if (channel != 0 && (ctrl & CMD_CTRL_2PORT) == 0) {		printf("%s: %s ignored (disabled)\n",		    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);		return;	}	pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize, cmd_pci_intr);	if (cp->hw_ok == 0)		return;	if (channel == 1) {		if (pciiide_chan_candisable(cp)) {			ctrl &= ~CMD_CTRL_2PORT;			pciide_pci_write(pa->pa_pc, pa->pa_tag,			    CMD_CTRL, ctrl);		}	}	pciide_map_compat_intr(pa, cp, channel, interface);}intcmd_pci_intr(arg)	void *arg;{	struct pciide_softc *sc = arg;	struct pciide_channel *cp;	struct channel_softc *wdc_cp;	int i, rv, crv; 	u_int32_t priirq, secirq;	rv = 0;	priirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CONF);	secirq = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_ARTTIM23);	for (i = 0; i < sc->sc_wdcdev.nchannels; i++) {		cp = &sc->pciide_channels[i];		wdc_cp = &cp->wdc_channel;		/* If a compat channel skip. */		if (cp->compat)			continue;		if ((i == 0 && (priirq & CMD_CONF_DRV0_INTR)) ||		    (i == 1 && (secirq & CMD_ARTTIM23_IRQ))) {			crv = wdcintr(wdc_cp);#ifdef PMON			if (crv == 0)				rv = 0;			else				rv = 1;#else			if (crv == 0)				printf("%s:%d: bogus intr\n",				    sc->sc_wdcdev.sc_dev.dv_xname, i);			else				rv = 1;#endif /* PMON */		}	}	return rv;}voidcmd_chip_map(sc, pa)	struct pciide_softc *sc;	struct pci_attach_args *pa;{	int channel;	pcireg_t interface =	    PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG));	/* 	 * For a CMD PCI064x, the use of PCI_COMMAND_IO_ENABLE	 * and base adresses registers can be disabled at 	 * hardware level. In this case, the device is wired	 * in compat mode and its first channel is always enabled,	 * but we can't rely on PCI_COMMAND_IO_ENABLE.	 * In fact, it seems that the first channel of the CMD PCI0640	 * can't be disabled. 	 */#ifdef PCIIDE_CMD064x_DISABLE	if (pciide_chipen(sc, pa) == 0)		return;#endif	printf(": no DMA");	sc->sc_dma_ok = 0;	sc->sc_wdcdev.channels = sc->wdc_chanarray;	sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16;	pciide_print_channels(sc->sc_wdcdev.nchannels, interface);	for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {		cmd_channel_map(pa, sc, channel);	}}voidcmd0643_6_chip_map(sc, pa)	struct pciide_softc *sc;	struct pci_attach_args *pa;{	struct pciide_channel *cp;	int channel;	pcireg_t interface =	    PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG));	/*	 * For a CMD PCI064x, the use of PCI_COMMAND_IO_ENABLE	 * and base adresses registers can be disabled at	 * hardware level. In this case, the device is wired	 * in compat mode and its first channel is always enabled, 	 * but we can't rely on PCI_COMMAND_IO_ENABLE.	 * In fact, it seems that the first channel of the CMD PCI0

⌨️ 快捷键说明

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