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

📄 pci.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 3 页
字号:
        setup_fixed_memory_alloc( dev );	for( t=0; t<dev->bar_count; t++ )	{	    if( fixed_memory_alloc( dev, t ) )	    {	        bar        = &dev->bar[t];	        bar->fixed = TRUE;	        /* Insert at front of list */	        pptr = bar->io ?		   &bus->io_largest_ptr :		   &bus->mem_largest_ptr;			   	        bar->next = *pptr;	        *pptr     = bar;	    }	}    }    /* BAR impact on bus prefetch */    for(i=0; i<dev_count; i++ )    {        dev = &dev_data[i];	bus = &bus_data[dev->bus];	for(t=0; t<dev->bar_count; t++)	{	    bar = &dev->bar[t];            if(!bar->prefetch)	        bus->prefetch = FALSE;	}    }    /* Alloc memory address space */    rc = alloc_space( freeio_start+pci_io_offset, freeio_end+pci_io_offset, freemem_start, freemem_end );    if( rc != OK ) return rc;    /* Alloc I/O address space    */    rc = alloc_space( 0,0, freeio_start, freeio_end );    if( rc != OK ) return rc;    /* Device impacts on bus settings and store offsets */    for( i=0; i<dev_count; i++ )    {        dev = &dev_data[i];	/* Determine device impact on bus fastb2b */	if( !(dev->status & PCI_STATUS_FBB_BIT))	{	    bus_data[dev->bus].fastb2b = FALSE;	}    }    /* Device private settings */    for( i=0; i<dev_count; i++ )    {        dev = &dev_data[i];	dev->lat_tim = arch_pci_lattim( dev );        /* Determine interrupt line */	if( dev->bus == PCI_BUS_LOCAL )	{	    /* Is it a PCI slot */	    if( arch_pci_slot( dev->dev, &slotnum ) )	    {	        dev->intline = arch_pci_slot_intline( dev->dev, dev->intpin );	    }	    else	    {	        SEARCH_KNOWN( dev, t )	        if( t == known_devs_count )		{	            return ERROR_PCI_UNKNOWN_DEVICE;		}	        else                    dev->intline = known_devs[t].intline;            }	}	else	{	    dev->intline = arch_pci_remote_intline( dev->intpin );	}    }    return OK;}    /************************************************************************ *                          fixed_memory_alloc ************************************************************************/static boolfixed_memory_alloc(    t_pci_cfg_dev *dev,    UINT32        bar_index ){    /* Determine whether this BAR has fixed memory mapping requirements */    UINT32 i;    UINT32 pos;    pos = dev->bar[bar_index].pos;    for( i=0; i<bar_reqs_count; i++ )    {        if( KNOWN_BAR( dev, pos, bar_reqs[i] ) )	{	    return TRUE;	}    }    return FALSE;}/************************************************************************ *                          setup_fixed_memory_alloc ************************************************************************/static voidsetup_fixed_memory_alloc(     t_pci_cfg_dev *dev ){    UINT32 i, t;    /* Find all BAR requests for device */    for( i=0; i<bar_reqs_count; i++ )    {        if( KNOWN_DEV( dev, bar_reqs[i] ) )	{	    /*  Found a BAR request.	     *  Now find BAR location in device data.	     */	     	    for( t=0; 		     (t < dev->bar_count) &&	             (dev->bar[t].pos != bar_reqs[i].bar.pos);		 t++ )            {	        ;            }	    if( t == dev->bar_count )	    {	        /*  Didn't find BAR (device did not report it).		 *  Increase bar count so BAR may be setup.		 */	        dev->bar_count++;	    }            /*  Copy fixed memory allocation requirements from requirements 	     *  array to the BAR in question.	     */	    memcpy( &dev->bar[t],		    &bar_reqs[i].bar,		    sizeof(t_pci_bar) );	}    }}/************************************************************************ *                          config_dev ************************************************************************/static UINT32config_dev(     t_pci_cfg_dev   *dev,		/* Device data			*/    UINT32	    memlimit,		/* Max valid mem address	*/    UINT32	    iolimit )		/* Max valid io address		*/{    UINT32 data;    UINT32 rc;    UINT32 i;    /* clear COMMAND field - some devices lock their BARs otherwise */    if( dev->bus != PCI_BUS_LOCAL &&        dev->dev != PCI_IDSEL2DEVNUM(ATLAS_IDSEL_CORE) )    {         pci_config_write32( dev->bus, dev->dev, dev->function, PCI_SC, 0);    }    /* Setup latency timer field */    rc = pci_config_write8( dev->bus, dev->dev, dev->function,			    PCI_LATTIM, dev->lat_tim );    if( rc != OK ) return rc;    /* Setup Interrupt Line field */    rc = pci_config_write8( dev->bus, dev->dev, dev->function,			    PCI_INTLINE, dev->intline );    if( rc != OK ) return rc;    /* Setup BARs */    if (!dev->alloc_err)    {        for( i=0; i<dev->bar_count; i++ )        {             t_pci_bar *bar;            bar = &dev->bar[i];	    rc = pci_config_write32( dev->bus, dev->dev, dev->function,	                             bar->pos, bar->start );	    if( rc != OK ) return rc;        }    }        /* Setup power management (if available through extended capabilities) */    if( dev->status & PCI_STATUS_CAP_BIT )    {        UINT8 cap_ptr, cap_id;        /* Determine capability pointer */	rc = pci_config_read8( dev->bus, dev->dev, dev->function,			       PCI_CAP_PTR, &cap_ptr );        if( rc != OK ) return rc;	while( (cap_ptr != 0)         && 	       ((cap_ptr & 0x3) == 0) &&   /* Must be 32 bit aligned */	       (cap_ptr >= PCI_FIRST_NON_STANDARD) )	{	    /* Read capability ID */	    rc = pci_config_read8( dev->bus, dev->dev, dev->function,			           cap_ptr + PCI_EXT_CAP_ID_OFS, &cap_id );            if( rc != OK ) return rc;	    if( cap_id == PCI_EXT_CAP_ID_PWR_MGMT )	    {	        /*  Found power management capability.		 *  Set power state to D0.		 */	        rc = pci_config_write16( dev->bus, dev->dev, dev->function,			                 cap_ptr + PCI_EXT_CAP_PWR_MGMT_STATUS_OFS,			                 PCI_EXT_CAP_PWR_MGMT_STATUS_D0 );                if( rc != OK ) return rc;	    }	    /* Next capability */	    rc = pci_config_read8( dev->bus, dev->dev, dev->function,			           cap_ptr + PCI_EXT_CAP_NEXT_PTR_OFS,			           &cap_ptr );            if( rc != OK ) return rc;	}    }    if( DEV_PPB(dev) )    {        t_pci_cfg_bus *bus;        /**** PCI-PCI Bridge ****/	/* Secondary latency timer */        rc = pci_config_write8( dev->bus, dev->dev, dev->function,			        PCI_LATTIM, dev->lat_tim );        if( rc != OK ) return rc;	    	if( sys_platform == PRODUCT_ATLASA_ID && 	    dev->bus == PCI_BUS_LOCAL &&	    dev->dev == PCI_IDSEL2DEVNUM(ATLAS_IDSEL_21150) &&	    !arch_pci_system_slot() )	{            rc = pci_config_write32( dev->bus, dev->dev, dev->function,				     PCI_IO, 0x0000FFF0 );            if( rc != OK ) return rc;	                rc = pci_config_write32( dev->bus, dev->dev, dev->function,				     PCI_MEM, 0x0000FFF0 );            if( rc != OK ) return rc;	                rc = pci_config_write32( dev->bus, dev->dev, dev->function,				     PCI_PREFMEM, 0x0000FFF0 );	    return rc;	}	/* Secondary bus data */	bus = &bus_data[dev->bus + 1];	/* Secondary I/O base and limit (bit 15:12) */	data =  ((bus->start_io & 0xF000) >> 8) << PCI_IO_BASE_SHF;	data |= ((iolimit       & 0xF000) >> 8) << PCI_IO_LIMIT_SHF;        rc = pci_config_write32( dev->bus, dev->dev, dev->function,				 PCI_IO, data );        if( rc != OK ) return rc;	    			/* I/O base and limit (bit 31:16) */	data = ((bus->start_io >> 16) << PCI_UPPERIO_BASE_SHF) |	       ((iolimit       >> 16) << PCI_UPPERIO_LIMIT_SHF);        rc = pci_config_write32( dev->bus, dev->dev, dev->function,				 PCI_UPPERIO, data );        if( rc != OK ) return rc;	            /* Secondary memory base and limit      */	if( bus->prefetch )	{	    /* Disable non-prefetchable memory */	    data = (0xFFF0 << PCI_MEM_BASE_SHF) |		   (0x0000 << PCI_MEM_LIMIT_SHF);	}	else	{	    /* Setup non-prefetchable memory (bit 31:20) */	    data =  ((bus->start_mem & 0xFFF00000) >> 16) << PCI_MEM_BASE_SHF;	    data |= ((memlimit       & 0xFFF00000) >> 16) << PCI_MEM_LIMIT_SHF;	        }        rc = pci_config_write32( dev->bus, dev->dev, dev->function,				 PCI_MEM, data );        if( rc != OK ) return rc;	    	/* Secondary prefetchable memory base and limit */	if( bus->prefetch )	{	    /* Setup prefetchable memory (bit 31:20) */	    data =  ((bus->start_mem & 0xFFF00000) >> 16) << PCI_PREFMEM_BASE_SHF;	    data |= ((memlimit       & 0xFFF00000) >> 16) << PCI_PREFMEM_LIMIT_SHF;		}	else	{    	    /* Disable prefetchable memory */	    data = (0xFFF0 << PCI_PREFMEM_BASE_SHF) |		   (0x0000 << PCI_PREFMEM_LIMIT_SHF);	}        rc = pci_config_write32( dev->bus, dev->dev, dev->function,				 PCI_PREFMEM, data );        if( rc != OK ) return rc;	    	/* Bridge control */        rc = pci_config_write16( dev->bus, dev->dev, dev->function,				 PCI_BC,				   (PCI_BCII_BC_PERR_BIT |				   PCI_BCII_BC_SERR_BIT |				   PCI_BCII_BC_MA_BIT   |				   (bus->fastb2b ? PCI_BCII_BC_FBB_BIT : 0))>>16 );        if( rc != OK ) return rc;    }    /* Setup COMMAND field */    data = PCI_SC_CMD_IOS_BIT  |	   PCI_SC_CMD_MS_BIT   |	   PCI_SC_CMD_BM_BIT   |	   PCI_SC_CMD_PERR_BIT |	   PCI_SC_CMD_SERR_BIT;    if( bus_data[dev->bus].fastb2b )        data |= PCI_SC_CMD_FBB_BIT;    if (dev->alloc_err)	data = 0;    rc = pci_config_write32( dev->bus, dev->dev, dev->function,			     PCI_SC, data );    return rc;}	      /************************************************************************ *                          alloc_space ************************************************************************/static UINT32alloc_space(    UINT32 red_start,	/* redpage, 0 -> IO space, !=0 -> memory space	*/    UINT32 red_end,    UINT32 mem_start,    UINT32 mem_end ){    UINT32	  i;    t_pci_cfg_bus *bus;    t_pci_bar	  *bar;    t_pci_bar	  *firstconfbar;    UINT32        firstconfmem;    for( i=0; i < bus_count; i++ )    {	bus = &bus_data[i];	if( red_start == 0 )	{            mem_start = align( mem_start, PCI_ALIGN_IO );	    bar = bus->io_largest_ptr;	    bus->start_io =	        ( bar && bar->fixed ) ?		    bar->start :		    mem_start;	}	else	{            mem_start = align( mem_start, PCI_ALIGN_MEM );	    bar = bus->mem_largest_ptr;	    bus->start_mem =	        ( bar && bar->fixed ) ?		    bar->start :		    mem_start;	}	/* First the fixed */	while( bar && bar->fixed )	{	    mem_start = MAX( mem_start, bar->start + bar->size );	    if( mem_start > mem_end )	        return ERROR_PCI_MALLOC;	    bar = bar->next;	}	/* Now the configurable */ 	firstconfbar = bar;	firstconfmem = mem_start;	for( ;bar; bar= bar->next )	{	    if (bar->start == 0x00000001)		continue;	    /* Alignment requirement for BAR */	    mem_start  =  align( mem_start, bar->size );	    if (mem_start == red_start)		mem_start = align( red_end, bar->size );	    if( mem_start + bar->size > mem_end )	    {		/* PCI ressource allocation trouble.		 * Something has to be removed, so we remove the		 * biggest configurable and start over again.		 */		t_pci_cfg_dev *dev;		int d, t;		for( d=0; d<dev_count; d++ )		{		    dev = &dev_data[d];		    if (firstconfbar < &dev->bar[0]) continue;		    if (firstconfbar >= &dev->bar[dev->bar_count]) continue;		    for( t=0; t<dev->bar_count; t++ )		    {			dev->bar[t].start = 0x00000001;		    }		    dev->alloc_err = TRUE;		    break;		}		pci_alloc_err = TRUE;		/* start over again */		bar = firstconfbar;		mem_start  = firstconfmem;		firstconfbar = bar->next;	    }	    else	    {		bar->start =  mem_start;		mem_start  += bar->size;	    }        }    }    return OK;}/************************************************************************ *                          align ************************************************************************/static UINT32align(    UINT32    addr,			/* Address to be aligned	*/    UINT32    alignment )		/* Alignment requirement	*/{    return (addr + alignment - 1) & ~(alignment - 1);}/************************************************************************ *                          error_lookup ************************************************************************/static INT32 error_lookup(     t_sys_error_string *param ){    UINT32 index;    index = SYSERROR_ID( param->syserror );    if( index < sizeof(error_strings)/sizeof(char*) )    {        param->strings[SYSCON_ERRORMSG_IDX] = error_strings[index];        param->count = 1;    }    else        param->count = 0;    return OK;}

⌨️ 快捷键说明

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