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

📄 nppb.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
字号:
/*      $Id: nppb.c,v 1.1.1.1 2003/11/08 08:41:45 wlin Exp $     *//* * Copyright (c) 2000 Per Fogelstrom, Opsycon AB  (www.opsycon.se) *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by *	Per Fogelstrom, Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *//* * PCI bridge 2155x 'driver'. */#include <sys/param.h>#include <sys/systm.h>#include <sys/device.h>#include <sys/malloc.h>#include <dev/pci/pcireg.h>#include <dev/pci/pcivar.h>#include <dev/pci/pcidevs.h>#include <dev/pci/nppbreg.h>extern int _pciverbose;struct nppb_softc {	struct device	sc_dev;	pci_chipset_tag_t sc_pc;	bus_space_tag_t	sc_iot;	bus_space_handle_t sc_ioh;	pcitag_t	sc_tag;};int	nppb_match __P((struct device *, void *, void *));void	nppb_attach __P((struct device *, struct device *, void *));struct cfattach nppb_ca = {	sizeof(struct nppb_softc), nppb_match, nppb_attach};struct        cfdriver nppb_cd = {      NULL, "nppb", DV_DULL};intnppb_match(parent, match, aux)	struct device *parent;	void *match;	void *aux;{	struct pci_attach_args *pa = aux;	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&	    PCI_PRODUCT(pa->pa_id) == 0x0046)		return (1);	return (0);}voidnppb_attach(parent, self, aux)	struct device *parent, *self;	void *aux;{	struct pci_attach_args *pa = aux;	struct nppb_softc *sc = (struct nppb_softc *)self;	u_int32_t ioaddr;	size_t iosize;	pcitag_t tag;	pcireg_t rval;	sc->sc_pc = pa->pa_pc;	sc->sc_iot = pa->pa_iot;	sc->sc_tag = tag = pa->pa_tag;	if(pci_io_find(pa->pa_pc, pa->pa_tag, 0x14, &ioaddr, &iosize) != 0) {		printf(": can't find i/o space\n");		return;	}	if(bus_space_map(pa->pa_iot, ioaddr, iosize, 0, &sc->sc_ioh) != 0) {		printf(": couldn't map i/o space\n");		return;	}#ifdef PMON	/*	 * Set up local to cPCI translations. We usually deal with	 * 256Mb windows to PCI and make the assumption that we can	 * map parts of it to the cPCI space.	 */	/* Upstream Non prefetchable and I/O to cPCI bus maps 1:1 */	_pci_conf_write(tag, cfgoffs(ds.up_mem0_tran), PCI_BRIDGE_IO_BASE);	_pci_conf_write(tag, cfgoffs(ds.up_mem1_tran), PCI_BRIDGE_MEM_BASE);	/* Downstream Non prefetchable to RAM */	_pci_conf_write(tag, cfgoffs(ds.down_mem2_tran), 0);	/* Downstream Prefetchable to RAM */	_pci_conf_write(tag, cfgoffs(ds.down_mem3_tran), PCI_TO_LOCAL_RAM_BASE);	/* Downstream I/O to PCI bus */	_pci_conf_write(tag, cfgoffs(ds.down_mem1_tran), PCI_TO_LOCAL_RAM_BASE);	/* Enable Upstream BAR's */	rval = -PCI_BRIDGE_IO_SIZE | PCI_MAPREG_TYPE_IO;	_pci_conf_write(tag, cfgoffs(ds.up_mem0_setup), rval);	rval = -PCI_BRIDGE_MEM_SIZE | PCI_MAPREG_TYPE_MEM;	_pci_conf_write(tag, cfgoffs(ds.up_mem1_setup), rval);	/* Enable Downstream BAR's */	rval = -cPCI_BRIDGE_IO_SIZE | PCI_MAPREG_TYPE_IO;	_pci_conf_write(tag, cfgoffs(ds.down_mem1_setup), rval);	rval = -cPCI_BRIDGE_MEM_SIZE | PCI_MAPREG_TYPE_MEM;	_pci_conf_write(tag, cfgoffs(ds.down_mem2_setup), rval);	rval = -cPCI_BRIDGE_MEM_SIZE | PCI_MAPREG_TYPE_MEM;	_pci_conf_write(tag, cfgoffs(ds.down_mem3_setup), rval);	/* Map cPCI upstream */	_pci_conf_write(tag, cfgoffs(local.up_mem0_bar), PCI_BRIDGE_IO_BASE);	_pci_conf_write(tag, cfgoffs(local.up_mem1_bar), PCI_BRIDGE_MEM_BASE);#ifdef PCI_BRIDGE_PMEM_BASE	_pci_conf_write(tag, cfgoffs(local.up_mem2_bar), PCI_BRIDGE_PMEM_BASE);#endif	/* Map cPCI downstream */	_pci_conf_write(tag, cfgoffs(sub.down_mem1_bar), cPCI_BRIDGE_IO_BASE);	_pci_conf_write(tag, cfgoffs(sub.down_mem2_bar), cPCI_BRIDGE_MEM_BASE);	_pci_conf_write(tag, cfgoffs(sub.down_mem3_bar), cPCI_BRIDGE_PMEM_BASE);	/* Clear lock */	rval = _pci_conf_read(tag, cfgoffs(ds.chip_control));	rval &=  ~PRIM_LOCKOUT;	_pci_conf_write(tag, cfgoffs(ds.chip_control), rval);	/* Enable cPCI side */	rval = _pci_conf_read(tag, cfgoffs(sub.command));	rval |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_IO_ENABLE |		PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_PARITY_ENABLE |		PCI_COMMAND_SERR_ENABLE | PCI_COMMAND_BACKTOBACK_ENABLE;	_pci_conf_write(tag, cfgoffs(sub.command), rval);	/* Clear lock */	rval = _pci_conf_read(tag, cfgoffs(ds.chip_control));	rval &=  ~PRIM_LOCKOUT;	_pci_conf_write(tag, cfgoffs(ds.chip_control), rval);#endif	printf(": PCI-PCI bridge, non-transparent");	printf("\n");}pcireg_tnppb_config_read(tag, reg)	pcitag_t tag;	int reg;{	int bus, dev, func, adr;	pcireg_t rval, cval;	struct nppb_softc *sc = nppb_cd.cd_devs[0];	if(reg & 3) {		return(-1);	}	pci_break_tag(tag, &bus, &dev, &func);	if(func < 0 || func > 7 ||	   reg < 0 || reg > 255) {		return(-1);	}	if(bus == 1 && dev >= 0 && dev < 15) {		/* Do config type 0 cycles */		adr = 0x10000 << dev |  func << 8 | reg;	}	else if(bus > 1 && bus < 256 && dev >= 0 && dev < 32) {		/* Do config type 1 cycles */		adr = pci_make_tag(bus - 1, dev, func) | reg | 1;	}	else {		return(-1);	}	/* Turn off master abort == error */	rval = _pci_conf_read(sc->sc_tag, cfgoffs(ds.chip_control));	_pci_conf_write(sc->sc_tag, cfgoffs(ds.chip_control), rval & ~1);	bus_space_read_2(sc->sc_iot, sc->sc_ioh, csroffs(cnfg_own) + 2);	bus_space_write_4(sc->sc_iot, sc->sc_ioh, csroffs(up_addr), adr);	cval = bus_space_read_4(sc->sc_iot, sc->sc_ioh, csroffs(up_data));	_pci_conf_write(sc->sc_tag, cfgoffs(ds.chip_control), rval);	return(cval);}intnppb_config_write(tag, reg, data)	pcitag_t tag;	int reg;	pcireg_t data;{	int bus, dev, func, adr;	pcireg_t rval;	struct nppb_softc *sc = nppb_cd.cd_devs[0];	if(reg & 3) {		return(-1);	}	pci_break_tag(tag, &bus, &dev, &func);	if(func < 0 || func > 7 ||	   reg < 0 || reg > 255) {		return(-1);	}	if(bus == 1 && dev >= 0 && dev < 15) {		/* Do config type 0 cycles */		adr = 0x10000 << dev |  func << 8 | reg;	}	else if(bus > 1 && bus < 256 && dev >= 0 && dev < 32) {		/* Do config type 1 cycles */		adr = pci_make_tag(bus - 1, dev, func) | reg | 1;	}	else {		return(-1);	}	/* Turn off master abort == error */	rval = _pci_conf_read(sc->sc_tag, cfgoffs(ds.chip_control));	_pci_conf_write(sc->sc_tag, cfgoffs(ds.chip_control), rval & ~1);	bus_space_read_2(sc->sc_iot, sc->sc_ioh, csroffs(cnfg_own) + 2);	bus_space_write_4(sc->sc_iot, sc->sc_ioh, csroffs(up_addr), adr);	bus_space_write_4(sc->sc_iot, sc->sc_ioh, csroffs(up_data), data);	_pci_conf_write(sc->sc_tag, cfgoffs(ds.chip_control), rval);	return(0);}int nppbscan __P((int));int nppbscan(ptr)	int ptr;{	int i,j,k;	for(j = 0; j < 255; j++) {		for(i = 0; i < 32; i++) {			k = nppb_config_read((j << 16) | (i << 11), 0);			if(k != -1 && k != -2) {				printf("bus %d dev %d -> %p\n", j, i, k);			}		}	}	return(0);}#ifdef PMON/* *  This code is called from low level setup before device *  initialisation but after scan of PCI BUS 0. * *  The table below deals with the serial rom initialization such that *  if we have no serial rom, the 21554 is correctly setup anyway. */struct nppb_init {	u_int32_t csroffs;	u_int32_t value;	u_int32_t mask;};struct nppb_init nppb_devspec[] = {	{ cfgoffs(ds.cnfg_own),		0x02020000, 0xfcfcfefe },	{ cfgoffs(ds.down_mem0_tran),	0x00000000, 0x00000fff },	{ cfgoffs(ds.down_mem1_tran),	0x00000000, 0x0000003f },	{ cfgoffs(ds.down_mem2_tran),	0x00000000, 0x00000fff },	{ cfgoffs(ds.down_mem3_tran),	0x00000000, 0x00000fff },	{ cfgoffs(ds.up_mem0_tran),	0x00000000, 0x0000003f },	{ cfgoffs(ds.up_mem1_tran),	0x00000000, 0x0000003f },	{ cfgoffs(ds.down_mem0_setup),	0x00000000, 0x00000ff0 },	{ cfgoffs(ds.down_mem1_setup),	0x00000000, 0x00000030 },	{ cfgoffs(ds.down_mem2_setup),	0x00000000, 0x00000ff0 },	{ cfgoffs(ds.down_mem3_setup),	0x00000000, 0x00000ff0 },	{ cfgoffs(ds.down_upper32),	0x00000000, 0x00000000 },	{ cfgoffs(ds.pri_exp_rom),	0x00000000, 0xfe000fff },	{ cfgoffs(ds.up_mem0_setup),	0x00000000, 0x00000030 },	{ cfgoffs(ds.up_mem1_setup),	0x00000000, 0x00000ff0 },	{ cfgoffs(ds.chip_control),	0x003c0481, 0x00003000 },	{ cfgoffs(ds.chip_status),	0x0200f0f0, 0xfc00f0f0 },	{ cfgoffs(ds.serr_disables),	0x00000000, 0xffff8080 },	{ cfgoffs(ds.reset_control),	0x00000000, 0xfffffff8 },	{ cfgoffs(ds.power_cap),	0x00000000, 0xf9c00000 },	{ cfgoffs(ds.power_csr),	0x00000000, 0x00000000 },	{ cfgoffs(ds.vpd_addr),		0x00000000, 0x7e000000 },	{ cfgoffs(ds.vpd_data),		0x00000000, 0x00000000 },	{ cfgoffs(ds.hot_swap),		0x00c00000, 0xff350000 },};#define nppb_devspec_size (sizeof(nppb_devspec) / sizeof(struct nppb_init))void_nppb_pmon_init(tag)	pcitag_t tag;{	int i;	pcireg_t rval;	for(i = 0; i < nppb_devspec_size; i++) {		rval = _pci_conf_read(tag, nppb_devspec[i].csroffs);		rval &= nppb_devspec[i].mask;		rval |= nppb_devspec[i].value;		_pci_conf_write(tag, nppb_devspec[i].csroffs, rval);	}	rval = _pci_conf_read(tag, cfgoffs(sub.command));	rval |= PCI_COMMAND_MASTER_ENABLE;	_pci_conf_write(tag, cfgoffs(sub.command), rval);}pcireg_t_nppb_config_read(btag, tag, reg)	pcitag_t btag;	pcitag_t tag;	int reg;{	int bus, dev, func, adr;	pcireg_t rval, cval;	if(reg & 3) {		return(-1);	}	pci_break_tag(tag, &bus, &dev, &func);	/* This really never happen with the limits we use, but keep in */	if(func < 0 || func > 7 ||	   reg < 0 || reg > 255) {		return(-1);	}	if(bus == 1 && dev >= 0 && dev < 15) {		/* Do config type 0 cycles */		adr = 0x10000 << dev |  func << 8 | reg;	}	else if(bus > 1 && bus < 256 && dev >= 0 && dev < 32) {		/* Do config type 1 cycles */		adr = pci_make_tag(bus - 1, dev, func) | reg | 1;	}	else {		return(-1);	}	/* Turn off master abort == error */	rval = _pci_conf_read(btag, cfgoffs(ds.chip_control));	_pci_conf_write(btag, cfgoffs(ds.chip_control), rval & ~1);	/* Reset bus error status */	cval = _pci_conf_read(btag, cfgoffs(sub.command));	_pci_conf_write(btag, cfgoffs(sub.command), cval);	(void)_pci_conf_read(btag, cfgoffs(ds.cnfg_own));	/* Semaphore */	_pci_conf_write(btag, cfgoffs(ds.up_addr), adr);	cval = _pci_conf_read(btag, cfgoffs(ds.up_data));	_pci_conf_write(btag, cfgoffs(ds.chip_control), rval);	/* Check for bus errors */	rval = _pci_conf_read(btag, cfgoffs(sub.command));	if(rval & (PCI_STATUS_TARGET_TARGET_ABORT |		   PCI_STATUS_MASTER_TARGET_ABORT | PCI_STATUS_MASTER_ABORT |		   PCI_STATUS_SPECIAL_ERROR | PCI_STATUS_PARITY_DETECT)) {		cval = ~0;	/* Error detected */	}	return(cval);}int_nppb_config_write(btag, tag, reg, data)	pcitag_t btag;	pcitag_t tag;	int reg;	pcireg_t data;{	int bus, dev, func, adr;	pcireg_t rval;	if(reg & 3) {		return(-1);	}	pci_break_tag(tag, &bus, &dev, &func);	/* This really never happen with the limits we use, but keep in */	if(func < 0 || func > 7 ||	   reg < 0 || reg > 255) {		return(-1);	}	if(bus == 1 && dev >= 0 && dev < 15) {		/* Do config type 0 cycles */		adr = 0x10000 << dev |  func << 8 | reg;	}	else if(bus > 1 && bus < 256 && dev >= 0 && dev < 32) {		/* Do config type 1 cycles */		adr = pci_make_tag(bus - 1, dev, func) | reg | 1;	}	else {		return(-1);	}	/* Turn off master abort == error */	rval = _pci_conf_read(btag, cfgoffs(ds.chip_control));	_pci_conf_write(btag, cfgoffs(ds.chip_control), rval & ~1);	(void)_pci_conf_read(btag, cfgoffs(ds.cnfg_own));	/* Semaphore */	_pci_conf_write(btag, cfgoffs(ds.up_addr), adr);	_pci_conf_write(btag, cfgoffs(ds.up_data), data);	_pci_conf_write(btag, cfgoffs(ds.chip_control), rval);	return(0);}#endif

⌨️ 快捷键说明

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