/* | |
* Performance Profiling routines | |
* | |
* Copyright (c) 2017 Realtek Semiconductor Corp. | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License version 2 as | |
* published by the Free Software Foundation. | |
*/ | |
#include "8192cd_cfg.h" | |
#ifdef PERF_DUMP | |
#include "romeperf.h" | |
//#include <asm/rtl865x/rtl_glue.h> | |
#define KERNEL_SYSeALLS | |
#include <asm/unistd.h> | |
#include <asm/processor.h> | |
#include <asm/uaccess.h> | |
#include <asm/rlxregs.h> | |
#ifdef CONFIG_WIRELESS_LAN_MODULE | |
#define __IRAM | |
#else | |
#define __IRAM __attribute__ ((section(".iram-gen"))) | |
#endif | |
#define __OPT_0 __attribute__((optimize("O0"))) | |
#define rtlglue_malloc(size) kmalloc(size, 0x1f0) | |
#define rtlglue_free(p) kfree(p) | |
#define rtlglue_printf panic_printk | |
enum CP3_COUNTER | |
{ | |
CP3CNT_CYCLES = 0, | |
CP3CNT_NEW_INST_FECTH, | |
CP3CNT_NEW_INST_FETCH_CACHE_MISS, | |
CP3CNT_NEW_INST_MISS_BUSY_CYCLE, | |
CP3CNT_DATA_STORE_INST, | |
CP3CNT_DATA_LOAD_INST, | |
CP3CNT_DATA_LOAD_OR_STORE_INST, | |
CP3CNT_EXACT_RETIRED_INST, | |
CP3CNT_RETIRED_INST_FOR_PIPE_A, | |
CP3CNT_RETIRED_INST_FOR_PIPE_B, | |
CP3CNT_DATA_LOAD_OR_STORE_CACHE_MISS, | |
CP3CNT_DATA_LOAD_OR_STORE_MISS_BUSY_CYCLE, | |
CP3CNT_RESERVED12, | |
CP3CNT_RESERVED13, | |
CP3CNT_RESERVED14, | |
CP3CNT_RESERVED15, | |
}; | |
/* Local variables */ | |
//static | |
uint64 tempVariable64; | |
static uint32 tempVariable32; | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
static uint32 tempVariable32_2; | |
unsigned char bCounterUsed[8]; | |
unsigned char numOfUsedCounter = 0; | |
#endif | |
static uint64 currCnt[4]; | |
unsigned int countTemp = 0xff; | |
/* Global variables */ | |
#ifdef CONFIG_WIRELESS_LAN_MODULE | |
static uint64 cnt1, cnt2; | |
static rtl8651_romeperf_stat_t romePerfStat[ROMEPERF_INDEX_MAX]; | |
static uint32 rtl8651_romeperf_inited = 0; | |
static uint32 rtl8651_romeperf_enable = TRUE; | |
#else | |
uint64 cnt1, cnt2; | |
rtl8651_romeperf_stat_t romePerfStat[ROMEPERF_INDEX_MAX]; | |
uint32 rtl8651_romeperf_inited = 0; | |
uint32 rtl8651_romeperf_enable = TRUE; | |
#endif | |
unsigned char *mapping[]= | |
{ | |
#if (PERF_DUMP_CP3_SELECT == PERF_DUMP_CP3_OLD) | |
"CP3CNT_CYCLES", | |
"CP3CNT_NEW_INST_FECTH", | |
"CP3CNT_NEW_INST_FETCH_CACHE_MISS", | |
"CP3CNT_NEW_INST_MISS_BUSY_CYCLE", | |
"CP3CNT_DATA_STORE_INST", | |
"CP3CNT_DATA_LOAD_INST", | |
"CP3CNT_DATA_LOAD_OR_STORE_INST", | |
"CP3CNT_EXACT_RETIRED_INST", | |
"CP3CNT_RETIRED_INST_FOR_PIPE_A", | |
"CP3CNT_RETIRED_INST_FOR_PIPE_B", | |
"CP3CNT_DATA_LOAD_OR_STORE_CACHE_MISS", | |
"CP3CNT_DATA_LOAD_OR_STORE_MISS_BUSY_CYCLE", | |
"CP3CNT_RESERVED12", | |
"CP3CNT_RESERVED13", | |
"CP3CNT_RESERVED14", | |
"CP3CNT_RESERVED15", | |
}; | |
#else | |
"CP3CNT_STOP_COUNT", | |
"CP3CNT_INST_FECTH", | |
"CP3CNT_ICACHE_MISS", | |
"CP3CNT_ICACHE_MISS_CYCLE", | |
"CP3CNT_STORE_INST", | |
"CP3CNT_LOAD_INST", | |
"CP3CNT_LOAD_OR_STORE_INST", | |
"CP3CNT_COMPLETE_INST", | |
"CP3CNT_CYCLES", | |
"CP3CNT_ICACHE_SOFT_MISS", | |
"CP3CNT_DCACHE_MISS", | |
"CP3CNT_DCACHE_MISS_CYCLES", | |
"CP3CNT_L2CACHE_HIT", | |
"CP3CNT_L2CACHE_HIT_CYCLES", | |
"CP3CNT_L2CACHE_MISS", | |
"CP3CNT_L2CACHE_MISS_CYCLES", | |
"CP3CNT_BRANCH_PREDICTION", | |
"CP3CNT_BRANCH_PREDICTION_MISS", | |
}; | |
#endif | |
__IRAM void CP3_COUNTER0_INIT( void ) | |
{ | |
__asm__ __volatile__ | |
( | |
"mfc0 $8, $12 \n\t" | |
"la $9, 0x80000000 \n\t" | |
"or $8, $9 \n\t" | |
"mtc0 $8, $12 \n\t" | |
: | |
: | |
:"$8","$9" | |
); | |
} | |
__IRAM uint32 CP3_COUNTER0_IS_INITED( void ) | |
{ | |
__asm__ __volatile__ | |
( | |
"mfc0 $8, $12 \n\t" | |
"la $9, tempVariable32 \n\t" | |
"sw $8, 0($9) \n\t" | |
: | |
: | |
:"$8","$9" | |
); | |
return tempVariable32; | |
} | |
__IRAM void CP3_COUNTER0_START( void ) | |
{ | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
__asm__ __volatile__ | |
( | |
"la $8, tempVariable32 \n\t" | |
"lw $8, 0($8) \n\t" | |
"ctc3 $8, $0 \n\t" | |
"la $8, tempVariable32_2 \n\t" | |
"lw $8, 0($8) \n\t" | |
"ctc3 $8, $1 \n\t" | |
"li $8, 0xf \n\t" | |
"ctc3 $8, $2 \n\t" | |
: | |
: | |
:"$8" | |
); | |
#else | |
__asm__ __volatile__ | |
( | |
"la $8, tempVariable32 \n\t" | |
"lw $8, 0($8) \n\t" | |
"ctc3 $8, $0 \n\t" | |
: | |
: | |
:"$8" | |
); | |
#endif // PERF_DUMP_CP3_DUAL_COUNTER_EN | |
} | |
__IRAM void CP3_COUNTER0_ASSIGN_EVENT( void ) | |
{ | |
#if (PERF_DUMP_CP3_SELECT == PERF_DUMP_CP3_OLD) | |
#if 1 /* Inst */ | |
tempVariable32 = /* Counter0 */((0x10|CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((0x10|CP3CNT_NEW_INST_FECTH)<< 8) | | |
/* Counter2 */((0x10|CP3CNT_NEW_INST_FETCH_CACHE_MISS)<<16) | | |
/* Counter3 */((0x10|CP3CNT_NEW_INST_MISS_BUSY_CYCLE)<<24); | |
#elif 1 /* Data (LOAD+STORE) */ | |
tempVariable32 = /* Counter0 */((0x10|CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((0x10|CP3CNT_DATA_LOAD_OR_STORE_INST)<< 8) | | |
/* Counter2 */((0x10|CP3CNT_DATA_LOAD_OR_STORE_CACHE_MISS)<<16) | | |
/* Counter3 */((0x10|CP3CNT_DATA_LOAD_OR_STORE_MISS_BUSY_CYCLE)<<24); | |
#elif 1 /* Data (STORE) */ | |
tempVariable32 = /* Counter0 */((0x10|CP3CNT_DATA_LOAD_INST)<< 0) | | |
/* Counter1 */((0x10|CP3CNT_DATA_STORE_INST)<< 8) | | |
/* Counter2 */((0x10|CP3CNT_DATA_LOAD_OR_STORE_CACHE_MISS)<<16) | | |
/* Counter3 */((0x10|CP3CNT_DATA_LOAD_OR_STORE_MISS_BUSY_CYCLE)<<24); | |
#else | |
#error | |
#endif | |
#elif (PERF_DUMP_CP3_SELECT == PERF_DUMP_CP3_NEW) | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
#if 1 /* Inst */ | |
tempVariable32 = /* Counter0 */((CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((CP3CNT_INST_FECTH)<< 8) | | |
/* Counter2 */((CP3CNT_ICACHE_MISS)<<16) | | |
/* Counter3 */((CP3CNT_ICACHE_MISS_CYCLE)<<24); | |
tempVariable32_2 = /* Counter0 */((CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((CP3CNT_INST_FECTH)<< 8) | | |
/* Counter2 */((CP3CNT_ICACHE_MISS)<<16) | | |
/* Counter3 */((CP3CNT_ICACHE_MISS_CYCLE)<<24); | |
#elif 1 /* Data (LOAD+STORE) */ | |
tempVariable32 = /* Counter0 */((CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((CP3CNT_LOAD_OR_STORE_INST)<< 8) | | |
/* Counter2 */((CP3CNT_STORE_INST)<<16) | | |
/* Counter3 */((CP3CNT_LOAD_INST)<<24); | |
#else | |
#error | |
#endif | |
#else | |
#if 1 /* Inst */ | |
tempVariable32 = /* Counter0 */((CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((CP3CNT_INST_FECTH)<< 8) | | |
/* Counter2 */((CP3CNT_ICACHE_MISS)<<16) | | |
/* Counter3 */((CP3CNT_ICACHE_MISS_CYCLE)<<24); | |
#elif 1 /* Data (LOAD+STORE) */ | |
tempVariable32 = /* Counter0 */((CP3CNT_CYCLES)<< 0) | | |
/* Counter1 */((CP3CNT_LOAD_OR_STORE_INST)<< 8) | | |
/* Counter2 */((CP3CNT_STORE_INST)<<16) | | |
/* Counter3 */((CP3CNT_LOAD_INST)<<24); | |
#else | |
#error | |
#endif | |
#endif // PERF_DUMP_CP3_DUAL_COUNTER_EN | |
#else | |
#error "PERF_DUMP_CP3_SELECT flag error" | |
#endif | |
} | |
__IRAM void CP3_COUNTER0_RESET_ONE(int cnt_num) | |
{ | |
switch(cnt_num) | |
{ | |
case 0: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $8 \n\t" | |
); | |
break; | |
case 1: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $10 \n\t" | |
); | |
break; | |
case 2: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $12 \n\t" | |
); | |
break; | |
case 3: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $14 \n\t" | |
); | |
break; | |
case 4: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $9 \n\t" | |
); | |
break; | |
case 5: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $11 \n\t" | |
); | |
break; | |
case 6: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $13 \n\t" | |
); | |
break; | |
case 7: | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $15 \n\t" | |
); | |
break; | |
default: | |
printk("CP3 RESET ERROR COUNTER = %x \n",cnt_num); | |
break; | |
} | |
} | |
__IRAM void CP3_COUNTER0_RESET( void ) | |
{ | |
__asm__ __volatile__ | |
( | |
"mtc3 $0, $8 \n\t" | |
"mtc3 $0, $9 \n\t" | |
"mtc3 $0, $10 \n\t" | |
"mtc3 $0, $11 \n\t" | |
"mtc3 $0, $12 \n\t" | |
"mtc3 $0, $13 \n\t" | |
"mtc3 $0, $14 \n\t" | |
"mtc3 $0, $15 \n\t" | |
); | |
} | |
__IRAM void CP3_COUNTER0_STOP( void ) | |
{ | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
__asm__ __volatile__ | |
( | |
"ctc3 $0, $0 \n\t" | |
"ctc3 $0, $1 \n\t" | |
); | |
#else | |
__asm__ __volatile__ | |
( | |
"ctc3 $0, $0 \n\t" | |
); | |
#endif | |
} | |
__IRAM uint64 CP3_COUNTER0_GET( void ) | |
{ | |
__asm__ __volatile__ | |
( | |
"la $8, tempVariable64 \n\t" | |
"mfc3 $9, $9 \n\t" | |
"sw $9, 0($8) \n\t" | |
"mfc3 $9, $8 \n\t" | |
"sw $9, 4($8) \n\t" | |
: | |
: | |
:"$8","$9" | |
); | |
return tempVariable64; | |
} | |
__IRAM void CP3_COUNTER0_GET_ALL( void ) | |
{ | |
__asm__ __volatile__ ( | |
"mfc3 $9, $9 \n\t" | |
"sw $9, 0x00(%0) \n\t" | |
"mfc3 $9, $8 \n\t" | |
"sw $9, 0x04(%0) \n\t" | |
"mfc3 $9, $11 \n\t" | |
"sw $9, 0x08(%0) \n\t" | |
"mfc3 $9, $10 \n\t" | |
"sw $9, 0x0C(%0) \n\t" | |
"mfc3 $9, $13 \n\t" | |
"sw $9, 0x10(%0) \n\t" | |
"mfc3 $9, $12 \n\t" | |
"sw $9, 0x14(%0) \n\t" | |
"mfc3 $9, $15 \n\t" | |
"sw $9, 0x18(%0) \n\t" | |
"mfc3 $9, $14 \n\t" | |
"sw $9, 0x1C(%0) \n\t" | |
: | |
:"r"(currCnt) | |
); | |
} | |
int32 rtl8651_romeperfInit() | |
{ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_ASSIGN_EVENT(); | |
rtl8651_romeperf_inited = TRUE; | |
rtl8651_romeperf_enable = TRUE; | |
memset( &romePerfStat, 0, sizeof( romePerfStat ) ); | |
#if (PERF_DUMP_INIT_SELECT == PERF_DUMP_INIT_ORI) | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD].desc = "NAPT add_all"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_1].desc = "NAPT add_checkIntIP"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_2].desc = "NAPT add_localServer"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_3].desc = "NAPT add_checkExtIp"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_4].desc = "NAPT add_dupCheck1"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_5].desc = "NAPT add_dupCheck2"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_6].desc = "NAPT add_bPortReused"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_7].desc = "NAPT add_routeCache"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_8].desc = "NAPT add_tooManyConn"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_9].desc = "NAPT add_initConn"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_10].desc = "NAPT add_decisionFlo"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_ADD_11].desc = "NAPT add_ambiguous"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_DEL].desc = "NAPT del"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_FIND_OUTBOUND].desc = "NATP outbound"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_FIND_INBOUND].desc = "NAPT inbound"; | |
romePerfStat[ROMEPERF_INDEX_NAPT_UPDATE].desc = "NAPT update"; | |
romePerfStat[ROMEPERF_INDEX_UNTIL_RXTHREAD].desc = "IntDispatch-RxThread"; | |
romePerfStat[ROMEPERF_INDEX_RECVLOOP].desc = "RecvLoop-FwdInput"; | |
romePerfStat[ROMEPERF_INDEX_FWDENG_INPUT].desc = "FwdEng_Input()"; | |
romePerfStat[ROMEPERF_INDEX_BEFORE_CRYPTO_ENCAP].desc = "FwdInput-Crypto(En)"; | |
romePerfStat[ROMEPERF_INDEX_ENCAP].desc = "IPSEC Encap"; | |
romePerfStat[ROMEPERF_INDEX_ENCAP_CRYPTO_ENGINE].desc = "Encap Crypto"; | |
romePerfStat[ROMEPERF_INDEX_ENCAP_AUTH_ENGINE].desc = "Encap Authtication"; | |
romePerfStat[ROMEPERF_INDEX_BEFORE_CRYPTO_DECAP].desc = "FwdInput-Crypto(De)"; | |
romePerfStat[ROMEPERF_INDEX_DECAP].desc = "IPSEC Decap"; | |
romePerfStat[ROMEPERF_INDEX_DECAP_CRYPTO_ENGINE].desc = "Decap Crypto"; | |
romePerfStat[ROMEPERF_INDEX_DECAP_AUTH_ENGINE].desc = "Decap Authtication"; | |
romePerfStat[ROMEPERF_INDEX_FASTPATH].desc = "Fast Path"; | |
romePerfStat[ROMEPERF_INDEX_SLOWPATH].desc = "Slow Path"; | |
romePerfStat[ROMEPERF_INDEX_FWDENG_SEND].desc = "FwdEngSend()"; | |
romePerfStat[ROMEPERF_INDEX_UNTIL_ACLDB].desc = "FwdInput() Until ACLDB"; | |
romePerfStat[ROMEPERF_INDEX_GET_MTU_AND_SOURCE_MAC].desc = "L3Route_MTU_srcMAC"; | |
romePerfStat[ROMEPERF_INDEX_PPTPL2TP_1].desc = "L3Route_PPTPL2TP_1"; | |
romePerfStat[ROMEPERF_INDEX_PPPOE_ARP_CACHE].desc = "L3Route_PPPoE_ArpCache"; | |
romePerfStat[ROMEPERF_INDEX_PPTPL2TP_SEND].desc = "L3Route_PptpL2tpSend()"; | |
romePerfStat[ROMEPERF_INDEX_FRAG].desc = "L3Route_Fragment"; | |
romePerfStat[ROMEPERF_INDEX_EGRESS_ACL].desc = "FwdSend_EgressACL"; | |
romePerfStat[ROMEPERF_INDEX_PPTPL2TP_ENCAP].desc = "FwdSend_PPTP/L2TP_Encap"; | |
romePerfStat[ROMEPERF_INDEX_FROM_PS].desc = "FwdSend_FromPS"; | |
romePerfStat[ROMEPERF_INDEX_EXTDEV_SEND].desc = "FwdSend_ExtDevSend()"; | |
romePerfStat[ROMEPERF_INDEX_FRAG_2ND_HALF].desc = "FwdSend_Frag_2ndHalf()"; | |
romePerfStat[ROMEPERF_INDEX_TXPKTPOST].desc = "rtl8651_txPktPostProcessing()"; | |
romePerfStat[ROMEPERF_INDEX_MBUFPAD].desc = "mBuf_padding()"; | |
romePerfStat[ROMEPERF_INDEX_TXALIGN].desc = "_swNic_txAlign"; | |
romePerfStat[ROMEPERF_INDEX_ISRTXRECYCLE].desc = "_swNic_isrTxRecycle"; | |
romePerfStat[ROMEPERF_INDEX_16].desc = "FwdEng_temp_16"; | |
romePerfStat[ROMEPERF_INDEX_17].desc = "FwdEng_temp_17"; | |
romePerfStat[ROMEPERF_INDEX_18].desc = "FwdEng_temp_18"; | |
romePerfStat[ROMEPERF_INDEX_19].desc = "FwdEng_temp_19"; | |
romePerfStat[ROMEPERF_INDEX_20].desc = "FwdEng_temp_20"; | |
romePerfStat[ROMEPERF_INDEX_21].desc = "FwdEng_temp_21"; | |
romePerfStat[ROMEPERF_INDEX_22].desc = "FwdEng_temp_22"; | |
romePerfStat[ROMEPERF_INDEX_23].desc = "FwdEng_temp_23"; | |
romePerfStat[ROMEPERF_INDEX_24].desc = "FwdEng_temp_24"; | |
romePerfStat[ROMEPERF_INDEX_25].desc = "FwdEng_temp_25"; | |
romePerfStat[ROMEPERF_INDEX_FLUSHDCACHE].desc = "rtlglue_flushDCache"; | |
romePerfStat[ROMEPERF_INDEX_IRAM_1].desc = "IRAM Cached within IRAM"; | |
romePerfStat[ROMEPERF_INDEX_IRAM_2].desc = "IRAM Uncached within IRAM"; | |
romePerfStat[ROMEPERF_INDEX_IRAM_3].desc = "test ICACHE (1024*100)"; | |
romePerfStat[ROMEPERF_INDEX_IRAM_4].desc = "test Uncached (1024*10)"; | |
romePerfStat[ROMEPERF_INDEX_DRAM_1].desc = "DRAM Cached within DRAM"; | |
romePerfStat[ROMEPERF_INDEX_DRAM_2].desc = "DRAM Uncached within DRAM"; | |
romePerfStat[ROMEPERF_INDEX_DRAM_3].desc = "test DCACHE (1024*100)"; | |
romePerfStat[ROMEPERF_INDEX_DRAM_4].desc = "test Uncached (1024*10)"; | |
romePerfStat[ROMEPERF_INDEX_BMP].desc = "KMP Algorithm"; | |
romePerfStat[ROMEPERF_INDEX_MDCMDIO].desc = "MDCMDIO PHY Register ACCESS"; | |
#elif (PERF_DUMP_INIT_SELECT == PERF_DUMP_INIT_WLAN_TRX) | |
romePerfStat[ROMEPERF_INDEX_TX_PREWORK].desc = "XMIT_PREWORK"; | |
romePerfStat[ROMEPERF_INDEX_TX_XMIT_OUT].desc = "XMIT_OUT"; | |
romePerfStat[ROMEPERF_INDEX_TX_XMIT_OUT_2].desc = "XMIT_OUT_2"; | |
romePerfStat[ROMEPERF_INDEX_RX_ONE_PKT].desc = "RX_ONE_PKT"; | |
romePerfStat[ROMEPERF_INDEX_RX_ONE_PKT_2].desc = "RX_ONE_PKT_2"; | |
romePerfStat[ROMEPERF_INDEX_TX_START_XMIT].desc = "XMT_1"; | |
romePerfStat[ROMEPERF_INDEX_TX_START_XMIT_2].desc = "XMIT_2"; | |
romePerfStat[ROMEPERF_INDEX_TX_START_XMIT_3].desc = "XMIT_3"; | |
romePerfStat[ROMEPERF_INDEX_TX_START_XMIT_4].desc = "XMIT_4"; | |
romePerfStat[ROMEPERF_INDEX_TX_START_XMIT_5].desc = "XMIT_5"; | |
#else | |
#error "PERF_DUMP_INIT_SELECT flag error" | |
#endif | |
return SUCCESS; | |
} | |
int32 rtl8651_romeperfReset() | |
{ | |
rtl8651_romeperfInit(); | |
return SUCCESS; | |
} | |
#if 0/* old fashion function, for reference only. */ | |
int32 rtl8651_romeperfStart() | |
{ | |
if ( rtl8651_romeperf_inited == FALSE ) rtl8651_romeperfInit(); | |
START_AND_GET_CP3_COUNTER0( cnt1 ); | |
return SUCCESS; | |
} | |
int32 rtl8651_romeperfStop( uint64 *pDiff ) | |
{ | |
if ( rtl8651_romeperf_inited == FALSE ) rtl8651_romeperfInit(); | |
STOP_AND_GET_CP3_COUNTER0( cnt2 ); | |
*pDiff = cnt2 - cnt1; | |
return SUCCESS; | |
} | |
#endif | |
int32 rtl8651_romeperfGet( uint64 *pGet ) | |
{ | |
if ( rtl8651_romeperf_inited == FALSE ) return FAILED; | |
/* Louis patch: someone will disable CP3 in somewhere. */ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_STOP(); | |
*pGet = CP3_COUNTER0_GET(); | |
CP3_COUNTER0_START(); | |
return SUCCESS; | |
} | |
int32 rtl8651_romeperfPause( void ) | |
{ | |
if ( rtl8651_romeperf_inited == FALSE ) return FAILED; | |
rtl8651_romeperf_enable = FALSE; | |
/* Louis patch: someone will disable CP3 in somewhere. */ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_STOP(); | |
return SUCCESS; | |
} | |
int32 rtl8651_romeperfResume( void ) | |
{ | |
if ( rtl8651_romeperf_inited == FALSE ) return FAILED; | |
rtl8651_romeperf_enable = TRUE; | |
/* Louis patch: someone will disable CP3 in somewhere. */ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_START(); | |
return SUCCESS; | |
} | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
__IRAM int32 rtl_romeperfEnterPoint_dual(uint32 index, int cnt_num,char *event) | |
{ | |
unsigned char i,j,counter; | |
/* Louis patch: someone will disable CP3 in somewhere. */ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_STOP(); | |
if ( (rtl8651_romeperf_inited == FALSE) || (rtl8651_romeperf_enable == FALSE) ) { | |
//CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
if ( index >= (sizeof(romePerfStat)/sizeof(rtl8651_romeperf_stat_t)) ) { | |
printk("CP3 index error! \n"); | |
CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
if(cnt_num + numOfUsedCounter > MAX_CP3_COUNTER) { | |
printk("Index=[%x]CP3 counter not enough, request:%x, availableCnt:%x \n",index,cnt_num,(MAX_CP3_COUNTER-numOfUsedCounter)); | |
CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
if(TRUE == romePerfStat[index].bUsed) { | |
printk("CP3 Error : reue the index=%x \n",index); | |
CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
// check reCall enter function, but not exit | |
if((countTemp!=0xff)&(countTemp != index)) | |
{ | |
romePerfStat[index].reEnterIdx = countTemp; | |
} | |
countTemp = index; | |
romePerfStat[index].numOfCount = cnt_num; | |
//printk("ENTER romePerfStat[%x].startCounter =%x \n",index,romePerfStat[index].startCounter); | |
for(i=0; i<cnt_num ;i++) | |
{ | |
counter = getAvailableCnt(); | |
romePerfStat[index].Counter[i] = counter; | |
romePerfStat[index].Event[i] = event[i]; | |
bCounterUsed[counter] = TRUE; | |
// printk("ENTER index= %x counter =[%x]requestCntNum :%x\n",index,counter,cnt_num); | |
CP3_COUNTER0_RESET_ONE(counter); | |
setEvent(counter,event[i]); | |
numOfUsedCounter++; | |
} | |
// printk("ENTER index =%x total numOfUsedCounter =%x\n",index,numOfUsedCounter); | |
romePerfStat[index].bUsed = TRUE; | |
romePerfStat[index].hasTempCycle = TRUE; | |
CP3_COUNTER0_START(); | |
return SUCCESS; | |
} | |
__IRAM int32 rtl_romeperfExitPoint_dual(uint32 index) | |
{ | |
unsigned char i,j,counter; | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_STOP(); | |
if ( (rtl8651_romeperf_inited == FALSE) || (rtl8651_romeperf_enable == FALSE) ) | |
{ | |
//CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
if ( index >= (sizeof(romePerfStat)/sizeof(rtl8651_romeperf_stat_t)) ) | |
{ | |
printk("CP3 index error! \n"); | |
CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
if ( romePerfStat[index].hasTempCycle == FALSE ) | |
{ | |
printk("CP3 EXIT error! romePerfStat[%x].hasTempCycle == FALSE \n",index); | |
CP3_COUNTER0_START(); | |
return FAILED; | |
} | |
if(countTemp == index) | |
{ | |
countTemp = 0xff; | |
} | |
CP3_COUNTER0_GET_ALL(); | |
for(i=0; i< romePerfStat[index].numOfCount; i++) | |
{ | |
counter = romePerfStat[index].Counter[i]; | |
//printk("LEAVE counter=[%x] cnt_index =%x romePerfStat[index].numOfCount =%x \n",counter,index,romePerfStat[index].numOfCount); | |
if (counter <4) { | |
romePerfStat[index].accCycle[i] += (currCnt[counter] & 0x00ffffff); | |
} else { // conter > 4 | |
romePerfStat[index].accCycle[i] += ((currCnt[counter-4]>>32) & 0x00ffffff); | |
} | |
// counter available | |
bCounterUsed[counter] = FALSE; | |
numOfUsedCounter--; | |
} | |
// printk("LEAVE numOfUsedCounter =%x \n",numOfUsedCounter); | |
romePerfStat[index].bUsed = FALSE; | |
romePerfStat[index].hasTempCycle = FALSE; | |
romePerfStat[index].executedNum++; | |
//CP3_COUNTER0_RESET_DUAL(cnt_num); | |
CP3_COUNTER0_START(); | |
return SUCCESS; | |
} | |
int getAvailableCnt(void) | |
{ | |
int i; | |
for(i=0;i<MAX_CP3_COUNTER;i++) | |
{ | |
if( bCounterUsed[i] == false) | |
{ | |
return i; | |
} | |
} | |
printk("Not avalable counter !!! \n"); | |
} | |
int setEvent(int counter,char event) | |
{ | |
if(event >= CP3_CNT_MAX) | |
{ | |
printk("Event over max = %x \n",event); | |
return FAILED; | |
} | |
if(counter < 4) | |
{ | |
tempVariable32 = (tempVariable32 & (~(0xff << (counter*8)))) | ( event << (counter*8)); | |
} | |
else | |
{ | |
tempVariable32_2 = (tempVariable32_2 & (~(0xff << ((counter-4)*8)))) | ( event << ((counter-4)*8)); | |
} | |
} | |
#else | |
__IRAM int32 rtl8651_romeperfEnterPoint( uint32 index ) | |
{ | |
if ( rtl8651_romeperf_inited == FALSE || | |
rtl8651_romeperf_enable == FALSE ) return FAILED; | |
if ( index >= (sizeof(romePerfStat)/sizeof(rtl8651_romeperf_stat_t)) ) | |
return FAILED; | |
if((countTemp!=0xff)&(countTemp != index)) | |
{ | |
romePerfStat[index].reEnterIdx = countTemp; | |
} | |
countTemp = index; | |
/* Louis patch: someone will disable CP3 in somewhere. */ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_STOP(); | |
CP3_COUNTER0_RESET(); | |
CP3_COUNTER0_GET_ALL(); | |
romePerfStat[index].tempCycle[0] = currCnt[0]; | |
romePerfStat[index].tempCycle[1] = currCnt[1]; | |
romePerfStat[index].tempCycle[2] = currCnt[2]; | |
romePerfStat[index].tempCycle[3] = currCnt[3]; | |
romePerfStat[index].hasTempCycle = TRUE; | |
CP3_COUNTER0_START(); | |
return SUCCESS; | |
} | |
__IRAM int32 rtl8651_romeperfExitPoint( uint32 index ) | |
{ | |
if ( rtl8651_romeperf_inited == FALSE || | |
rtl8651_romeperf_enable == FALSE ) return FAILED; | |
if ( index >= (sizeof(romePerfStat)/sizeof(rtl8651_romeperf_stat_t)) ) | |
return FAILED; | |
if ( romePerfStat[index].hasTempCycle == FALSE ) | |
return FAILED; | |
if((countTemp == index)||(countTemp == 0)) | |
{ | |
countTemp = 0; | |
} | |
/* Louis patch: someone will disable CP3 in somewhere. */ | |
CP3_COUNTER0_INIT(); | |
CP3_COUNTER0_STOP(); | |
CP3_COUNTER0_GET_ALL(); | |
romePerfStat[index].accCycle[0] += (currCnt[0] - romePerfStat[index].tempCycle[0]); | |
romePerfStat[index].accCycle[1] += (currCnt[1] - romePerfStat[index].tempCycle[1]); | |
romePerfStat[index].accCycle[2] += (currCnt[2] - romePerfStat[index].tempCycle[2]); | |
romePerfStat[index].accCycle[3] += (currCnt[3] - romePerfStat[index].tempCycle[3]); | |
romePerfStat[index].hasTempCycle = FALSE; | |
romePerfStat[index].executedNum++; | |
CP3_COUNTER0_RESET(); | |
return SUCCESS; | |
} | |
#endif //#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
int32 rtl8651_romeperfDump( int start, int end ) | |
{ | |
#if 0 | |
int i; | |
rtlglue_printf( "index %30s %12s %8s %10s\n", "description", "accCycle", "totalNum", "Average" ); | |
for( i = start; i <= end; i++ ) | |
{ | |
if ( romePerfStat[i].executedNum == 0 ) | |
{ | |
rtlglue_printf( "[%3d] %30s %12s %8s %10s\n", i, romePerfStat[i].desc, "--", "--", "--" ); | |
} | |
else | |
{ | |
int j; | |
rtlglue_printf( "[%3d] %30s ", | |
i, romePerfStat[i].desc ); | |
for( j =0; j < sizeof(romePerfStat[i].accCycle)/sizeof(romePerfStat[i].accCycle[0]); | |
j++ ) | |
{ | |
uint32 *pAccCycle = (uint32*)&romePerfStat[i].accCycle[j]; | |
uint32 avrgCycle = /* Hi-word */ (pAccCycle[0]*(0xffffffff/romePerfStat[i].executedNum)) + | |
/* Low-word */(pAccCycle[1]/romePerfStat[i].executedNum); | |
rtlglue_printf( "%12llu %8u %10u\n", | |
romePerfStat[i].accCycle[j], | |
romePerfStat[i].executedNum, | |
avrgCycle | |
); | |
rtlglue_printf( " %3s %30s ", "", "" ); | |
} | |
rtlglue_printf( "\r" ); | |
} | |
} | |
return SUCCESS; | |
#else | |
int i,bReturn; | |
rtl8651_romeperf_stat_t* statSnapShot = rtlglue_malloc(sizeof(rtl8651_romeperf_stat_t) * (end - start + 1) ); | |
if( statSnapShot == NULL ) | |
{ | |
rtlglue_printf("statSnapShot mem alloc failed\n"); | |
return FAILED; | |
} | |
rtlglue_printf( "index %30s %30s %12s %8s %10s %8s\n", "description","Event","accCycle", "totalNum", "Average","reENTERIdx" ); | |
for( i = start; i <= end; i++ ) | |
{ | |
int j; | |
for( j =0; j < sizeof(romePerfStat[i].accCycle)/sizeof(romePerfStat[i].accCycle[0]); j++ ) | |
{ | |
statSnapShot[i].accCycle[j] = romePerfStat[i].accCycle[j]; | |
statSnapShot[i].tempCycle[j] = romePerfStat[i].tempCycle[j]; | |
} | |
statSnapShot[i].executedNum = romePerfStat[i].executedNum; | |
statSnapShot[i].hasTempCycle = romePerfStat[i].hasTempCycle; | |
} | |
for( i = start; i < end; i++ ) | |
{ | |
if ( statSnapShot[i].executedNum == 0 ) | |
{ | |
rtlglue_printf( "[%3d] %30s %30s %12s %8s %10s %8s\n", i, romePerfStat[i].desc, "--", "--", "--", "--", "--","--" ); | |
} | |
else | |
{ | |
int j; | |
rtlglue_printf( "[%3d] %30s ", i, romePerfStat[i].desc ); | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
for( j =0; j < romePerfStat[i].numOfCount; j++ ) | |
#else | |
for( j =0; j < sizeof(statSnapShot[i].accCycle)/sizeof(statSnapShot[i].accCycle[0]); j++ ) | |
#endif //#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
{ | |
uint32 *pAccCycle = (uint32*)&statSnapShot[i].accCycle[j]; | |
uint32 avrgCycle = /* Hi-word */ (pAccCycle[0]*(0xffffffff/statSnapShot[i].executedNum)) + | |
/* Low-word */(pAccCycle[1]/statSnapShot[i].executedNum); | |
rtlglue_printf( "%30s %12llu %8u %10u %8x\n", | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
mapping[romePerfStat[i].Event[j]], | |
#else | |
mapping[getEventIndex(j)], | |
#endif //#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
statSnapShot[i].accCycle[j], | |
statSnapShot[i].executedNum, | |
avrgCycle, | |
romePerfStat[i].reEnterIdx); | |
rtlglue_printf( " %3s %30s ", "", "" ); | |
} | |
rtlglue_printf( "\r" ); | |
} | |
} | |
rtlglue_free(statSnapShot); | |
return SUCCESS; | |
#endif | |
} | |
//////////////////////////////////////////////////////////////////////////////// | |
int getEventIndex(int i) | |
{ | |
int index; | |
#if (PERF_DUMP_CP3_SELECT == PERF_DUMP_CP3_OLD) | |
index = (tempVariable32 >> (i*8))&0xf; | |
#else | |
#ifdef PERF_DUMP_CP3_DUAL_COUNTER_EN | |
if(i < 4) | |
{ | |
index = (tempVariable32 >> (i*8))&0xff; | |
} | |
else | |
{ | |
index = (tempVariable32_2 >> ((i-4)*8))&0xff; | |
} | |
#else | |
index = (tempVariable32 >> (i*8))&0xff; | |
#endif // PERF_DUMP_CP3_DUAL_COUNTER_EN | |
#endif //(PERF_DUMP_CP3_SELECT == PERF_DUMP_CP3_OLD) | |
return index; | |
} | |
#endif // PERF_DUMP | |