/** * @file debug.c * @brief DebugModule * @author chenrixin@zh-jieli.net * @version 0.1.00 * @date 2016-10-27 */ #include "system/includes.h" #include "asm/debug.h" #include "asm/p33.h" #include "asm/clock.h" #include "asm/crc16.h" #include "asm/power_interface.h" #include "asm/sfc_norflash_api.h" #include "asm/system_reset_reason.h" #include "system/boot.h" #include "app_config.h" #include "fs/fs.h" #define EXPCPTION_IN_SRAM 0 //如果出现死机不复位的情况务必需要打开,防止flash挂了,进入异常函数失败复位不了 #define DEBUG_UART JL_UART2 //debug串口 extern const char *os_current_task_rom(); extern void log_output_release_deadlock(void); extern void exception_irq_handler(); extern void sdtap_init(u32 ch); extern void __wdt_clear(void); extern void __cpu_reset(void); static u8 debug_index; static const char *const debug_msg[32] = { /*0---7*/ "wdt_timout_err", "prp_rd_mmu_err", "prp_wr_limit_err", "prp_wr_mmu_err", "axi_rd_inv", "axi_wr_inv", "c1_rd_mmu_expt", "c0_rd_mmu_expt", /*8---15*/ "c1_wr_mmu_expt", "c0_wr_mmu_expt", "c1_pc_limit_err_r", "c1_wr_limit_err_r", "c0_pc_limit_err_r", "c0_wr_limit_err_r", "dmc_pnd", "dbg_pnd", /*16---23*/ "c1_if_bus_inv", "c1_rd_bus_inv", "c1_wr_bus_inv", "c0_if_bus_inv", "c0_rd_bus_inv", "c0_wr_bus_inv", "reserved", "reserved", /*24---31*/ "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", }; static const char *const emu_msg[32] = { "reserved", //31 "reserved", //30 "reserved", //29 "reserved", //28 "reserved", //27 "reserved", //26 "reserved", //25 "reserved", //24 "reserved", //23 "reserved", //22 "reserved", //21 "fpu_ine_err", //20 "fpu_huge_err", //19 "fpu_tiny", //18 "fpu_inf_err", //17 "fpu_inv_err", //16 "reserved", //15 "reserved", //14 "reserved", //13 "reserved", //12 "reserved", //11 "reserved", //10 "reserved", //9 "etm_wp0_err", //8 "reserved", //7 "reserved", //6 "reserved", //5 "reserved", //4 "stackoverflow", //3 "div0_err", //2 "illeg_err", //1 "misalign_err", //0 }; #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH static u32 exception_log_flash_addr sec(.volatile_ram); static char exception_log_buf[640]; #define LOG_PATH "mnt/sdfile/EXT_RESERVED/log" static int get_exception_log_flash_addr(void) { struct vfs_attr file_attr; FILE *fp = fopen(LOG_PATH, "r"); if (fp == NULL) { return -1; } fget_attrs(fp, &file_attr); fclose(fp); exception_log_flash_addr = file_attr.sclust; exception_log_buf[0] = -1; sdfile_reserve_zone_read(exception_log_buf, exception_log_flash_addr, sizeof(exception_log_buf), 0); if (exception_log_buf[0] != -1) { printf("last exception log : \n%s\n", exception_log_buf); sdfile_reserve_zone_erase(exception_log_flash_addr, SDFILE_SECTOR_SIZE, 0); } memset(exception_log_buf, 0, sizeof(exception_log_buf)); return 0; } platform_initcall(get_exception_log_flash_addr); static void write_exception_log_to_flash(void *data, u32 len) { extern void set_os_init_flag(u8 value); set_os_init_flag(0); extern void norflash_set_write_cpu_hold(u8 hold_en); norflash_set_write_cpu_hold(0); /* sdfile_reserve_zone_erase(exception_log_flash_addr, SDFILE_SECTOR_SIZE, 0); */ sdfile_reserve_zone_write(data, exception_log_flash_addr, len, 0); } #endif //使用此功能必须确保软件上没有出现异常的可能性,电源供电必须足够稳定 #ifdef CONFIG_EXCEPTION_AUTO_FIX_ENABLE #define FIX_PATH "mnt/sdfile/EXT_RESERVED/fix" #define EXCEPTION_FIX_MAGIC 0x3CE8A924 #define EXCEPTION_FIX_INFO_OFFSET 1024 #define EXCEPTION_FIX_CRC_OFFSET 512 #define EXCEPTION_FIX_MAX_STEP 2 //取以下MAX STEP的最大值 #define EXCEPTION_FIX_VDDIOM_MAX_STEP 2 #define EXCEPTION_FIX_VDDIOW_MAX_STEP 0 #define EXCEPTION_FIX_VDC14_MAX_STEP 0 #define EXCEPTION_FIX_SYSVDD_MAX_STEP 1 #define EXCEPTION_FIX_SDRAM_CLK_MAX_STEP 1 struct exception_fix_info_t { u32 sdram_clock; u32 sys_clock; u8 sdram_clock_fix_step; u8 sys_clock_fix_step; u8 vddiom; u8 vddiom_fix_step; u8 vddiow; u8 vddiow_fix_step; u8 vdc14; u8 vdc14_fix_step; u8 sysvdd; u8 sysvdd_fix_step; }; static u32 exception_fix_flash_addr sec(.volatile_ram); int exception_auto_fix_config(void) { struct vfs_attr file_attr; struct exception_fix_info_t *info; u16 crc; FILE *fp = fopen(FIX_PATH, "r"); if (fp == NULL) { return -1; } fget_attrs(fp, &file_attr); fclose(fp); exception_fix_flash_addr = file_attr.sclust; u32 *buf = zalloc(1024 * 4); if (!buf) { return -1; } if (sdfile_reserve_zone_read(buf, exception_fix_flash_addr, 1024 * 4, 0) != 1024 * 4) { goto __exit; } info = (struct exception_fix_info_t *)&buf[EXCEPTION_FIX_INFO_OFFSET / sizeof(u32)]; crc = CRC16(info, sizeof(struct exception_fix_info_t)); if (crc != (buf[EXCEPTION_FIX_CRC_OFFSET / sizeof(u32)] & 0xffff) || info->sdram_clock > clk_get("sdram") || info->sdram_clock < 120 * 1000000 || info->vddiom < TCFG_LOWPOWER_VDDIOM_LEVEL || info->vddiom > VDDIOM_VOL_MAX || info->vddiow < TCFG_LOWPOWER_VDDIOW_LEVEL || info->vddiow > VDDIOW_VOL_MAX || info->vdc14 < VDC14_VOL_SEL_LEVEL || info->vdc14 > VDC14_VOL_SEL_MAX || info->sysvdd < SYSVDD_VOL_SEL_LEVEL || info->sysvdd > SYSVDD_VOL_SEL_MAX) { memset(info, 0, sizeof(struct exception_fix_info_t)); info->sdram_clock = clk_get("sdram"); info->vddiom = TCFG_LOWPOWER_VDDIOM_LEVEL; info->vddiow = TCFG_LOWPOWER_VDDIOW_LEVEL; info->vdc14 = VDC14_VOL_SEL_LEVEL; info->sysvdd = SYSVDD_VOL_SEL_LEVEL; } if (buf[0] != 0xffffffff) { printf("find exception fix flag"); sdfile_reserve_zone_erase(exception_fix_flash_addr, SDFILE_SECTOR_SIZE, 0); #if 0 //此等待延时是为了避免插拔上电不稳定导致的异常从而误触发 if (crc == (buf[EXCEPTION_FIX_CRC_OFFSET / sizeof(u32)] & 0xffff)) { sdfile_reserve_zone_write(&crc, exception_fix_flash_addr + EXCEPTION_FIX_CRC_OFFSET, sizeof(crc), 0); sdfile_reserve_zone_write(info, exception_fix_flash_addr + EXCEPTION_FIX_INFO_OFFSET, sizeof(struct exception_fix_info_t), 0); os_time_dly(100); sdfile_reserve_zone_erase(exception_fix_flash_addr, SDFILE_SECTOR_SIZE, 0); } #endif if (buf[0] == EXCEPTION_FIX_MAGIC && system_reset_reason_get() == SYS_RST_SOFT) { for (int i = 0; i <= EXCEPTION_FIX_MAX_STEP; ++i) { if (info->vddiom_fix_step < i && info->vddiom_fix_step < EXCEPTION_FIX_VDDIOM_MAX_STEP) { info->vddiom_fix_step++; info->vddiom++; break; } if (info->sysvdd_fix_step < i && info->sysvdd_fix_step < EXCEPTION_FIX_SYSVDD_MAX_STEP) { info->sysvdd_fix_step++; info->sysvdd++; break; } if (info->vddiow_fix_step < i && info->vddiow_fix_step < EXCEPTION_FIX_VDDIOW_MAX_STEP) { info->vddiow_fix_step++; info->vddiow++; break; } if (info->vdc14_fix_step < i && info->vdc14_fix_step < EXCEPTION_FIX_VDC14_MAX_STEP) { info->vdc14_fix_step++; info->vdc14++; break; } //最后才降sdram时钟 if (i == EXCEPTION_FIX_MAX_STEP) { if (info->sdram_clock_fix_step < i && info->sdram_clock_fix_step < EXCEPTION_FIX_SDRAM_CLK_MAX_STEP) { u32 sdram_clk_tab[4] = {120 * 1000000, 160 * 1000000, 192 * 1000000, 240 * 1000000}; for (int k = ARRAY_SIZE(sdram_clk_tab) - 1; k >= 0; --k) { if (sdram_clk_tab[k] == clk_get("sdram") && info->sdram_clock_fix_step < k) { info->sdram_clock_fix_step++; info->sdram_clock = sdram_clk_tab[k - info->sdram_clock_fix_step]; break; } } break; } } } crc = CRC16(info, sizeof(struct exception_fix_info_t)); buf[EXCEPTION_FIX_CRC_OFFSET / sizeof(u32)] = crc; } if (crc == (buf[EXCEPTION_FIX_CRC_OFFSET / sizeof(u32)] & 0xffff)) { sdfile_reserve_zone_write(&crc, exception_fix_flash_addr + EXCEPTION_FIX_CRC_OFFSET, sizeof(crc), 0); sdfile_reserve_zone_write(info, exception_fix_flash_addr + EXCEPTION_FIX_INFO_OFFSET, sizeof(struct exception_fix_info_t), 0); } } if (info->vddiom > TCFG_LOWPOWER_VDDIOM_LEVEL && info->vddiom < VDDIOM_VOL_MAX) { printf("exception fix vddiom : %d", info->vddiom); VDDIOM_VOL_SEL(info->vddiom); } if (info->vddiow > TCFG_LOWPOWER_VDDIOW_LEVEL && info->vddiow < VDDIOW_VOL_MAX) { printf("exception fix vddiow : %d", info->vddiow); VDDIOW_VOL_SEL(info->vddiow); } if (info->vdc14 > VDC14_VOL_SEL_LEVEL && info->vdc14 < VDC14_VOL_SEL_MAX) { printf("exception fix vdc14 : %d", info->vdc14); VDC14_VOL_SEL(info->vdc14); } if (info->sysvdd > SYSVDD_VOL_SEL_LEVEL && info->vdc14 < SYSVDD_VOL_SEL_MAX) { printf("exception fix sysvdd : %d", info->sysvdd); SYSVDD_VOL_SEL(info->sysvdd); } if (info->sdram_clock < clk_get("sdram")) { printf("exception fix sdram clock : %d", info->sdram_clock); sdram_clock_set(info->sdram_clock); } __exit: free(buf); return 0; } static void write_exception_fix_to_flash(void) { extern void set_os_init_flag(u8 value); set_os_init_flag(0); struct vm_info vm = {0}; norflash_ioctl(NULL, IOCTL_GET_VM_INFO, (u32)&vm); if (!exception_fix_flash_addr || exception_fix_flash_addr < vm.vm_saddr + vm.vm_size) { return; } u32 magic = EXCEPTION_FIX_MAGIC; extern void norflash_set_write_cpu_hold(u8 hold_en); norflash_set_write_cpu_hold(0); sdfile_reserve_zone_write(&magic, exception_fix_flash_addr, sizeof(magic), 0); } #endif static void trace_call_stack(int *len) { for (int c = 0; c < CPU_CORE_NUM; c++) { printf("CPU%d %x --> %x --> %x --> %x\n", c, q32DSP(c)->ETM_PC3, q32DSP(c)->ETM_PC2, q32DSP(c)->ETM_PC1, q32DSP(c)->ETM_PC0); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH *len += snprintf(exception_log_buf + *len, sizeof(exception_log_buf) - *len, "CPU%d %x --> %x --> %x --> %x\r\n", c, q32DSP(c)->ETM_PC3, q32DSP(c)->ETM_PC2, q32DSP(c)->ETM_PC1, q32DSP(c)->ETM_PC0); #endif } } #if EXPCPTION_IN_SRAM AT(.volatile_ram_code) static char excep_str[] = "\n\n---------------------exception error ------------------------\n"; AT(.volatile_ram_code) static char debug_msg_str[32][32] = { /*0---7*/ "wdt_timout_err", "prp_rd_mmu_err", "prp_wr_limit_err", "prp_wr_mmu_err", "axi_rd_inv", "axi_wr_inv", "c1_rd_mmu_expt", "c0_rd_mmu_expt", /*8---15*/ "c1_wr_mmu_expt", "c0_wr_mmu_expt", "c1_pc_limit_err_r", "c1_wr_limit_err_r", "c0_pc_limit_err_r", "c0_wr_limit_err_r", "dmc_pnd", "dbg_pnd", /*16---23*/ "c1_if_bus_inv", "c1_rd_bus_inv", "c1_wr_bus_inv", "c0_if_bus_inv", "c0_rd_bus_inv", "c0_wr_bus_inv", "reserved", "reserved", /*24---31*/ "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", "reserved", }; extern void putbyte(char a); AT(.volatile_ram_code) static void uart_putchar(char a) { if (DEBUG_UART->CON0 & BIT(0)) { if (a == '\n') { DEBUG_UART->CON0 |= BIT(13); DEBUG_UART->BUF = '\r'; __asm_csync(); while ((DEBUG_UART->CON0 & BIT(15)) == 0); } DEBUG_UART->CON0 |= BIT(13); DEBUG_UART->BUF = a; __asm_csync(); while ((DEBUG_UART->CON0 & BIT(15)) == 0); } } AT(.volatile_ram_code) static void putbuffer(char *buf) { while (*buf != 0) { uart_putchar(*buf++); } } AT(.volatile_ram_code) static void puthex(int hex) { uart_putchar(' '); uart_putchar('0'); uart_putchar('x'); for (char i = 28, p = 0, f = 0; i >= 0; i -= 4) { p = (char)(hex >> i) & 0xF; if (p || f || i == 0) { f = 1; uart_putchar(p > 9 ? ('A' + (p - 10)) : ('0' + p)); } } } AT(.volatile_ram_code) static void putretis(unsigned int reti, unsigned int rets) { uart_putchar('r'); uart_putchar('e'); uart_putchar('t'); uart_putchar('i'); uart_putchar(':'); puthex(reti); uart_putchar('\n'); uart_putchar('r'); uart_putchar('e'); uart_putchar('t'); uart_putchar('s'); uart_putchar(':'); puthex(rets); uart_putchar('\n'); } AT(.volatile_ram_code) static void putstrandhex(char c0, char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, int hex, int hex1) { char bf[10]; bf[0] = c0, bf[1] = c1, bf[2] = c2, bf[3] = c3, bf[4] = c4, bf[5] = c5, bf[6] = c6, bf[7] = c7, bf[8] = c8, bf[9] = c9; for (int i = 0; i < sizeof(bf); i++) { if (bf[i]) { uart_putchar(bf[i]); } } puthex(hex); if (hex1) { puthex(hex1); } uart_putchar('\n'); } AT(.volatile_ram_code) static void putpchex(int cpu_id) { q32DSP(!cpu_id)->CMD_PAUSE = -1; if (cpu_id) { corex2(0)->C0_CON &= ~BIT(3); corex2(0)->C0_CON |= BIT(1); } else { corex2(0)->C1_CON &= ~BIT(3); corex2(0)->C1_CON |= BIT(1); } putstrandhex('e', 'r', 'r', ' ', 'C', 'P', 'U', '0' + cpu_id, 0, 0, cpu_id, 0); for (int c = 0; c < CPU_CORE_NUM; c++) { uart_putchar('C'); uart_putchar('P'); uart_putchar('U'); uart_putchar('0' + c); uart_putchar(':'); puthex(q32DSP(c)->ETM_PC3); uart_putchar(' '); uart_putchar('-'); uart_putchar('-'); uart_putchar('>'); puthex(q32DSP(c)->ETM_PC2); uart_putchar(' '); uart_putchar('-'); uart_putchar('-'); uart_putchar('>'); puthex(q32DSP(c)->ETM_PC1); uart_putchar(' '); uart_putchar('-'); uart_putchar('-'); uart_putchar('>'); puthex(q32DSP(c)->ETM_PC0); uart_putchar('\n'); } } AT(.volatile_ram_code) static void putdebugreg(void) { putstrandhex('D', 'B', 'G', '_', 'M', 'S', 'G', ':', 0, 0, corex2(0)->DBG_MSG, 0); for (int i = 0, j = 0, num = 0; i < 32; i++) { if (BIT(i) & corex2(0)->DBG_MSG) { j = 0; if (i == 2 || i == 11 || i == 13) { num = j == 2 ? corex2(0)->PRP_WR_LIMIT_ERR_NUM : (j == 11 ? corex2(0)->C1_WR_LIMIT_ERR_NUM : corex2(0)->C0_WR_LIMIT_ERR_NUM); while (!(num & BIT(j)) && ++j < 8); putstrandhex('W', 'R', '_', 'L', 'I', 'M', 'I', 'T', 'L', ':', ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); } else if (i == 10 || i == 12) { putstrandhex('P', 'C', '_', 'L', 'M', 'T', '0', 'L', '-', 'H', corex2(0)->PC_LIMIT0_L, corex2(0)->PC_LIMIT0_H); putstrandhex('P', 'C', '_', 'L', 'M', 'T', '1', 'L', '-', 'H', corex2(0)->PC_LIMIT1_L, corex2(0)->PC_LIMIT1_H); } else if (i == 14) { putstrandhex('S', 'D', 'R', ' ', 'D', 'B', 'G', 'I', 'N', 'F', JL_SDR->DBG_INFO, 0); putstrandhex('S', 'D', 'R', ' ', 'D', 'B', 'G', 'A', 'D', 'R', JL_SDR->DBG_ADR, 0); putstrandhex('S', 'D', 'R', ' ', 'D', 'B', 'G', 'S', 'T', 'A', JL_SDR->DBG_START, 0); putstrandhex('S', 'D', 'R', ' ', 'D', 'B', 'G', 'E', 'N', 'D', JL_SDR->DBG_END, 0); } else if (i == 15) { putstrandhex('A', 'X', 'I', '_', 'L', 'M', 'T', 'L', '_', 'H', JL_DBG->LIMIT_L, JL_DBG->LIMIT_H); putstrandhex('W', 'R', '_', 'A', 'L', 'W', ' ', 'I', 'D', '0', JL_DBG->WR_ALLOW_ID0, 0); putstrandhex('W', 'R', '_', 'A', 'L', 'W', ' ', 'I', 'D', '1', JL_DBG->WR_ALLOW_ID1, 0); putstrandhex('W', 'R', '_', 'L', 'M', 'T', ' ', 'I', 'D', ':', JL_DBG->WR_ALLOW_ID0, 0); } uart_putchar('R'); uart_putchar('e'); uart_putchar('a'); uart_putchar('s'); uart_putchar('o'); uart_putchar('n'); uart_putchar(':'); putbuffer((char *)&debug_msg_str[i]); } } uart_putchar('\n'); uart_putchar('\n'); } AT(.volatile_ram_code) ___interrupt static void exception_analyze_sram(void) { #if 0 u32 rets, reti, cpu_id; __asm__ volatile("%0 = rets ;" : "=r"(rets)); __asm__ volatile("%0 = reti ;" : "=r"(reti)); __asm__ volatile("%0 = cnum" : "=r"(cpu_id) ::); putbuffer(excep_str); putretis(reti, rets); putpchex(cpu_id); putdebugreg(); #endif __wdt_clear(); __cpu_reset(); } #endif void exception_analyze(int *sp) { int len = 0; log_output_release_deadlock(); printf("\r\n\r\n---------------------exception error ------------------------\r\n\r\n"); u32 cpu_id = current_cpu_id(); if (cpu_id == 0) { q32DSP(1)->CMD_PAUSE = -1; corex2(0)->C1_CON &= ~BIT(3) ; corex2(0)->C1_CON |= BIT(1) ; printf("CPU1 run addr = 0x%x \n", q32DSP(1)->PCRS); printf("cpu 0 %s DEBUG_MSG = 0x%x, EMU_MSG = 0x%x C0_CON=%x\n", __func__, corex2(0)->DBG_MSG, q32DSP(0)->EMU_MSG, corex2(0)->C0_CON); } else { q32DSP(0)->CMD_PAUSE = -1; corex2(0)->C0_CON &= ~BIT(3) ; corex2(0)->C0_CON |= BIT(1) ; printf("CPU0 run addr = 0x%x \n", q32DSP(0)->PCRS); printf("cpu 1 %s DEBUG_MSG = 0x%x, EMU_MSG = 0x%x C1_CON=%x\n", __func__, corex2(0)->DBG_MSG, q32DSP(1)->EMU_MSG, corex2(0)->C1_CON); } #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "CPU%d run addr = 0x%x\r\ncpu %d DEBUG_MSG = 0x%x, EMU_MSG = 0x%x C%d_CON=%x\r\n", !cpu_id, q32DSP(!cpu_id)->PCRS, cpu_id, corex2(0)->DBG_MSG, q32DSP(0)->EMU_MSG, cpu_id, cpu_id ? corex2(0)->C1_CON : corex2(0)->C0_CON); #endif trace_call_stack(&len); unsigned int reti = sp[16]; unsigned int rete = sp[17]; unsigned int retx = sp[18]; unsigned int rets = sp[19]; unsigned int psr = sp[20]; unsigned int icfg = sp[21]; unsigned int usp = sp[22]; unsigned int ssp = sp[23]; unsigned int _sp = sp[24]; for (int r = 0; r < 16; r++) { printf("R%d: %x\n", r, sp[r]); } printf("icfg: %x \n", icfg); printf("psr: %x \n", psr); printf("rets: 0x%x \n", rets); printf("reti: 0x%x \n", reti); printf("usp : %x, ssp : %x sp: %x\r\n\r\n", usp, ssp, _sp); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "icfg: %x\r\n", icfg); len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "psr : %x\r\n", psr); len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "rets: 0x%x\r\n", rets); len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "reti: 0x%x\r\n", reti); len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "usp : %x, ssp : %x sp: %x\r\n", usp, ssp, _sp); #endif for (int i = 0; i < 32; i++) { if (q32DSP(cpu_id)->EMU_MSG & BIT(i)) { printf("%s\r\n", emu_msg[31 - i]); if (i == 3) { if (os_current_task_rom()) { printf("current_task : %s\r\n", os_current_task_rom()); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "%s\r\ncurrent_task : %s\r\n", emu_msg[31 - i], os_current_task_rom()); #endif } printf("usp limit %x %x\r\n", q32DSP(cpu_id)->EMU_USP_L, q32DSP(cpu_id)->EMU_USP_H); printf("ssp limit %x %x\r\n", q32DSP(cpu_id)->EMU_SSP_L, q32DSP(cpu_id)->EMU_SSP_H); } } } if (os_current_task_rom()) { printf("current_task : %s\r\n", os_current_task_rom()); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "\r\ncurrent_task : %s\r\n", os_current_task_rom()); #endif } printf("\n %s AXI_WR_INV_ID : 0x%x, AXI_RD_INV_ID : 0x%x, PRP_WR_LIMIT_ID : 0x%x, PRP_MMU_ERR_RID : 0x%x, PRP_MMU_ERR_WID : 0x%x\n", corex2(0)->AXI_RD_INV_ID == 0X100 ? "CPU0" : "CPU1", corex2(0)->AXI_WR_INV_ID, corex2(0)->AXI_RD_INV_ID, corex2(0)->PRP_WR_LIMIT_ID, corex2(0)->PRP_MMU_ERR_RID, corex2(0)->PRP_MMU_ERR_WID); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "%s AXI_WR_INV_ID : 0x%x, AXI_RD_INV_ID : 0x%x, PRP_WR_LIMIT_ID : 0x%x, PRP_MMU_ERR_RID : 0x%x, PRP_MMU_ERR_WID : 0x%x\r\n", corex2(0)->AXI_RD_INV_ID == 0X100 ? "CPU0" : "CPU1", corex2(0)->AXI_WR_INV_ID, corex2(0)->AXI_RD_INV_ID, corex2(0)->PRP_WR_LIMIT_ID, corex2(0)->PRP_MMU_ERR_RID, corex2(0)->PRP_MMU_ERR_WID); #endif int i = 0; int j = 0; int num = 0; for (i = 0; i < 32; i++) { if (BIT(i) & corex2(0)->DBG_MSG) { j = 0; if (i == 2) { printf("PRP_MMU_ERR_WID %x %x\n", corex2(0)->PRP_MMU_ERR_WID, corex2(0)->PRP_WR_LIMIT_ERR_NUM); num = corex2(0)->PRP_WR_LIMIT_ERR_NUM; while (!(num & BIT(j)) && ++j < 8); printf("\nWR_LIMITH : 0x%x, WR_LIMITL : 0x%x\n", ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "PRP_MMU_ERR_WID %x %x\r\nWR_LIMITH : 0x%x, WR_LIMITL : 0x%x\r\n", corex2(0)->PRP_MMU_ERR_WID, corex2(0)->PRP_WR_LIMIT_ERR_NUM, ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); #endif } else if (i == 11) { num = corex2(0)->C1_WR_LIMIT_ERR_NUM; while (!(num & BIT(j)) && ++j < 8); printf("\nWR_LIMITH : 0x%x, WR_LIMITL : 0x%x\n", ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "WR_LIMITH : 0x%x, WR_LIMITL : 0x%x\r\n", ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); #endif } else if (i == 13) { num = corex2(0)->C0_WR_LIMIT_ERR_NUM; while (!(num & BIT(j)) && ++j < 8); printf("\nWR_LIMITH : 0x%x, WR_LIMITL : 0x%x\n", ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "WR_LIMITH : 0x%x, WR_LIMITL : 0x%x\r\n", ((volatile u32 *)(&corex2(0)->WR_LIMIT0_H))[j], ((volatile u32 *)(&corex2(0)->WR_LIMIT0_L))[j]); #endif } else if (i == 10) { printf("\nPC_LIMIT0_H : 0x%x, PC_LIMIT0_L : 0x%x\n", corex2(0)->PC_LIMIT0_H, corex2(0)->PC_LIMIT0_L); printf("\nPC_LIMIT1_H : 0x%x, PC_LIMIT1_L : 0x%x\n", corex2(0)->PC_LIMIT1_H, corex2(0)->PC_LIMIT1_L); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "PC_LIMIT0_H : 0x%x, PC_LIMIT0_L : 0x%x\r\nPC_LIMIT1_H : 0x%x, PC_LIMIT1_L : 0x%x\r\n", corex2(0)->PC_LIMIT0_H, corex2(0)->PC_LIMIT0_L, corex2(0)->PC_LIMIT1_H, corex2(0)->PC_LIMIT1_L); #endif } else if (i == 12) { printf("\nPC_LIMIT0_H : 0x%x, PC_LIMIT0_L : 0x%x\n", corex2(0)->PC_LIMIT0_H, corex2(0)->PC_LIMIT0_L); printf("\nPC_LIMIT1_H : 0x%x, PC_LIMIT1_L : 0x%x\n", corex2(0)->PC_LIMIT1_H, corex2(0)->PC_LIMIT1_L); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "PC_LIMIT0_H : 0x%x, PC_LIMIT0_L : 0x%x\r\nPC_LIMIT1_H : 0x%x, PC_LIMIT1_L : 0x%x\r\n", corex2(0)->PC_LIMIT0_H, corex2(0)->PC_LIMIT0_L, corex2(0)->PC_LIMIT1_H, corex2(0)->PC_LIMIT1_L); #endif } else if (i == 14) { printf("JL_SDR->DBG_INFO : 0x%x ,err in JL_SDR->DBG_ADR = 0x%x, JL_SDR->DBG_START : 0x%x JL_SDR->DBG_END : 0x%x\n", JL_SDR->DBG_INFO, JL_SDR->DBG_ADR, JL_SDR->DBG_START, JL_SDR->DBG_END); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "JL_SDR->DBG_INFO : 0x%x ,err in JL_SDR->DBG_ADR = 0x%x, JL_SDR->DBG_START : 0x%x JL_SDR->DBG_END : 0x%x\r\n", JL_SDR->DBG_INFO, JL_SDR->DBG_ADR, JL_SDR->DBG_START, JL_SDR->DBG_END); #endif } else if (i == 15) { printf("\nAXI_RAM_LIMIT0_H : 0x%x, AXI_RAM_LIMIT0_L : 0x%x\n", JL_DBG->LIMIT_H, JL_DBG->LIMIT_L); printf("\nJL_DBG->WR_ALLOW_ID0 : 0x%x, JL_DBG->WR_ALLOW_ID1 : 0x%x, JL_DBG->WR_LIMIT_ID : 0x%x\n", JL_DBG->WR_ALLOW_ID0, JL_DBG->WR_ALLOW_ID1, JL_DBG->WR_LIMIT_ID); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "AXI_RAM_LIMIT0_H : 0x%x, AXI_RAM_LIMIT0_L : 0x%x\r\nJL_DBG->WR_ALLOW_ID0 : 0x%x, JL_DBG->WR_ALLOW_ID1 : 0x%x, JL_DBG->WR_LIMIT_ID : 0x%x\r\n", JL_DBG->LIMIT_H, JL_DBG->LIMIT_L, JL_DBG->WR_ALLOW_ID0, JL_DBG->WR_ALLOW_ID1, JL_DBG->WR_LIMIT_ID); #endif } printf("exception reason : %s \n", debug_msg[i]); #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH len += snprintf(exception_log_buf + len, sizeof(exception_log_buf) - len, "exception reason : %s \n", debug_msg[i]); #endif } } #ifdef CONFIG_EXCEPTION_AUTO_FIX_ENABLE write_exception_fix_to_flash(); #endif #ifdef CONFIG_SAVE_EXCEPTION_LOG_IN_FLASH printf("exception log buf len : %d\n", len); write_exception_log_to_flash(exception_log_buf, len + 1); #endif printf("system_reset...\r\n\r\n\r\n"); log_flush(); //只能在异常中断里调用 __wdt_clear(); #ifdef SDTAP_DEBUG sdtap_init(2);//防止IO被占据,重新初始化SDTAP while (1); #endif #ifndef CONFIG_FPGA_ENABLE __cpu_reset(); while (1); #endif } ___interrupt static void osa_irq_handler(void) { JL_OSA->CON |= BIT(6); puts("----------lsb clk lost-----------\n"); } static void debug_enter_critical(void) { if (corex2(0)->DBG_WR_EN & BIT(0)) { return; } corex2(0)->DBG_WR_EN = 0xe7;//set debug reg write enable } static void debug_exit_critical(void) { if (corex2(0)->DBG_WR_EN & BIT(0)) { corex2(0)->DBG_WR_EN = 0xe7;//set debug reg write disable } } static inline int get_debug_index(void) { for (u8 i = 0; i < 8 ; i++) { if (!(debug_index & BIT(i))) { return i; } } return -1; } static void pc0_rang_limit(void *low_addr, void *high_addr) { printf("pc0 :%x---%x\n", (u32)low_addr, (u32)high_addr); corex2(0)->DBG_MSG_CLR = 0xffffffff; corex2(0)->PC_LIMIT0_H = (u32)high_addr; corex2(0)->PC_LIMIT0_L = (u32)low_addr; } static void pc1_rang_limit(void *low_addr, void *high_addr) { printf("pc1 :%x---%x\n", (u32)low_addr, (u32)high_addr); corex2(0)->DBG_MSG_CLR = 0xffffffff; corex2(0)->PC_LIMIT1_H = (u32)high_addr; corex2(0)->PC_LIMIT1_L = (u32)low_addr; } void pc_rang_limit(void *low_addr0, void *high_addr0, void *low_addr1, void *high_addr1) { debug_enter_critical(); if (low_addr0 && high_addr0) { pc0_rang_limit(low_addr0, high_addr0); } if (low_addr1 && high_addr1) { pc1_rang_limit(low_addr1, high_addr1); } debug_exit_critical(); } #define wr_limit_h ((volatile u32 *)&corex2(0)->WR_LIMIT0_H) #define wr_limit_l ((volatile u32 *)&corex2(0)->WR_LIMIT0_L) #define wr_allow_num ((volatile u32 *)&corex2(0)->WR_ALLOW_ID0) int dev_write_range_limit(int limit_index, void *low_addr, void *high_addr, u32 is_allow_write_out, int dev_id) { if (limit_index == -1) { limit_index = get_debug_index(); } /* else if (debug_index & BIT(limit_index)) { return debug_index; } */ if (limit_index == -1) { return -1; } debug_enter_critical(); debug_index |= BIT(limit_index); #if 1 printf("dev %x write %s low_addr:%x--high_addr:%x\n", dev_id, is_allow_write_out ? ("allow") : ("limit"), (u32)low_addr, (u32)high_addr); #endif corex2(0)->DBG_MSG_CLR = 0xffffffff; wr_limit_h[limit_index] = (u32)high_addr; wr_limit_l[limit_index] = (u32)low_addr; if (dev_id != -1) { corex2(0)->PRP_WR_ALLOW_EN |= BIT(limit_index); wr_allow_num[limit_index] = dev_id; } if (!is_allow_write_out) { corex2(0)->PRP_OUTLIM_ERR_EN |= BIT(limit_index); } corex2(0)->PRP_WR_LIMIT_EN |= BIT(limit_index); debug_exit_critical(); #if 1 printf("WR_LIM%dL:%x--WR_LIM%dH:%x--corex2(0)->DBG_CON:%x--PRP_WR_LIMIT_EN:0x%x\n", limit_index, wr_limit_l[limit_index], limit_index, wr_limit_h[limit_index], corex2(0)->DBG_CON, corex2(0)->PRP_WR_LIMIT_EN); #endif return 0; } void all_dev_range_limit(void *addr, int size)//所有外设写进异常(地址:sram+经过cach的sdram) { int limit_index = 0; debug_enter_critical(); corex2(0)->PRP_WR_LIMIT_EN &= ~BIT(limit_index); corex2(0)->DBG_MSG_CLR = 0xffffffff; debug_index |= BIT(limit_index); corex2(0)->WR_LIMIT0_L = (u32)((u32)addr); corex2(0)->WR_LIMIT0_H = (u32)((u32)addr + size); corex2(0)->WR_ALLOW_ID0 = 0; corex2(0)->PRP_WR_LIMIT_EN = BIT(limit_index); debug_exit_critical(); } void all_dev_range_unlimit(void *addr) { debug_enter_critical(); corex2(0)->DBG_MSG_CLR = 0xffffffff; corex2(0)->WR_LIMIT0_L = 0; corex2(0)->WR_LIMIT0_H = 0; corex2(0)->WR_ALLOW_ID0 = 0; corex2(0)->PRP_WR_LIMIT_EN = 0; debug_exit_critical(); } int cpu_write_range_limit(void *low_addr, u32 win_size) { void *high_addr = low_addr + win_size - 1; int i = get_debug_index(); if (i == -1) { return -1; } debug_enter_critical(); debug_index |= BIT(i); corex2(0)->DBG_MSG_CLR = 0xffffffff; wr_limit_h[i] = (u32)high_addr; wr_limit_l[i] = (u32)low_addr; corex2(0)->C0_WR_LIMIT_EN |= BIT(i); corex2(0)->C1_WR_LIMIT_EN |= BIT(i); debug_exit_critical(); return 0; } void cpu_write_range_unlimit(void *low_addr) { int i; debug_enter_critical(); corex2(0)->DBG_MSG_CLR = 0xffffffff; for (i = 0; i < 8; i++) { if (wr_limit_l[i] == (u32)low_addr) { wr_limit_h[i] = 0; wr_limit_l[i] = 0; debug_index &= ~BIT(i); corex2(0)->C0_WR_LIMIT_EN &= ~BIT(i); corex2(0)->C1_WR_LIMIT_EN &= ~BIT(i); } } debug_exit_critical(); } //使用前一定要先完全flush int sdr_read_write_range_limit(u32 low_addr, u32 high_addr, int id0, int id1, u8 rd0_permit, u8 wr0_permit, u8 rd1_permit, u8 wr1_permit, u8 wr0_over_area_permit, u8 wr1_over_area_permit) { if (id0 == -1 && id1 == -1) { return -1; } JL_SDR->DBG_INFO = 0; JL_SDR->DBG_INFO |= BIT(13); if (id0 != -1) { JL_SDR->DBG_INFO |= ((id0 >> 6) & 0xf); JL_SDR->DBG_INFO &= ~BIT(4); JL_SDR->DBG_INFO &= ~BIT(5); JL_SDR->DBG_INFO &= ~BIT(14); if (rd0_permit) { JL_SDR->DBG_INFO |= BIT(5); } if (wr0_permit) { JL_SDR->DBG_INFO |= BIT(4); } if (wr0_over_area_permit) { JL_SDR->DBG_INFO |= BIT(14); } } if (id1 != -1) { JL_SDR->DBG_INFO |= ((id1 >> 6) & 0xf) << 6; JL_SDR->DBG_INFO &= ~BIT(10); JL_SDR->DBG_INFO &= ~BIT(11); JL_SDR->DBG_INFO &= ~BIT(15); if (rd1_permit) { JL_SDR->DBG_INFO |= BIT(11); } if (wr1_permit) { JL_SDR->DBG_INFO |= BIT(10); } if (wr1_over_area_permit) { JL_SDR->DBG_INFO |= BIT(15); } } JL_SDR->DBG_START = low_addr; JL_SDR->DBG_END = high_addr; JL_SDR->DBG_INFO |= BIT(12); /* matrt id ISC0:0 ISC1:1 LSB:2 JPG:3 CPI0:4 CPU1:5 CACH:6 DMA_COPY:7 EMI:8 IMD:9 */ return 0; } int sdr_read_write_range_unlimit(void) { JL_SDR->DBG_INFO &= ~BIT(12); __asm_csync(); return 0; } int axi_ram_write_range_limit(u32 low_addr, u32 high_addr, u32 is_allow_write_out, int id0, int id1) { #if 0 printf("axi_ram id0 %x id1 %x write_out %s low_addr:%x--high_addr:%x\n", id0, id1, is_allow_write_out ? ("allow") : ("limit"), low_addr, high_addr); #endif if (low_addr < 0x1bfe000 || low_addr >= 0x1c00000) { return -1; } if (high_addr < 0x1bfe000 || high_addr >= 0x1c00000 || high_addr < low_addr) { return -1; } JL_DBG->LIMIT_H = high_addr; JL_DBG->LIMIT_L = low_addr; if (id0 == -1 && id1 == -1) { JL_DBG->CON &= ~BIT(1); } else { if (id0 != -1) { JL_DBG->WR_ALLOW_ID0 = id0; JL_DBG->CON |= BIT(1); } if (id1 != -1) { JL_DBG->WR_ALLOW_ID1 = id1; JL_DBG->CON |= BIT(1); } if (!is_allow_write_out) { JL_DBG->CON |= BIT(2); } } JL_DBG->CON |= (BIT(6) | BIT(3) | BIT(0)); #if 0 printf("WR_LIML:0x%x--WR_LIMH:0x%x-- JL_DBG->CON:0x%x \n", JL_DBG->LIMIT_L, JL_DBG->LIMIT_H, JL_DBG->CON); #endif return 0; } void debug_clear(void) { debug_enter_critical(); JL_SDR->DBG_INFO = 0; JL_DBG->CON = 0; corex2(0)->DBG_CON = 0; corex2(0)->DBG_EN = 0; corex2(0)->C0_WR_LIMIT_EN = 0; corex2(0)->C1_WR_LIMIT_EN = 0; corex2(0)->PRP_WR_LIMIT_EN = 0; corex2(0)->PRP_WR_ALLOW_EN = 0; corex2(0)->PRP_OUTLIM_ERR_EN = 0; corex2(0)->DBG_MSG_CLR = 0xffffffff; q32DSP(0)->EMU_MSG = -1; q32DSP(1)->EMU_MSG = -1; debug_index = 0; debug_exit_critical(); } __attribute__((noinline)) void sp_ovf_unen(void) { q32DSP(OS_CPU_ID)->EMU_CON &= ~ BIT(3); } __attribute__((noinline)) void sp_ovf_en(void) { #ifndef SDTAP_DEBUG q32DSP(OS_CPU_ID)->EMU_CON |= BIT(3); //如果用户使用setjmp longjmp, 或者使用sdtap gdb调试 务必要删掉这句话 #endif } void debug_msg_clear(void) { debug_enter_critical(); JL_DBG->CON |= BIT(6); JL_SDR->DBG_INFO |= BIT(11); corex2(0)->DBG_CON |= (BIT(17) | BIT(18)); corex2(0)->DBG_MSG_CLR = 0xffffffff; debug_exit_critical(); } extern u32 cpu0_sstack_begin[]; extern u32 cpu0_sstack_end[]; extern u32 cpu1_sstack_begin[]; extern u32 cpu1_sstack_end[]; void debug_init(void) { u32 cpu_id = current_cpu_id(); #if EXPCPTION_IN_SRAM request_irq(IRQ_EXCEPTION_IDX, 7, exception_analyze_sram, 0xff); #else request_irq(IRQ_EXCEPTION_IDX, 7, exception_irq_handler, 0xff); #endif JL_OSA->CON = 0x6D; //监控lsb_clk request_irq(IRQ_OSA_IDX, 7, osa_irq_handler, 0); #ifdef SDTAP_DEBUG sdtap_init(2); #endif q32DSP(cpu_id)->EMU_CON = 0; if (cpu_id == 0) { debug_clear(); debug_enter_critical(); corex2(0)->DBG_EN |= (0x3f << 16); corex2(0)->DBG_EN |= (0x3 << 4); debug_exit_critical(); q32DSP(0)->EMU_CON &= ~ BIT(3); q32DSP(0)->EMU_SSP_L = (int)cpu0_sstack_begin; q32DSP(0)->EMU_SSP_H = (int)cpu0_sstack_end; q32DSP(0)->EMU_USP_L = 0; q32DSP(0)->EMU_USP_H = -1; q32DSP(0)->EMU_CON |= BIT(3); printf("cpu 0 usp limit %x %x\r\n", q32DSP(0)->EMU_USP_L, q32DSP(0)->EMU_USP_H); printf("cpu 0 ssp limit %x %x\r\n", q32DSP(0)->EMU_SSP_L, q32DSP(0)->EMU_SSP_H); } else { #if !defined CONFIG_VIDEO_ENABLE && !defined CONFIG_UI_ENABLE && !defined CONFIG_RTOS_AND_MM_LIB_CODE_SECTION_IN_SDRAM && !defined CONFIG_RF_TRIM_CODE_MOVABLE pc_rang_limit(&text_rodata_begin, &text_rodata_end, &ram_text_rodata_begin, &ram_text_rodata_end); #endif q32DSP(1)->EMU_CON &= ~BIT(3); q32DSP(1)->EMU_SSP_L = (int)cpu1_sstack_begin; q32DSP(1)->EMU_SSP_H = (int)cpu1_sstack_end; q32DSP(1)->EMU_USP_L = 0; q32DSP(1)->EMU_USP_H = -1; q32DSP(1)->EMU_CON |= BIT(3); printf("cpu 1 usp limit %x %x\r\n", q32DSP(1)->EMU_USP_L, q32DSP(1)->EMU_USP_H); printf("cpu 1 ssp limit %x %x\r\n", q32DSP(1)->EMU_SSP_L, q32DSP(1)->EMU_SSP_H); } /* q32DSP(cpu_id)->EMU_CON |= (0xf << 0) | (0x1 << 8) | (0x1f << 16); */ /* q32DSP(cpu_id)->EMU_CON |= (0xf << 0) | (0x1 << 8) | (0x06 << 16); */ q32DSP(cpu_id)->EMU_CON |= (BIT(2) | BIT(8)); q32DSP(cpu_id)->ETM_CON |= BIT(0); } #if 0 static u64 cpu_cnt[CPU_CORE_NUM][4] ; void cpu_effic_init(void) { debug_enter_critical(); for (u8 j = 0 ; j < CPU_CORE_NUM ; ++j) { if (j == 0) { corex2(0)->DBG_CON |= (0x7); ///< enable if_inv_en of_inv_en ex_inv_en ((u32 *)(&cpu_cnt[0][0]))[0] = corex2(0)->C0_IF_UACNTL ; ((u32 *)(&cpu_cnt[0][0]))[1] = corex2(0)->C0_IF_UACNTH ; ((u32 *)(&cpu_cnt[0][1]))[0] = corex2(0)->C0_RD_UACNTL ; ((u32 *)(&cpu_cnt[0][1]))[1] = corex2(0)->C0_RD_UACNTH ; ((u32 *)(&cpu_cnt[0][2]))[0] = corex2(0)->C0_WR_UACNTL ; ((u32 *)(&cpu_cnt[0][2]))[1] = corex2(0)->C0_WR_UACNTH ; ((u32 *)(&cpu_cnt[0][3]))[0] = corex2(0)->C0_TL_CKCNTL ; ((u32 *)(&cpu_cnt[0][3]))[1] = corex2(0)->C0_TL_CKCNTH ; } else { corex2(0)->DBG_CON |= (0x7 << 8); ///< enable if_inv_en of_inv_en ex_inv_en ((u32 *)(&cpu_cnt[1][0]))[0] = corex2(0)->C1_IF_UACNTL ; ((u32 *)(&cpu_cnt[1][0]))[1] = corex2(0)->C1_IF_UACNTH ; ((u32 *)(&cpu_cnt[1][1]))[0] = corex2(0)->C1_RD_UACNTL ; ((u32 *)(&cpu_cnt[1][1]))[1] = corex2(0)->C1_RD_UACNTH ; ((u32 *)(&cpu_cnt[1][2]))[0] = corex2(0)->C1_WR_UACNTL ; ((u32 *)(&cpu_cnt[1][2]))[1] = corex2(0)->C1_WR_UACNTH ; ((u32 *)(&cpu_cnt[1][3]))[0] = corex2(0)->C1_TL_CKCNTL ; ((u32 *)(&cpu_cnt[1][3]))[1] = corex2(0)->C1_TL_CKCNTH ; } } debug_exit_critical(); } void cpu_effic_calc(void) { u64 cpu_cnt_tmp[CPU_CORE_NUM][4] ; u64 all_cnt ; u64 effic ; int i = 0 ; int j ; static u8 init_flag = 0; if (!init_flag) { cpu_effic_init(); init_flag = 1; return; //初始化后需要隔一段时间 } for (j = 0 ; j < CPU_CORE_NUM ; j++) { if (j == 0) { ((u32 *)(&cpu_cnt_tmp[0][0]))[0] = corex2(0)->C0_IF_UACNTL ; ((u32 *)(&cpu_cnt_tmp[0][0]))[1] = corex2(0)->C0_IF_UACNTH ; ((u32 *)(&cpu_cnt_tmp[0][1]))[0] = corex2(0)->C0_RD_UACNTL ; ((u32 *)(&cpu_cnt_tmp[0][1]))[1] = corex2(0)->C0_RD_UACNTH ; ((u32 *)(&cpu_cnt_tmp[0][2]))[0] = corex2(0)->C0_WR_UACNTL ; ((u32 *)(&cpu_cnt_tmp[0][2]))[1] = corex2(0)->C0_WR_UACNTH ; ((u32 *)(&cpu_cnt_tmp[0][3]))[0] = corex2(0)->C0_TL_CKCNTL ; ((u32 *)(&cpu_cnt_tmp[0][3]))[1] = corex2(0)->C0_TL_CKCNTH ; } else if (j == 1) { ((u32 *)(&cpu_cnt_tmp[1][0]))[0] = corex2(0)->C1_IF_UACNTL ; ((u32 *)(&cpu_cnt_tmp[1][0]))[1] = corex2(0)->C1_IF_UACNTH ; ((u32 *)(&cpu_cnt_tmp[1][1]))[0] = corex2(0)->C1_RD_UACNTL ; ((u32 *)(&cpu_cnt_tmp[1][1]))[1] = corex2(0)->C1_RD_UACNTH ; ((u32 *)(&cpu_cnt_tmp[1][2]))[0] = corex2(0)->C1_WR_UACNTL ; ((u32 *)(&cpu_cnt_tmp[1][2]))[1] = corex2(0)->C1_WR_UACNTH ; ((u32 *)(&cpu_cnt_tmp[1][3]))[0] = corex2(0)->C1_TL_CKCNTL ; ((u32 *)(&cpu_cnt_tmp[1][3]))[1] = corex2(0)->C1_TL_CKCNTH ; } } const char *CNTLX[] = {"IF_UACNT", "RD_UACNT", "WR_UACNT", "TL_CKCNT"}; for (j = 0 ; j < CPU_CORE_NUM ; j++) { all_cnt = 0 ; u64 ddd = cpu_cnt_tmp[j][3] - cpu_cnt[j][3] ; /*printf("cpu[%d] TL_CKCNT = %d \r\n", j, ddd);*/ for (i = 0 ; i < 3 ; i++) { /*printf("0x%08x%08x , 0x%08x%08x \r\n" ,((u32*) &cpu_cnt[j][i])[1],((u32*) &cpu_cnt[j][i])[0] ,((u32*)&cpu_cnt_tmp[j][i])[1], ((u32*)&cpu_cnt_tmp[j][i])[0]);*/ effic = cpu_cnt_tmp[j][i] - cpu_cnt[j][i] ; /*printf("sub = %08x%08x \r\n" ,((u32*)&effic)[1] ,((u32*)&effic)[0] );*/ all_cnt += effic ; /*printf("cpu[%d] %s = %d \r\n", j, CNTLX[i], effic);*/ printf("cpu[%d] %s effic = %llu%% \r\n", j, CNTLX[i], effic * 100 / ddd) ; } /*printf("0x%08x%08x , 0x%08x%08x \r\n" ,((u32*) &cpu_cnt[j][i])[1],((u32*) &cpu_cnt[j][i])[0] ,((u32*)&cpu_cnt_tmp[j][i])[1], ((u32*)&cpu_cnt_tmp[j][i])[0]);*/ effic = cpu_cnt_tmp[j][3] - cpu_cnt[j][3] ; /*printf("all cnt = %08x%08x \r\n" ,((u32*)&effic)[1] ,((u32*)&effic)[0]);*/ effic = (all_cnt * 100) / effic ; printf("cpu %d TL_CKCNT effic %d%% \r\n", j, (u32)effic) ; memcpy((void *)&cpu_cnt[j], (void *)&cpu_cnt_tmp[j], sizeof(u64) * 4) ; } } #endif