📄 syscon_cpu.c
字号:
/* 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; if( watch ) { if ( sys_processor == MIPS_24K ) { cp0_reg[SYSCON_IWATCHLO0].valid = TRUE; cp0_reg[SYSCON_IWATCHHI0].valid = TRUE; cp0_reg[SYSCON_IWATCHLO1].valid = TRUE; cp0_reg[SYSCON_IWATCHHI1].valid = TRUE; cp0_reg[SYSCON_DWATCHLO0].valid = TRUE; cp0_reg[SYSCON_DWATCHHI0].valid = TRUE; cp0_reg[SYSCON_DWATCHLO1].valid = TRUE; cp0_reg[SYSCON_DWATCHHI1].valid = TRUE; } else { cp0_reg[SYSCON_WATCHLO].valid = TRUE; cp0_reg[SYSCON_WATCHHI].valid = TRUE; } } 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); cp0_reg[SYSCON_L23TAGLO ].regsize = sizeof(UINT64); cp0_reg[SYSCON_L23TAGHI ].regsize = sizeof(UINT64); cp0_reg[SYSCON_L23DATALO ].regsize = sizeof(UINT64); cp0_reg[SYSCON_L23DATAHI ].regsize = sizeof(UINT64); cp0_reg[SYSCON_IWATCHLO0 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_IWATCHHI0 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_IWATCHLO1 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_IWATCHHI1 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_DWATCHLO0 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_DWATCHHI0 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_DWATCHLO1 ].regsize = sizeof(UINT64); cp0_reg[SYSCON_DWATCHHI1 ].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_24K : cycle_per_count = MIPS24K_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 + -