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

📄 pci_core.c

📁 sigma yamon yamon-src-02[1].06.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
		 */		if( write )		{		    /* Avoid writes to DeviceID and ClassCode regs */		    if (reg != PCI_ID && reg != PCI_CCREV)		    {		    	BONITO_PCI_REG(reg) = *(UINT32 *)data;		    }		}		else		{	 	   *(UINT32 *)data = BONITO_PCI_REG(reg);		}        	return OK;	    }	}	/* Clear cause register bits */	BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR);	/* Setup pattern to be used as PCI "address" for Type 0	cycle */	if( busnum == PCI_BUS_LOCAL )	{	    /* IDSEL */            data32 = 1 << PCI_DEVNUM2IDSEL(devnum);	}	else		{	    /* Bus number */	    data32 = busnum << PCI_CFG_TYPE1_BUS_SHF;	    /* Device number */	    data32 |= devnum << PCI_CFG_TYPE1_DEV_SHF;	}	/* Function (same for Type 0/1) */	data32 |= func << PCI_CFG_TYPE0_FUNC_SHF;	/* Register number (same for Type 0/1) */	data32 |= reg << PCI_CFG_TYPE0_REG_SHF;	if( busnum == PCI_BUS_LOCAL )	{	    /* Type 0 */	    BONITO_PCIMAP_CFG = data32 >> 16;	}	else	{	    /* Type 1 */	    BONITO_PCIMAP_CFG = (data32 >> 16) | 0x10000;	}	  	/* Flush Bonito register block */	BONITO_PCIMAP_CFG;	sys_sync();		/* Perform access */	if( write )	{	    REG32( KSEG1(BONITO_PCICFG_BASE) + (data32 & 0xFFFF) ) = 	        *(UINT32 *)data;	    /* Wait till done */	    while( BONITO_PCIMSTAT & 0xF );	}	else	{	    *(UINT32 *)data = 	        REG32( KSEG1(BONITO_PCICFG_BASE) + (data32 & 0xFFFF) );	}	/* Detect Master/Target abort */        if( BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR) )        {            /* Error occurred */            /* Clear bits */	    BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR);                return ERROR_PCI_ABORT;        }        return OK;      case MIPS_REVISION_CORID_QED_RM5261 :      case MIPS_REVISION_CORID_CORE_LV :      case MIPS_REVISION_CORID_CORE_FPGA :      case MIPS_REVISION_CORID_CORE_FPGAr2 :        /**** Galileo system controller ****/        /* Workaround : Galileo seems to stall if requested to access         *              device 31         */         if( (busnum == PCI_BUS_LOCAL) && (devnum == 31) )            return ERROR_PCI_ABORT;        /* Clear cause register bits */        GT_W32( sys_nb_base, GT_INTRCAUSE_OFS, 	        ~(GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT) );        /* Setup address */        GT_W32( sys_nb_base, GT_PCI0_CFGADDR_OFS,	            (busnum     << GT_PCI0_CFGADDR_BUSNUM_SHF)   |	            (devnum     << GT_PCI0_CFGADDR_DEVNUM_SHF)   |	            (func       << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |	            ((reg >> 2) << GT_PCI0_CFGADDR_REGNUM_SHF)   |	            GT_PCI0_CFGADDR_CONFIGEN_BIT );        /* Perform the access */        if( write )            GT_W32( sys_nb_base, GT_PCI0_CFGDATA_OFS, *(UINT32 *)data );        else            GT_L32( sys_nb_base, GT_PCI0_CFGDATA_OFS, *(UINT32 *)data );	        /* Check for master or target abort */        GT_L32( sys_nb_base, GT_INTRCAUSE_OFS, intr );        if( intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT) )        {            /* Error occurred */            /* Clear bits */            GT_W32( sys_nb_base, GT_INTRCAUSE_OFS, 	            ~(GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT) );                return ERROR_PCI_ABORT;        }        return OK;      case MIPS_REVISION_CORID_CORE_SYS :      case MIPS_REVISION_CORID_CORE_FPGA2 :      case MIPS_REVISION_CORID_CORE_EMUL_SYS :        /**** MIPS system controller ****/        /* Clear cause register bits */        REG(MSC01_PCI_REG_BASE, MSC01_PCI_INTSTAT) =	        MSC01_PCI_INTSTAT_MA_BIT | MSC01_PCI_INTSTAT_TA_BIT;        /* Setup address */        REG(MSC01_PCI_REG_BASE, MSC01_PCI_CFGADDR) =	            (busnum     << MSC01_PCI_CFGADDR_BNUM_SHF) |	            (devnum     << MSC01_PCI_CFGADDR_DNUM_SHF) |	            (func       << MSC01_PCI_CFGADDR_FNUM_SHF) |	            ((reg >> 2) << MSC01_PCI_CFGADDR_RNUM_SHF);	sys_sync();        /* Perform the access */        if( write )	{            REG(MSC01_PCI_REG_BASE, MSC01_PCI_CFGDATA) = *(UINT32 *)data;	    sys_sync();	}        else            *(UINT32 *)data = REG(MSC01_PCI_REG_BASE, MSC01_PCI_CFGDATA);	        /* Check for master or target abort */        intr = REG(MSC01_PCI_REG_BASE, MSC01_PCI_INTSTAT);        if( intr & (MSC01_PCI_INTSTAT_MA_BIT | MSC01_PCI_INTSTAT_TA_BIT) )        {            /* Error occurred */            /* Clear bits */            REG(MSC01_PCI_REG_BASE, MSC01_PCI_INTSTAT) =	            MSC01_PCI_INTSTAT_MA_BIT | MSC01_PCI_INTSTAT_TA_BIT ;                return ERROR_PCI_ABORT;        }        return OK;	      /* Add new core cards here */      default : /* Should never happen */	return ERROR_PCI_ABORT;    }}/************************************************************************ * *                          arch_pci_lattim *  Description : *  ------------- * *  Latency timer value to be written to PCI device (Max_Lat) * *  Return values : *  --------------- * *  Value to be written to Max_Lat. * ************************************************************************/UINT8arch_pci_lattim(     t_pci_cfg_dev *dev )	/* PCI device structure			*/{    /*  Determine latency timer     *  Special handling of Galileo System Controller.     */    return        ((dev->vendorid == PCI_VENDID_GALILEO ) && (dev->devid == PCI_DEVID_64120)) ?            MAX( dev->min_gnt, MAX(GT_LATTIM_MIN, PCI_LATTIM_FIXED) ) :            MAX( dev->min_gnt, PCI_LATTIM_FIXED );}/************************************************************************ * *                          arch_pci_multi *  Description : *  ------------- * *  Extract multi field from PCI configuration word 0xc *  (Word holding Bist/Header Type/Latency Timer/Cache Line Size) * *  Return values : *  --------------- * *  multi field * ************************************************************************/UINT8arch_pci_multi(     t_pci_cfg_dev *dev,    UINT32	  bhlc ){    /*  Special handling of Galileo System Controller :     *  It is a multi function device, but we only use function 0.     */    if( (dev->vendorid == PCI_VENDID_GALILEO ) &&        (dev->devid    == PCI_DEVID_64120) )    {        return 0;    }    else        return (bhlc & PCI_BHLC_MULTI_MSK) >> PCI_BHLC_MULTI_SHF;}/************************************************************************ *  Implementation : Static functions ************************************************************************//************************************************************************ *                          config_bonito64 ************************************************************************/static UINT32config_bonito64( void ){    UINT32 cmd;    UINT32 line;    UINT32 mask, trans;      /* Map PCI addresses transparently */    mask  =  ~((sys_ramsize >> (BONITO_PCIMEMBASECFG_ASHIFT+1)) - 1);    trans =  ~mask + 1;    mask  &= (BONITO_PCIMEMBASECFG_MEMBASE0_MASK >> 	      BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT);    trans &= (BONITO_PCIMEMBASECFG_MEMBASE0_TRANS >> 	      BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT);    BONITO_PCIMEMBASECFG =        (mask  << BONITO_PCIMEMBASECFG_MEMBASE0_MASK_SHIFT)  | 	(0     << BONITO_PCIMEMBASECFG_MEMBASE0_TRANS_SHIFT) |         (mask  << BONITO_PCIMEMBASECFG_MEMBASE1_MASK_SHIFT)  |	(trans << BONITO_PCIMEMBASECFG_MEMBASE1_TRANS_SHIFT) |        (sys_cpu_cache_coherency ?	    (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |	     BONITO_PCIMEMBASECFG_MEMBASE1_CACHED) : 0);    /*  If CPU is big endian, we need to handle endianness due to     *  PCI being little endian.     *     *  We have chosen the following setup of Bonito64      *  (through BONGENCFG register) :     *     *  PCI device doing DMA :     *     *      Bonito64 swaps byte lanes.     *     *  CPU accesses PCI device :     *     *      Bonito64 does NOT swap byte lanes.      *     *      This means that software must do the following :     *     *      Word access     : Do nothing.     *      Halfword access : Software must invert bit 1 of address.     *      Byte access     : Software must invert 2 msb of address.     */    /*  Enable IOBC and configure byteswapping */    BONITO_BONGENCFG =        BONITO_BONGENCFG	  |#ifdef EB        BONITO_BONGENCFG_BYTESWAP |#endif        BONITO_BONGENCFG_UNCACHED |	BONITO_BONGENCFG_SNOOPEN  |	(sys_cpu_cache_coherency ?	    (BONITO_BONGENCFG_WBEHINDEN | BONITO_BONGENCFG_PREFETCHEN) :	    0);    /* Invalidate lines */    for( line = 0; line < 4; line ++ )    {        cmd = (0    << BONITO_PCICACHECTRL_CACHECMD_SHIFT)     |	      (line << BONITO_PCICACHECTRL_CACHECMDLINE_SHIFT);        BONITO_PCICACHECTRL = cmd;        BONITO_PCICACHECTRL = cmd | BONITO_PCICACHECTRL_CMDEXEC;        while(BONITO_PCICACHECTRL & BONITO_PCICACHECTRL_CMDEXEC)        {            ;        }        BONITO_PCICACHECTRL = cmd;    }    return OK;}/************************************************************************ *                          config_gt64120 ************************************************************************/static UINT32config_gt64120( void ){    UINT32 rc;    UINT32 data, bare;    /**** Setup GT64120 BAR ****/    /* Disable all BARs except SCS30 and SCS10 */    bare =         GT_PCI0_BARE_SWSCS3BOOTDIS_BIT |	GT_PCI0_BARE_SWSCS32DIS_BIT    |	GT_PCI0_BARE_SWSCS10DIS_BIT    |	GT_PCI0_BARE_INTIODIS_BIT      |	GT_PCI0_BARE_INTMEMDIS_BIT     |	GT_PCI0_BARE_CS3BOOTDIS_BIT    |	GT_PCI0_BARE_CS20DIS_BIT;    /* Check range and calc mask for GT bank size registers */    if( scs10_size != 0 )    {        rc = pci_check_range( scs10_start, scs10_size, &data );        if( rc != OK ) return rc;        /* Write BAR size register */        GT_W32( sys_nb_base, GT_PCI0_BS_SCS10_OFS, data );    }    else        bare |= GT_PCI0_BARE_SCS10DIS_BIT;    if( scs32_size != 0 )    {        rc = pci_check_range( scs32_start, scs32_size, &data );        if( rc != OK ) return rc;        /* Write BAR size register */        GT_W32( sys_nb_base, GT_PCI0_BS_SCS32_OFS, data );    }    else        bare |= GT_PCI0_BARE_SCS32DIS_BIT;    GT_W32( sys_nb_base, GT_PCI0_BARE_OFS, bare );    return OK;}/************************************************************************ *                          gt_calc_range ************************************************************************/static voidgt_calc_range(     UINT32 ld,    UINT32 hd,    UINT32 *start,    UINT32 *size ){    UINT32 end;    GT_L32( sys_nb_base, ld, *start );    GT_L32( sys_nb_base, hd, end );    /* TBD : Remove "magic" numbers */    *start = (*start & 0x7FFF)  << 21;    end    = ((end & 0x7F) + 1) << 21;    *size  = (end > *start) ? end - *start : 0;}/************************************************************************ *                          config_sysctrl ************************************************************************/static UINT32config_sysctrl( void ){    /*  If CPU is big endian, we need to handle endianness due to     *  PCI being little endian.     *     *  We have chosen the following setup of MSC01     *     *  PCI device doing DMA :     *      MSC01 swaps byte lanes.     *     *  CPU accesses PCI device :     *      MSC01 does NOT swap byte lanes.      *     *      This means that software must do the following :     *     *      Word access     : Do nothing.     *      Halfword access : Software must invert bit 1 of address.     *      Byte access     : Software must invert 2 msb of address.     *     *  Above setup has been completed in msc01_core.S     */    /* Set up changes since early setup in msc01_core.S */    REG(MSC01_PCI_REG_BASE, MSC01_PCI_BAR0) = -sc_calc_pwr2(sys_ramsize);    return OK;}/************************************************************************ *                          sc_calc_pwr2ramsize *  Calculate least size in power of 2 that can hold arg ************************************************************************/static UINT32sc_calc_pwr2( UINT32 arg ){    UINT32 mysize;    for ( mysize = 1; mysize < arg; mysize <<= 1) ;    return mysize;}

⌨️ 快捷键说明

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