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

📄 pciconf.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}static void_pci_device_insert(parent, device)    struct pci_device *parent;    struct pci_device *device;{    struct pci_device *pd = parent->bridge.child;    if(pd == NULL) {        parent->bridge.child = device;    } else {            for(; pd->next != NULL; pd = pd->next)            ;;        pd->next = device;    }}static void_pci_query_dev (struct pci_device *dev, int bus, int device, int initialise){	pcitag_t tag;	pcireg_t id;	pcireg_t misc;	tag = _pci_make_tag(bus, device, 0);	if (!_pci_canscan (tag))		return;	if (_pciverbose >= 2)		_pci_bdfprintf (bus, device, -1, "probe...");	id = _pci_conf_read(tag, PCI_ID_REG);	if (_pciverbose >= 2) {		PRINTF ("completed\n");	}	if (id == 0 || id == 0xffffffff) {		return;	}	misc = _pci_conf_read(tag, PCI_BHLC_REG);	if (PCI_HDRTYPE_MULTIFN(misc)) {		int function;		for (function = 0; function < 8; function++) {			tag = _pci_make_tag(bus, device, function);			id = _pci_conf_read(tag, PCI_ID_REG);			if (id == 0 || id == 0xffffffff) {				return;			}			_pci_query_dev_func (dev, tag, initialise);		}	}	else {		_pci_query_dev_func (dev, tag, initialise);	}}static pcireg_t_pci_allocate_mem(dev, size)	struct pci_device *dev;	vm_size_t size;{	pcireg_t address;#ifndef PCI_ALLOC_UPWARDS	/* allocate downwards, then round to size boundary */	address = (dev->bridge.secbus->nextpcimemaddr - size) & ~(size - 1);	if (address > dev->bridge.secbus->nextpcimemaddr ||	    address < dev->bridge.secbus->minpcimemaddr) {		return(-1);	}	dev->bridge.secbus->nextpcimemaddr = address;#else	/* allocate upwards, then round to size boundary */	address = (dev->bridge.secbus->minpcimemaddr + size) & ~(size - 1);	if (address > dev->bridge.secbus->nextpcimemaddr ||	    address < dev->bridge.secbus->minpcimemaddr) {		return(-1);	}	dev->bridge.secbus->minpcimemaddr = address;#endif		return(address);}static pcireg_t_pci_allocate_io(dev, size)    struct pci_device *dev;    vm_size_t size;{	pcireg_t address;#ifndef PCI_ALLOC_UPWARDS	/* allocate downwards, then round to size boundary */	address = (dev->bridge.secbus->nextpciioaddr - size) & ~(size - 1);	if (address > dev->bridge.secbus->nextpciioaddr ||            address < dev->bridge.secbus->minpciioaddr) {		return -1;	}	dev->bridge.secbus->nextpciioaddr = address;#else	/* allocate downwards, then round to size boundary */	address = (dev->bridge.secbus->minpciioaddr + size) & ~(size - 1);	if (address > dev->bridge.secbus->nextpciioaddr ||            address < dev->bridge.secbus->minpciioaddr) {		return -1;	}	dev->bridge.secbus->minpciioaddr = address;#endif	return(address);}static void_insertsort_window(pm_list, pm)    struct pci_win **pm_list;    struct pci_win *pm;{	struct pci_win *pm1, *pm2;	pm1 = (struct pci_win *)pm_list;	while((pm2 = pm1->next)) {		if(pm->size >= pm2->size) {			break;		}		pm1 = pm2;	}	pm1->next = pm;	pm->next = pm2;}static void_pci_setup_windows (struct pci_device *dev){    struct pci_win *pm;    struct pci_win *next;    struct pci_device *pd;    for(pm = dev->bridge.memspace; pm != NULL; pm = next) {        pd = pm->device;        next = pm->next;        pm->address = _pci_allocate_mem (dev, pm->size);        if (pm->address == -1) {            _pci_tagprintf (pd->pa.pa_tag,                             "not enough PCI mem space (%d requested)\n",                             pm->size);            continue;        }        if (_pciverbose >= 2)            _pci_tagprintf (pd->pa.pa_tag, "mem @%p, %d bytes\n", pm->address, pm->size);	if (PCI_ISCLASS(pd->pa.pa_class,	    PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) &&           (pm->reg == PCI_MEMBASE_1)) {            pcireg_t memory;            pd->bridge.secbus->minpcimemaddr = pm->address;            pd->bridge.secbus->nextpcimemaddr = pm->address + pm->size;            memory = (((pm->address+pm->size) >> 16) << 16) | (pm->address >> 16);            _pci_conf_write(pd->pa.pa_tag, pm->reg, memory);        } else if (pm->reg != PCI_MAPREG_ROM) {            /* normal memory - expansion rom done below */            pcireg_t base = _pci_conf_read(pd->pa.pa_tag, pm->reg);            base = pm->address | (base & ~PCI_MAPREG_MEM_ADDR_MASK);            _pci_conf_write(pd->pa.pa_tag, pm->reg, base);        }    }        /* Program expansion rom address base after normal memory base,        to keep DEC ethernet chip happy */    for (pm = dev->bridge.memspace; pm != NULL; pm = next) {	pd = pm->device;	if (PCI_ISCLASS(pd->pa.pa_class, PCI_CLASS_DISPLAY, PCI_SUBCLASS_DISPLAY_VGA)) 		vga_dev = pd;#if 0	/*	 * If this is the first VGA card we find, set the BIOS rom	 * at address c0000 if PCI base address is 0x00000000.	 */	if (pm->reg == PCI_MAPREG_ROM && !have_vga &&	    dev->bridge.secbus->minpcimemaddr == 0 &&	    (PCI_ISCLASS(pd->pa.pa_class,		PCI_CLASS_PREHISTORIC, PCI_SUBCLASS_PREHISTORIC_VGA) ||	    PCI_ISCLASS(pd->pa.pa_class,		PCI_CLASS_DISPLAY, PCI_SUBCLASS_DISPLAY_VGA))) {		have_vga = pd->pa.pa_tag;		pm->address = 0x000c0000;	/* XXX PCI MEM @ 0x000!!! */	}#endif	if (pm->reg == PCI_MAPREG_ROM) {	    /* expansion rom */		if (_pciverbose >= 2)		    _pci_tagprintf (pd->pa.pa_tag, "exp @%p, %d bytes\n",			pm->address, pm->size);	    _pci_conf_write(pd->pa.pa_tag, pm->reg, pm->address | PCI_MAPREG_TYPE_ROM);        }        next = pm->next;        dev->bridge.memspace = next;        pfree(pm);    }        for(pm = dev->bridge.iospace; pm != NULL; pm = next) {        pd = pm->device;        next = pm->next;        pm->address = _pci_allocate_io (dev, pm->size);        if (pm->address == -1) {            _pci_tagprintf (pd->pa.pa_tag,                             "not enough PCI io space (%d requested)\n",                             pm->size);            pfree(pm);            continue;        }        if (_pciverbose >= 2)		    _pci_tagprintf (pd->pa.pa_tag, "i/o @%p, %d bytes\n", pm->address, pm->size);	if (PCI_ISCLASS(pd->pa.pa_class,	    PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI) &&           (pm->reg == PCI_IOBASEL_1)) {	    pcireg_t tmp;            pd->bridge.secbus->minpciioaddr = pm->address;            pd->bridge.secbus->nextpciioaddr = pm->address + pm->size;	    tmp = _pci_conf_read(pd->pa.pa_tag,PCI_IOBASEL_1);	    tmp &= 0xffff0000;	    tmp |= (pm->address >> 8) & 0xf0;	    tmp |= ((pm->address + pm->size) & 0xf000);	    _pci_conf_write(pd->pa.pa_tag,PCI_IOBASEL_1, tmp);	    tmp = (pm->address >> 16) & 0xffff;	    tmp |= ((pm->address + pm->size) & 0xffff0000);	    _pci_conf_write(pd->pa.pa_tag,PCI_IOBASEH_1, tmp);        }        else {            _pci_conf_write(pd->pa.pa_tag, pm->reg, pm->address | PCI_MAPREG_TYPE_IO);        }        dev->bridge.iospace = next;        pfree(pm);    }    /* Recursive allocate memory for secondary buses */    for(pd = dev->bridge.child; pd != NULL; pd = pd->next) {	if (PCI_ISCLASS(pd->pa.pa_class,	    PCI_CLASS_BRIDGE, PCI_SUBCLASS_BRIDGE_PCI)) {            _pci_setup_windows(pd);        }    }}/* * Calculate interrupt routing for a device */static int_pci_getIntRouting(struct pci_device *dev){	return(dev->intr_routing[PCI_INTLINE_A]);}static int_pci_setupIntRouting(struct pci_device *dev){	int error = -1;	struct pci_intline_routing *pi;    	for(pi = _pci_inthead; pi != NULL; pi = pi->next) {		if(dev->parent->pa.pa_tag == _pci_make_tag(pi->bus, pi->device, pi->function)) {			dev->intr_routing[PCI_INTLINE_A] = pi->intline[dev->pa.pa_device][PCI_INTLINE_A];			dev->intr_routing[PCI_INTLINE_B] = pi->intline[dev->pa.pa_device][PCI_INTLINE_B];			dev->intr_routing[PCI_INTLINE_C] = pi->intline[dev->pa.pa_device][PCI_INTLINE_C];			dev->intr_routing[PCI_INTLINE_D] = pi->intline[dev->pa.pa_device][PCI_INTLINE_D];			error = 0;			break;		}	}		/*	 * If there where no predefines routing calculate it.	 */	if(error == -1) {		switch(dev->pa.pa_device % 4) {			case 0:				dev->intr_routing[PCI_INTLINE_A] = dev->parent->intr_routing[PCI_INTLINE_A];				dev->intr_routing[PCI_INTLINE_B] = dev->parent->intr_routing[PCI_INTLINE_B];				dev->intr_routing[PCI_INTLINE_C] = dev->parent->intr_routing[PCI_INTLINE_C];				dev->intr_routing[PCI_INTLINE_D] = dev->parent->intr_routing[PCI_INTLINE_D];				error = 0;				break;			case 1:				dev->intr_routing[PCI_INTLINE_A] = dev->parent->intr_routing[PCI_INTLINE_B];				dev->intr_routing[PCI_INTLINE_B] = dev->parent->intr_routing[PCI_INTLINE_C];				dev->intr_routing[PCI_INTLINE_C] = dev->parent->intr_routing[PCI_INTLINE_D];				dev->intr_routing[PCI_INTLINE_D] = dev->parent->intr_routing[PCI_INTLINE_A];				error = 0;				break;			case 2:				dev->intr_routing[PCI_INTLINE_A] = dev->parent->intr_routing[PCI_INTLINE_C];				dev->intr_routing[PCI_INTLINE_B] = dev->parent->intr_routing[PCI_INTLINE_D];				dev->intr_routing[PCI_INTLINE_C] = dev->parent->intr_routing[PCI_INTLINE_A];				dev->intr_routing[PCI_INTLINE_D] = dev->parent->intr_routing[PCI_INTLINE_B];				error = 0;				break;			case 3:				dev->intr_routing[PCI_INTLINE_A] = dev->parent->intr_routing[PCI_INTLINE_D];				dev->intr_routing[PCI_INTLINE_B] = dev->parent->intr_routing[PCI_INTLINE_A];				dev->intr_routing[PCI_INTLINE_C] = dev->parent->intr_routing[PCI_INTLINE_B];				dev->intr_routing[PCI_INTLINE_D] = dev->parent->intr_routing[PCI_INTLINE_C];				error = 0;				break;			default:				break;		}	}	return(error);}static void_pci_setup_devices (struct pci_device *parent, int initialise){    struct pci_device *pd;    for (pd = parent->bridge.child; pd ; pd = pd->next) {	/* set device parameters */	struct pci_bus *pb = pd->pcibus;	pcitag_t tag = pd->pa.pa_tag;	pcireg_t cmd, misc, class;	unsigned int ltim;	cmd = _pci_conf_read(tag, PCI_COMMAND_STATUS_REG);	if (initialise) {	    class = _pci_conf_read(tag, PCI_CLASS_REG);	    cmd |= PCI_COMMAND_MASTER_ENABLE 		| PCI_COMMAND_SERR_ENABLE 		| PCI_COMMAND_PARITY_ENABLE;	    /* always enable i/o & memory space, in case this card is	       just snarfing space from the fixed ISA block and doesn't	       declare separate PCI space. Exception from this is if	       it is a bridge chip which we will initialize later */            cmd |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE;	    if (pb->fast_b2b)		cmd |= PCI_COMMAND_BACKTOBACK_ENABLE;            _pci_conf_write(tag, PCI_COMMAND_STATUS_REG, cmd);	    ltim = pd->min_gnt * 33 / 4;	    ltim = MIN (MAX (pb->def_ltim, ltim), pb->max_ltim);	    misc = _pci_conf_read (tag, PCI_BHLC_REG);	    misc = (misc & ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT))		   | ((ltim & 0xff) << PCI_LATTIMER_SHIFT);	    misc = (misc & ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT))		   | ((PCI_CACHE_LINE_SIZE & 0xff) << PCI_CACHELINE_SHIFT);	    _pci_conf_write (tag, PCI_BHLC_REG, misc);	    	    if(PCI_CLASS(class) == PCI_CLASS_BRIDGE ||	       PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_PCI || pd->bridge.child != NULL) {		    _pci_setup_devices (pd, initialise); 	    }        }    }}void_pci_businit (int init){	char *v;	tgt_putchar('P');	v = getenv("pciverbose");	if (v) {	    _pciverbose = atol(v);	}	/* intialise the PCI bridge */	if (/*init*/ 1) {		SBD_DISPLAY ("PCIH", CHKPNT_PCIH);		init = _pci_hwinit (init, &def_bus_iot, &def_bus_memt);		pci_roots = init;		if (init < 1)			return;	}	if(monarch_mode) {		int i;		struct pci_device *pb;                if (_pciverbose) {			printf("setting up %d bus\n", init);		}		for(i = 0, pb = _pci_head; i < pci_roots; i++, pb = pb->next) {			_pci_scan_dev(pb, i, 0, init);		}        	_setup_pcibuses(init);	}}static void_pci_scan_dev(struct pci_device *dev, int bus, int device, int initialise){	for(; device < 32; device++) {		_pci_query_dev (dev, bus, device, initialise);	}}static void_setup_pcibuses(int initialise){	struct pci_bus *pb;	struct pci_device *pd;	unsigned int def_ltim, max_ltim;	int i;	SBD_DISPLAY ("PCIS", CHKPNT_PCIS);	for(pb = _pci_bushead; pb != NULL; pb = pb->next) {    		if (pb->ndev == 0)			return;		if (initialise) {			/* convert largest minimum grant time to cycle count *//*XXX 66/33 Mhz */	max_ltim = pb->min_gnt * 33 / 4;        			/* now see how much bandwidth is left to distribute */			if (pb->bandwidth <= 0) {				if (_pciverbose) {					_pci_bdfprintf (pb->bus, -1, -1,					    "WARN: total bandwidth exceeded\n");				}				def_ltim = 1;			}			else {				/* calculate a fair share for each device */				def_ltim = pb->bandwidth / pb->ndev;				if (def_ltim > pb->max_lat) {				/* would exceed critical time for some device */					def_ltim = pb->max_lat;				}				/* convert to cycle count */				def_ltim = def_ltim * 33 / 4;			}			/* most devices don't implement bottom three bits */			def_ltim = (def_ltim + 7) & ~7;			max_ltim = (max_ltim + 7) & ~7;        			pb->def_ltim = MIN (def_ltim, 255);			pb->max_ltim = MIN (MAX (max_ltim, def_ltim), 255);		}	}	SBD_DISPLAY ("PCIR", CHKPNT_PCIR);	_pci_hwreinit ();	/* setup the individual device windows */	SBD_DISPLAY ("PCIW", CHKPNT_PCIW);	for(i = 0, pd = _pci_head; i < pci_roots; i++, pd = pd->next) {		_pci_setup_windows (pd);	}}/* *  Scan list of configured devices, probe and attach. */void_pci_devinit (int initialise){	SBD_DISPLAY ("PCID", CHKPNT_PCID);	if(monarch_mode) {		int i;		struct pci_device *pd;		for(i = 0, pd = _pci_head; i < pci_roots; i++, pd = pd->next) {			_pci_setup_devices (pd, initialise);		}	}}

⌨️ 快捷键说明

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