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

📄 syscon_cpu.c

📁 This product may be controlled for export purposes. You may not export, or transfer for the purpos
💻 C
📖 第 1 页 / 共 2 页
字号:
    t_syscon_obj *objects )		/* Array of SYSCON objects	*/{    UINT32 mask;    UINT32 config, config1, config2, config3, ctrl;    bool   tag_data, lladdr, watch, trace, cacheerr, errctl;    UINT32 i;        syscon_objects = objects;    /* CP0 registers */    for(i=0;i<SYSCON_CP0_REG_COUNT;i++)    {        syscon_register_generic(	    cp0_reg[i].id,	    cpu_read_cp0,  (void *)&(cp0_reg[i]),	    cpu_write_cp0, (void *)&(cp0_reg[i]) );    }    switch( sys_processor )    {      case MIPS_20Kc  :      case MIPS_25Kf  :        cp0_reg[SYSCON_DERRCTL].valid = TRUE;	cp0_reg[SYSCON_IERRCTL].valid = TRUE;	cp0_reg[SYSCON_ITAGLO ].valid = TRUE;	cp0_reg[SYSCON_IDATALO].valid = TRUE;	cp0_reg[SYSCON_DTAGLO ].valid = TRUE;	cp0_reg[SYSCON_DDATALO].valid = TRUE;	cp0_reg[SYSCON_ITAGHI ].valid = TRUE;	cp0_reg[SYSCON_IDATAHI].valid = TRUE;	cp0_reg[SYSCON_DTAGHI ].valid = TRUE;	cp0_reg[SYSCON_DDATAHI].valid = TRUE;	/* Fallthrough !! */      case MIPS_4Kc      :      case MIPS_4Kmp     :      case MIPS_4KEc     :      case MIPS_4KEc_R2  :      case MIPS_4KEmp    :      case MIPS_4KEmp_R2 :      case MIPS_4KSc     :      case MIPS_4KSd     :      case MIPS_M4K      :      case MIPS_5K       :      case MIPS_5KE      :        /* Store initial setting of CP0 CONFIG1 register */	config1      = sys_cp0_read32( R_C0_Config, R_C0_SelConfig1 );	config1_init = config1;        /* Detect whether cache/TLB is configurable */        /*  This feature is present specifically to support configuration         *  testing of the core in a lead vehicle, and is not supported         *  in any other environment.  Attempting to use this feature         *  outside of the scope of a lead vehicle is a violation of the         *  MIPS Architecture, and may cause unpredictable operation of         *  the processor.         */        mask = sys_cpu_configurability();        cache_configurable =             (mask & SYS_CPU_CONFIGURABILITY_CACHE) ?                 TRUE : FALSE;        mmu_configurable =             (mask & SYS_CPU_CONFIGURABILITY_MMU) ? 	        TRUE : FALSE;	config = sys_cp0_read32( R_C0_Config, R_C0_SelConfig );	/* TLB availability */	tlb = 	    ( (config & M_ConfigMT) >> S_ConfigMT == K_ConfigMT_TLBMMU ) ?	        TRUE : FALSE;        /* Watch */	watch =	    (config1 & M_Config1WR) ?	        TRUE : FALSE;	/* TagHi, TagLo, DataHi, DataLo */        tag_data =           ( sys_processor != MIPS_20Kc ) &&          ( sys_processor != MIPS_25Kf ) &&          ( sys_processor != MIPS_M4K  );	/* LLAddr */	lladdr = 	  ( sys_processor != MIPS_M4K ) &&	  ( sys_processor != MIPS_5K  ) &&	  ( sys_processor != MIPS_5KE );	/* CacheErr */	cacheerr =	  ( sys_processor != MIPS_4Kc      ) &&	  ( sys_processor != MIPS_4Kmp     ) &&	  ( sys_processor != MIPS_4KEc     ) &&	  ( sys_processor != MIPS_4KEc_R2  ) &&	  ( sys_processor != MIPS_4KEmp    ) &&	  ( sys_processor != MIPS_4KEmp_R2 ) &&	  ( sys_processor != MIPS_4KSc     ) &&	  ( sys_processor != MIPS_4KSd     ) &&	  ( sys_processor != MIPS_M4K      );	/* ErrCtl */	errctl =          ( sys_processor != MIPS_20Kc ) &&          ( sys_processor != MIPS_25Kf ) &&          ( sys_processor != MIPS_M4K  );	/* Release 2 */        if( sys_arch_rev >= K_ConfigAR_Rel2 )	{            cp0_reg[SYSCON_PAGEGRAIN].valid = TRUE;            cp0_reg[SYSCON_HWRENA   ].valid = TRUE;            cp0_reg[SYSCON_EBASE    ].valid = TRUE;            cp0_reg[SYSCON_INTCTL   ].valid = TRUE;            cp0_reg[SYSCON_SRSCTL   ].valid = TRUE;            cp0_reg[SYSCON_SRSMAP   ].valid = TRUE;        }	/* EJTAG */	cp0_reg[SYSCON_DEBUG    ].valid = sys_ejtag;	cp0_reg[SYSCON_DEPC     ].valid = sys_ejtag;	cp0_reg[SYSCON_DESAVE   ].valid = sys_ejtag;        /* Config1/2/3 */	cp0_reg[SYSCON_CONFIG1  ].valid = TRUE;	cp0_reg[SYSCON_CONFIG2  ].valid = (config1 & M_Config1M) ? TRUE : FALSE;		if( cp0_reg[SYSCON_CONFIG2].valid )	{	    config2 = sys_cp0_read32( R_C0_Config, R_C0_SelConfig2 );	    cp0_reg[SYSCON_CONFIG3].valid = (config2 & M_Config2M) ? TRUE : FALSE;        }	/* Trace */	if( cp0_reg[SYSCON_CONFIG3].valid )	{	    config3 = sys_cp0_read32( R_C0_Config, R_C0_SelConfig3 );	    trace =	        (config3 & M_Config3TL) ?	            TRUE : FALSE;	    cp0_reg[SYSCON_TRACECONTROL ].valid = trace;	    cp0_reg[SYSCON_TRACECONTROL2].valid = trace;	    cp0_reg[SYSCON_USERTRACEDATA].valid = trace;	    cp0_reg[SYSCON_TRACEBPC     ].valid	= trace;        }	/* Performance counters */        if( config1 & M_Config1PC )	{	    cp0_reg[SYSCON_PERFCOUNT       ].valid = TRUE;	    cp0_reg[SYSCON_PERFCOUNT_COUNT0].valid = TRUE;	    	    ctrl = sys_cp0_read32( R_C0_PerfCnt, R_C0_SelPerfCnt );	    	    if( ctrl & M_PerfCntM )	    {	        cp0_reg[SYSCON_PERFCOUNT_CTRL1 ].valid = TRUE;		cp0_reg[SYSCON_PERFCOUNT_COUNT1].valid = TRUE;			        ctrl = sys_cp0_read32( R_C0_PerfCnt, R_C0_SelPerfCnt+1 );	        if( ctrl & M_PerfCntM )		{		    cp0_reg[SYSCON_PERFCOUNT_CTRL2 ].valid = TRUE;		    cp0_reg[SYSCON_PERFCOUNT_COUNT2].valid = TRUE;		}	    }        }	break;              default :	cache_configurable = FALSE;	mmu_configurable   = FALSE;	tlb		   = TRUE;	tag_data	   = TRUE;	lladdr		   = TRUE;	watch		   = TRUE;	cacheerr	   = TRUE;	errctl		   = TRUE;	break;    }    /* Following registers are always required */    cp0_reg[SYSCON_BADVADDR].valid = TRUE;    cp0_reg[SYSCON_COUNT   ].valid = TRUE;    cp0_reg[SYSCON_COMPARE ].valid = TRUE;    cp0_reg[SYSCON_STATUS  ].valid = TRUE;    cp0_reg[SYSCON_CAUSE   ].valid = TRUE;    cp0_reg[SYSCON_EPC     ].valid = TRUE;    cp0_reg[SYSCON_PRID    ].valid = TRUE;    cp0_reg[SYSCON_CONFIG  ].valid = TRUE;    cp0_reg[SYSCON_ERROREPC].valid = TRUE;    /* Following registers are required if TLB is present */    cp0_reg[SYSCON_INDEX   ].valid = tlb;    cp0_reg[SYSCON_RANDOM  ].valid = tlb;    cp0_reg[SYSCON_ENTRYLO0].valid = tlb;    cp0_reg[SYSCON_ENTRYLO1].valid = tlb;    cp0_reg[SYSCON_CONTEXT ].valid = tlb;    cp0_reg[SYSCON_PAGEMASK].valid = tlb;    cp0_reg[SYSCON_WIRED   ].valid = tlb;    cp0_reg[SYSCON_ENTRYHI ].valid = tlb;    cp0_reg[SYSCON_XCONTEXT].valid = tlb && sys_64bit;    cp0_reg[SYSCON_TAGLO   ].valid = tag_data;    cp0_reg[SYSCON_DATALO  ].valid = tag_data;    cp0_reg[SYSCON_TAGHI   ].valid = tag_data;    cp0_reg[SYSCON_DATAHI  ].valid = tag_data;    cp0_reg[SYSCON_LLADDR  ].valid = lladdr;    cp0_reg[SYSCON_WATCHLO ].valid = watch;    cp0_reg[SYSCON_WATCHHI ].valid = watch;    cp0_reg[SYSCON_CACHEERR].valid = cacheerr;    cp0_reg[SYSCON_ERRCTL].valid   = errctl;    /* Following registers are 64 bit on a 64 bit CPU */    if (sys_64bit)    {	cp0_reg[SYSCON_ENTRYLO0].regsize = sizeof(UINT64);	cp0_reg[SYSCON_ENTRYLO1].regsize = sizeof(UINT64);	cp0_reg[SYSCON_CONTEXT].regsize = sizeof(UINT64);	cp0_reg[SYSCON_BADVADDR].regsize = sizeof(UINT64);	cp0_reg[SYSCON_ENTRYHI].regsize = sizeof(UINT64);	cp0_reg[SYSCON_EPC].regsize = sizeof(UINT64);	cp0_reg[SYSCON_LLADDR].regsize = sizeof(UINT64);	cp0_reg[SYSCON_WATCHLO].regsize = sizeof(UINT64);	cp0_reg[SYSCON_WATCHHI].regsize = sizeof(UINT64);	cp0_reg[SYSCON_XCONTEXT].regsize = sizeof(UINT64);	cp0_reg[SYSCON_DEPC].regsize = sizeof(UINT64);	cp0_reg[SYSCON_ERROREPC].regsize = sizeof(UINT64);	cp0_reg[SYSCON_DESAVE].regsize = sizeof(UINT64);    }    /**** Register objects ****/    syscon_register_generic( SYSCON_CPU_CYCLE_PER_COUNT_ID,			    syscon_uint32_read, (void *)&cycle_per_count,			    NULL,		NULL );    syscon_register_generic( SYSCON_CPU_TLB_COUNT_RESET_ID,			     syscon_uint8_read, (void *)&tlb_reset,			     NULL,		NULL );    syscon_register_generic( SYSCON_CPU_TLB_AVAIL_ID,			     syscon_bool_read,  (void *)&tlb,			     syscon_bool_write, (void *)&tlb );    syscon_register_generic( SYSCON_CPU_CACHE_CONFIGURABLE_ID,			     syscon_bool_read,  (void *)&cache_configurable,			     NULL,		NULL );    syscon_register_generic( SYSCON_CPU_MMU_CONFIGURABLE_ID,			     syscon_bool_read,  (void *)&mmu_configurable,			     NULL,		NULL );    /* MIPS32/64 specifics */    syscon_register_id_mips32( SYSCON_CPU_CP0_CONFIG1_RESET_ID,			       /* MIPS32/64 */			       cpu_cp0_config1_reset_mips32_read, NULL,			       NULL,			          NULL,			       /* Other */			       NULL,			          NULL,			       NULL,				  NULL );    syscon_register_id_mips32( SYSCON_CPU_TLB_COUNT_ID,			       /* MIPS32/64 */			       cpu_tlb_count_mips32_read, NULL,			       NULL,		          NULL,			       /* Other (assume QED RM5261) */			       cpu_tlb_count_rm5261_read, NULL,			       NULL,		          NULL );    /* Determine initial TLB entry count */    if( tlb )    {        SYSCON_read( SYSCON_CPU_TLB_COUNT_ID,		     (void *)&tlb_reset,		     sizeof(UINT8) );    }    else    {        tlb_reset = 0;    }    /* Setup clock cycles per COUNT register increment */    switch( sys_processor )    {      case MIPS_4Kc      :      case MIPS_4Kmp     :      case MIPS_4KEc     :      case MIPS_4KEc_R2  :      case MIPS_4KEmp    :      case MIPS_4KEmp_R2 :      case MIPS_4KSc     :      case MIPS_4KSd     :        cycle_per_count = MIPS4K_COUNT_CLK_PER_CYCLE;	break;      case MIPS_5K    :      case MIPS_5KE   :        cycle_per_count = MIPS5K_COUNT_CLK_PER_CYCLE;	break;      case MIPS_20Kc  :      case MIPS_25Kf  :        cycle_per_count = MIPS20Kc_COUNT_CLK_PER_CYCLE;	break;      case MIPS_M4K :        cycle_per_count = MIPSM4K_COUNT_CLK_PER_CYCLE;	break;      case QED_RM70XX : /* Assume QED RM7061A */        cycle_per_count = QED_RM7061A_COUNT_CLK_PER_CYCLE;	break;      case QED_RM52XX : /* Assume QED RM5261 */      default :         cycle_per_count = QED_RM5261_COUNT_CLK_PER_CYCLE;	break;    }}/************************************************************************ * *                          syscon_register_id_mips32 *  Description : *  ------------- * *  Function used to register SYSCON object functions for objects  *  that depend on whether CPU is MIPS32/64 or not. * *  A read and/or write function may be registered. *  A NULL function pointer indicates that the operation (read or *  write) is not allowed. * *  read_data and write_data pointers are passed to the read and write *  function. *  Return values : *  --------------- * *  None * ************************************************************************/void syscon_register_id_mips32(    t_syscon_ids   id,			 /* OBJECT ID from syscon_api.h */    /* MIPS32/MIPS64 processor */    t_syscon_func  read_mips32,		 /* MIPS32/64 read function	*/    void	   *read_data_mips32,	 /* Registered data		*/    t_syscon_func  write_mips32,	 /* MIPS32/64 write function	*/    void	   *write_data_mips32,   /* Registered data		*/    /* Other processor */    t_syscon_func  read_other,		 /* "Other CPU" read function	*/    void	   *read_data_other,	 /* Registered data		*/    t_syscon_func  write_other,	         /* "Other CPU" write function	*/    void	   *write_data_other )   /* Registered data		*/{    t_syscon_obj *obj;    obj = &syscon_objects[id];    if( sys_mips32_64 )    {        /* MIPS32/64 CPU */        obj->read       = read_mips32;	obj->read_data  = read_data_mips32;	obj->write      = write_mips32;	obj->write_data = write_data_mips32;    }    else    {        /* Not MIPS32/64 CPU */        obj->read       = read_other;	obj->read_data  = read_data_other;	obj->write      = write_other;	obj->write_data = write_data_other;    }}

⌨️ 快捷键说明

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