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

📄 pci_machdep.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
字号:
/*	$Id: pci_machdep.c,v 1.2 2002/02/28 16:03:48 patrik Exp $ *//* * Copyright (c) 2001 IP Unplugged AB (www.ipunplugged.com) *  * 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 for IP Unplugged AB, by *      Patrik Lindergren. * 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. * */#include <sys/param.h>#include <sys/device.h>#include <sys/systm.h>#include <dev/pci/pcivar.h>#include <dev/pci/pcireg.h>#include <machine/pio.h>#include <include/powerpmc230.h>#include <pmon/dev/mpc107reg.h>#include <pmon.h>#include <stdlib.h>#ifndef VA_TO_PA#define VA_TO_PA(x)	(x)#endif#ifndef PA_TO_VA#define	PA_TO_VA(x)	(x)#endif#define	_256MB		0x10000000	/* One BAT reg mapping limit */static pcireg_t pci_mem_space_pci_base;static pcireg_t pci_local_mem_pci_base;static pcireg_t pci_local_mem_isa_base;extern int _pciverbose;extern int monarch_mode;/* * Called to initialise the bridge at the beginning of time */int_pci_hwinit(initialise, iot, memt)	int initialise;	bus_space_tag_t iot;	bus_space_tag_t memt;{    struct pci_device *pd;    struct pci_bus *pb;    unsigned int cfg;        iot->bus_base = PA_TO_VA(MPC107_PCI_ISA_IO_BASE);    iot->bus_reverse = 1;    memt->bus_base = PA_TO_VA(MPC107_PCI_MEM_BASE);    memt->bus_reverse = 1;    pci_local_mem_pci_base = PCI_LOCAL_MEM_PCI_BASE;    pci_local_mem_isa_base = PCI_LOCAL_MEM_ISA_BASE;    pci_mem_space_pci_base = PCI_MEM_SPACE_PCI_BASE;    if (!initialise) {        return(0);    }    cfg = inl(CONFIG_REGISTER) & CFG_REG_MASK;    monarch_mode = CFG_REG_MONARCH(cfg) ? 1 : 0;        /*     * Initialize PCI Head device (Northbridge).     */    pd = malloc(sizeof(struct pci_device));            if(pd == NULL) {        /* Can't Alloc memory */        printf("pci: can't alloc memory for northbridge\n");        return(-1);    }    bzero((void *)pd, sizeof(struct pci_device));        pd->pa.pa_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;    pd->pa.pa_iot = iot;    pd->pa.pa_memt = memt;    _pci_head = pd;        pd->bridge.secbus = malloc(sizeof(struct pci_bus));            if(pd->bridge.secbus == NULL) {        /* Can't Alloc memory */        printf("pci: can't alloc memory for new pci bus\n");        return(-1);    }    bzero((void *)pd->bridge.secbus, sizeof(struct pci_bus));        pb = pd->bridge.secbus;    pb->max_lat = 255;    pb->fast_b2b = 1;    pb->prefetch = 1;    pb->bandwidth = 4000000;    pb->ndev = 1;    _pci_bushead = pb;        /* point to start and end of memory region */    pb->minpcimemaddr = PCI_MEM_SPACE_PCI_BASE;    pb->nextpcimemaddr = PCI_MEM_SPACE_PCI_BASE + MPC107_PCI_MEM_SIZE;    /*     * point to start and end of io region      */    pb->minpciioaddr = PCI_IO_SPACE_PCI_BASE;    pb->nextpciioaddr = PCI_IO_SPACE_PCI_BASE + MPC107_PCI_IO_SIZE;    return(1);}/* * Called to reinitialise the bridge after we've scanned each PCI device * and know what is possible. */void_pci_hwreinit (void){}void_pci_flush (void){}/* *  Map the CPU virtual address of an area of local memory to a PCI *  address that can be used by a PCI bus master to access it. */vm_offset_t_pci_dmamap(va, len)	vm_offset_t va;	unsigned int len;{	return(pci_local_mem_pci_base + VA_TO_PA (va));}/* *  Map the PCI address of an area of local memory to a CPU physical *  address. */vm_offset_t_pci_cpumap(pcia, len)	vm_offset_t pcia;	unsigned int len;{	return(pcia - pci_local_mem_pci_base);}/* *  Map the CPU virtual address of an area of local memory to an ISA *  address that can be used by a ISA bus master to access it. */vm_offset_t_isa_dmamap(va, len)	vm_offset_t va;	unsigned int len;{	unsigned long pa = VA_TO_PA (va);    /* restrict ISA DMA access to bottom 8/16MB of local memory */	if (pa + len > 0x1000000 - pci_local_mem_isa_base) {		return (vm_offset_t)-1;	}	return(pci_local_mem_isa_base + pa);}/* *  Map the ISA address of an area of local memory to a CPU physical *  address. */vm_offset_t_isa_cpumap(pcia, len)	vm_offset_t pcia;	unsigned int len;{	return(pcia - pci_local_mem_isa_base);}int_pci_canscan (pcitag_t tag){      pcitag_t dev = pci_make_tag(0, 0, 0);      if(dev == tag)	    return(0);      else	    return (1);}/* *  Get contents of PCI Mapping register and do any machine *  dependent mapping setup. */int_pci_map_port(tag, reg, port)	pcitag_t tag;	int reg;	unsigned int *port;{	pcireg_t address;    	if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {		if (_pciverbose >= 1) {			_pci_tagprintf(tag, "_pci_map_port: bad request\r\n");		}		return -1;	}    	address = _pci_conf_read(tag, reg);    	if (PCI_MAPREG_TYPE(address) != PCI_MAPREG_TYPE_IO) {		if (_pciverbose >= 1) {			_pci_tagprintf (tag, "_pci_map_port: attempt to i/o map a memory region\r\n");		}		return(-1);	}	*port = (address & PCI_MAPREG_IO_ADDR_MASK) - PCI_IO_SPACE_PCI_BASE;	return(0);}int_pci_map_io(tag, reg, vap, pap)	pcitag_t tag;	int reg;	vm_offset_t *vap;	vm_offset_t *pap;{	pcireg_t address;	vm_offset_t pa;    	if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {		if (_pciverbose >= 1) {			_pci_tagprintf(tag, "_pci_map_io: bad request\r\n");		}		return(-1);	}    	address = _pci_conf_read(tag, reg);    	if (PCI_MAPREG_TYPE(address) != PCI_MAPREG_TYPE_IO) {		if (_pciverbose >= 1) {			_pci_tagprintf (tag, "_pci_map_io: attempt to i/o map a memory region\r\n");		}		return(-1);	}	pa = (address & PCI_MAPREG_IO_ADDR_MASK) - PCI_IO_SPACE_PCI_BASE;	*pap = pa;	*vap = (vm_offset_t) PA_TO_VA (MPC107_PCI_IO_BASE + pa);    	if (_pciverbose >= 3) {		_pci_tagprintf(tag, "_pci_map_io: mapping i/o at virtual %08x, physical %08x\n", *vap, *pap);	}	return(0);}int_pci_map_mem(tag, reg, vap, pap)	pcitag_t tag;	int reg;	vm_offset_t *vap;	vm_offset_t *pap;{	pcireg_t address;	vm_offset_t pa;	if (reg == PCI_MAPREG_ROM) {	/* expansion ROM */		address = _pci_conf_read(tag, reg);		if (PCI_MAPREG_TYPE(address) != PCI_MAPREG_TYPE_ROM) {			_pci_tagprintf (tag, "_pci_map_mem: attempt to map missing rom\r\n");			return(-1);		}		pa = PCI_MAPREG_ROM_ADDR(address);	}	else {		if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {			if (_pciverbose >= 1) {				_pci_tagprintf(tag, "_pci_map_mem: bad request\r\n");			}			return(-1);		}			address = _pci_conf_read(tag, reg);			if (PCI_MAPREG_TYPE(address) != PCI_MAPREG_TYPE_MEM) {			if (_pciverbose >= 1) {				_pci_tagprintf(tag, "pci_map_mem: attempt to memory map an I/O region\r\n");			}			return(-1);		}			switch (PCI_MAPREG_MEM_TYPE(address)) {		case PCI_MAPREG_MEM_TYPE_32BIT:		case PCI_MAPREG_MEM_TYPE_32BIT_1M:			break;		case PCI_MAPREG_MEM_TYPE_64BIT:			if (_pciverbose >= 1) {				_pci_tagprintf (tag, "_pci_map_mem: attempt to map 64-bit region\r\n");			}			return(-1);		default:			if (_pciverbose >= 1) {				_pci_tagprintf (tag, "_pci_map_mem: reserved mapping type\r\n");			}			return(-1);		}		pa = address & PCI_MAPREG_MEM_ADDR_MASK;	}	/*   	 *  Physical address returned should be what the PCI bus master uses	 *  when accessing the PCI bus mem space. Therefore don't remove the	 *  PCI bus offset. Hope this doesn't break something.	 */	*pap = pa;	pa -= pci_mem_space_pci_base;	*pap = pa;	*vap = (vm_offset_t) PA_TO_VA (MPC107_PCI_MEM_BASE + pa);	if (_pciverbose >= 3) {		_pci_tagprintf (tag, "_pci_map_mem: mapping memory at virtual 0x%x, physical 0x%x\r\n", *vap, *pap);	}	return(0);}void *_pci_map_int(tag, level, func, arg)	pcitag_t tag;	int level;	int (*func) __P((void *));	void *arg;{	pcireg_t data;	int pin, bus, device;	data = _pci_conf_read(tag, PCI_INTERRUPT_REG);	pin = PCI_INTERRUPT_PIN(data);	if (pin == 0) {		/* No IRQ used. */		return NULL;	}	if (pin > 4) {		if (_pciverbose >= 1) {			_pci_tagprintf (tag, "_pci_map_int: bad interrupt pin %d\r\n", pin);		}		return(NULL);	}	_pci_break_tag (tag, &bus, &device, NULL);	if (bus != 0 || device > 5) {		return(NULL);	}	/* XXX need to work this out based on device number etc. */	_pci_tagprintf(tag, "_pci_map_int: attempt to map device %d pin %c\n", 		   device, '@' + pin);	return(NULL);}

⌨️ 快捷键说明

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