?? tb.c
字號:
//set ret if (addr == tb_begin_addr) { ret = tbt->tbp_now; } //set insn_addr tbt->insn_addr[(tbt->tran_addr - tbt->addr) / sizeof(uint8_t *)] = tbt->tbp_now; //translate len = translate_word(state, *tb_begin_addr, tbt->tbp_now); tbt->tbp_now += len;//teawater change for if trap translate stop 2005.07.23------------------------- //*tran_addr += 4; tbt->tran_addr += 4; if (state->trap && ret && (tbt->tran_addr > tbt->ret_addr)) { break; }//AJ2D-------------------------------------------------------------------------- }//teawater change for if trap translate stop 2005.07.23------------------------- //*tbp_now = tbp; if (!state->trap) { GEN_OP(tbt->tbp_now, len, op_return); }//AJ2D--------------------------------------------------------------------------//teawater change for local tb branch directly jump 2005.10.10------------------ list_for_each_safe(list, n, &tb_branch_save_list) { e = list_entry(list, tb_branch_save_t, list); //memcpy((e->tbp - sizeof(ARMword)), &((uint32_t)tbt->insn_addr[(e->dst_addr - tbt->addr) / sizeof(uint8_t *)] - (uint32_t)e->tbp), sizeof(ARMword)); *((uint32_t *)(e->tbp - sizeof(ARMword))) = (uint32_t)tbt->insn_addr[(e->dst_addr - tbt->addr) / sizeof(uint8_t *)] - (uint32_t)e->tbp; }//AJ2D-------------------------------------------------------------------------- return(ret);}//AJ2D--------------------------------------------------------------------------//teawater remove tb_translate_find 2005.10.21----------------------------------/*static uint8_t *tb_translate_find (ARMul_State * state, ARMword * addr, ARMword * tb_begin_addr, uint8_t * tbp){ int len; uint8_t *ret = NULL; ARMword *tb_end_addr = tb_begin_addr + TB_LEN / sizeof (ARMword); for (; tb_begin_addr < tb_end_addr; tb_begin_addr++) { if (addr == tb_begin_addr) { ret = tbp; break; } len = translate_word (state, *tb_begin_addr, NULL); tbp += len; } return (ret);}*///AJ2D--------------------------------------------------------------------------//teawater add tb_insn_addr 2005.10.06------------------------------------------/*static inline voidtb_insert_cache (tb_t * tbt, ARMword addr, uint8_t * ret){ tb_cache_t *e = malloc (sizeof (tb_cache_t)); if (e) { uint32_t cache_num = addr & (TB_TBT_CACHE_MAX - 1); if (!tbt->cache[cache_num].next) INIT_LIST_HEAD (&tbt->cache[cache_num]); e->addr = addr; e->tp = ret; list_add_tail (&e->list, &tbt->cache[cache_num]); } else { TEA_OUT (fprintf (stderr, "SKYEYE: tb_find: Error allocating mem for cache.\n")); }}static inline uint8_t *tb_find_cache (tb_t * tbt, ARMword addr){ tb_cache_t *e; struct list_head *list, *n; uint32_t cache_num = addr & (TB_TBT_CACHE_MAX - 1); if (tbt->cache[cache_num].next) { list_for_each_safe (list, n, &tbt->cache[cache_num]) { e = list_entry (list, tb_cache_t, list); if (e->addr == addr) { return (e->tp); } } } return (NULL);}static inline voidtb_clear_cache (tb_t * tbt){ tb_cache_t *e; struct list_head *list, *n; uint32_t cache_num; for (cache_num = 0; cache_num < TB_TBT_CACHE_MAX; cache_num++) { if (tbt->cache[cache_num].next) { list_for_each_safe (list, n, &tbt->cache[cache_num]) { e = list_entry (list, tb_cache_t, list); list_del_init (&e->list); free (e); } } }}*///AJ2D--------------------------------------------------------------------------static inline voidtb_get_tbp (tb_t * tbt){ tb_t *e; struct list_head *list; if (tbp_now_size) { tbt->tbp = tbp_now; tbp_now += TB_TBP_MAX; tbp_now_size -= TB_TBP_MAX; } else { //get the oldest tbt from tbp_dynamic_list's head if (list_empty (&tbp_dynamic_list)) { fprintf (stderr, "SKYEYE: mem_reset: some bug.\n"); skyeye_exit (-1); } e = list_entry (tbp_dynamic_list.next, tb_t, list); tbt->tbp = e->tbp; e->tbp = NULL;//teawater add tb_insn_addr 2005.10.06------------------------------------------ /*if (e->ted) { tb_clear_cache(e); e->ted = 0; }*/ e->ted = 0;//AJ2D-------------------------------------------------------------------------- list_del_init (&e->list); }}static inline mem_bank_t *tb_get_mbp (ARMword addr, int *bank_num){ mem_bank_t *ret; ret = insn_bank_ptr (addr); if (ret) { *bank_num = ret - state->mem_bank->mem_banks; } return (ret);}uint8_t *tb_find (ARMul_State * state, ARMword ADDR){ uint8_t *ret = NULL; ARMword addr, align_addr; ARMword *real_begin_addr, *real_addr; static ARMword save_align_addr = 0x1; static tb_t *tbt; static uint8_t *tbp; static mem_bank_t *mbp; static int bank_num = -1; //get addr & align_addr if (mmu_v2p_dbct (state, ADDR, &addr)) { goto out; } align_addr = TB_ALIGN (addr); if (align_addr == save_align_addr) { goto get_ret; } //init bank_num = -1; save_align_addr = 0x1; //get tbt if (tbt_table_size) { //dynamic tbt tbt = &(tbt_table [align_addr & (uint32_t) (tbt_table_size - 1)]); if (tbt->addr != align_addr) { if (tbt->ted) {//teawater add tb_insn_addr 2005.10.06------------------------------------------ //tb_clear_cache(tbt);//AJ2D-------------------------------------------------------------------------- tbt->ted = 0; } tbt->addr = align_addr; } //get tbt->tbp if (!tbt->tbp) { tb_get_tbp (tbt); } else { if (tbp_dynamic) { list_del_init (&tbt->list); } } } else { //static tbt mbp = tb_get_mbp (align_addr, &bank_num); if (!mbp) { goto out; } if (!state->mem.tbt[bank_num]) { if (!tbp_dynamic) { state->mem.tbp[bank_num] = mmap (NULL, state->mem.rom_size[bank_num] / sizeof (ARMword) * TB_INSN_LEN_MAX + state->mem.rom_size[bank_num] / TB_LEN * op_return.len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (state->mem.tbp[bank_num] == MAP_FAILED) { fprintf (stderr, "SKYEYE: mem_reset: Error allocating mem for bank number %d.\n", bank_num); skyeye_exit (-1); } } state->mem.tbt[bank_num] = malloc (state->mem.rom_size[bank_num] / TB_LEN * sizeof (tb_t)); if (!state->mem.tbt[bank_num]) { fprintf (stderr, "SKYEYE: mem_reset: Error allocating mem for bank number %d.\n", bank_num); skyeye_exit (-1); } memset (state->mem.tbt[bank_num], 0, state->mem.rom_size[bank_num] / TB_LEN * sizeof (tb_t)); } tbt = &(state->mem. tbt[bank_num][(align_addr - mbp->addr) / TB_LEN]);//teawater add tb_insn_addr 2005.10.08------------------------------------------ tbt->addr = align_addr;//AJ2D-------------------------------------------------------------------------- //get tbt->tbp if (!tbt->tbp) { if (tbp_dynamic) { //dynamic tbp tb_get_tbp (tbt); } else { tbt->tbp = &(state->mem. tbp[bank_num][(align_addr - mbp->addr) / sizeof (ARMword) * TB_INSN_LEN_MAX + (align_addr - mbp->addr) / TB_LEN * op_return.len]); } } else { if (tbp_dynamic) { list_del_init (&tbt->list); } } } //get tbp tbp = tbt->tbp; //set tb_now to check the current running block is written. state->tb_now = (void *) tbt; //set save_align_addr save_align_addr = align_addr; //add tbt to tbp_dynamic_list's tail to be the newest one if (tbp_dynamic) { list_add_tail (&tbt->list, &tbp_dynamic_list); } //find ret from tb get_ret: if (tbt->ted) { //tbt has been translated//teawater add last use addr 2005.10.10----------------------------------------- if (tbt->last_addr == addr) { return(tbt->last_tbp); } //addr is align /*if (addr == align_addr) { ret = tbp; goto out; }*///AJ2D-------------------------------------------------------------------------- if (addr >= tbt->tran_addr) { //block need continue translate if (bank_num == -1) { mbp = tb_get_mbp (align_addr, &bank_num); if (!mbp) { goto out; } } real_begin_addr = &(state->mem. rom[bank_num][(align_addr - mbp->addr) / sizeof (ARMword)]) + (tbt->tran_addr - align_addr) / sizeof (ARMword); real_addr = real_begin_addr + (addr - tbt->tran_addr) / sizeof (ARMword);//teawater add tb_insn_addr 2005.10.08------------------------------------------ //ret = tb_translate(state, real_addr, real_begin_addr, tbt->tbp_now, &tbt->tran_addr, &tbt->tbp_now); ret = tb_translate(state, real_addr, real_begin_addr, tbt);//AJ2D-------------------------------------------------------------------------- } else {//teawater add tb_insn_addr 2005.10.08------------------------------------------ /*//find in cache ret = tb_find_cache(tbt, addr); if (ret) { goto out; } if (bank_num == -1) { mbp = tb_get_mbp(align_addr, &bank_num); if(!mbp) { goto out; } } real_begin_addr = &(state->mem.rom[bank_num][(align_addr - mbp->addr) / sizeof(ARMword)]); real_addr = real_begin_addr + (addr - align_addr) / sizeof(ARMword); ret = tb_translate_find(state, real_addr, real_begin_addr, tbp);*/ //find in insn_addr ret = tbt->insn_addr[(addr - align_addr) / sizeof(uint8_t *)];//AJ2D-------------------------------------------------------------------------- } } else { //tbt has not been translated if (bank_num == -1) { mbp = tb_get_mbp (align_addr, &bank_num); if (!mbp) { goto out; } } real_begin_addr = &(state->mem. rom[bank_num][(align_addr - mbp->addr) / sizeof (ARMword)]); real_addr = real_begin_addr + (addr - align_addr) / sizeof (ARMword); tbt->tran_addr = align_addr;//teawater add tb_insn_addr 2005.10.08------------------------------------------ //ret = tb_translate(state, real_addr, real_begin_addr, tbp, &tbt->tran_addr, &tbt->tbp_now); tbt->tbp_now = tbp; ret = tb_translate(state, real_addr, real_begin_addr, tbt); /*if (ret) { tbt->ted = 1; }*/ tbt->ted = 1;//AJ2D-------------------------------------------------------------------------- }//teawater add tb_insn_addr 2005.10.08------------------------------------------ /*if (ret) { tb_insert_cache(tbt, addr, ret); }*///AJ2D-------------------------------------------------------------------------- out://teawater add last use addr 2005.10.10----------------------------------------- if (ret) { tbt->last_addr = addr; tbt->last_tbp = ret; }//AJ2D-------------------------------------------------------------------------- return (ret);}inttb_setdirty (ARMul_State * state, ARMword addr, mem_bank_t * mbp){ ARMword align_addr = TB_ALIGN (addr); static ARMword save_align_addr = 0x1; static tb_t *tbt = NULL; if (save_align_addr == align_addr) { goto setdirty; } save_align_addr = 0x1; //get tbt if (tbt_table_size) { tbt = &(tbt_table [align_addr & (uint32_t) (tbt_table_size - 1)]); if (tbt->addr != align_addr) { return (0); } } else { int bank_num; if (!mbp) { mbp = tb_get_mbp (align_addr, &bank_num); if (!mbp) { return (0); } } else { bank_num = mbp - state->mem_bank->mem_banks; } if (!state->mem.tbt[bank_num]) { return (0); } tbt = &(state->mem. tbt[bank_num][(align_addr - mbp->addr) / TB_LEN]); } save_align_addr = align_addr; setdirty: if (tbt->ted) {//teawater add tb_insn_addr 2005.10.09------------------------------------------ //tb_clear_cache(tbt);//AJ2D-------------------------------------------------------------------------- tbt->ted = 0; switch (state->cpu->cpu_val & state->cpu->cpu_mask) { case SA1100: case SA1110: mmu_wb_drain_all (state, (&state->mmu.u.sa_mmu.wb_t)); break; case 0x41009200: mmu_wb_drain_all (state, (&state->mmu.u.arm920t_mmu.wb_t)); break; }; } return (0);}int tb_insn_len_max = 0;inttb_insn_len_max_init (ARMul_State * state){ int dp_len = 0, other_len = 0; //return if debug || irq || fiq || condition if (op_begin.len > op_movl_Tx_im[0].len + sizeof (ARMword) + op_begin_test_T0.len) { tb_insn_len_max += op_begin.len; } else { tb_insn_len_max += op_movl_Tx_im[0].len + sizeof (ARMword) + op_begin_test_T0.len; } //end tb_insn_len_max += op_return.len; tb_insn_len_max += op_addpc.len; //TEA_OUT(tb_insn_len_max += op_return.len); //dp_len { int dp_head_len = 0; int sm_head; int op_setcpsr_nzc_len = 0, op_setcpsr_nzc_setr15_len = 0, op_setcpsr_nzc_notsetr15_len = 0, op_setcpsr_nzc_setreg_len = 0; int op_setcpsr_nzcv_len = 0, op_setcpsr_nzcv_setr15_len = 0, op_setcpsr_nzcv_notsetr15_len = 0, op_setcpsr_nzcv_setreg_len = 0; int dp_tmp1; //dp_head_len { int dp_head_imm_len = 0, dp_head_reg_len = 0; //dp_head_imm_len dp_head_imm_len += op_movl_Tx_im[1].len; dp_head_imm_len += sizeof (ARMword); if (op_logic_1_sc.len > op_logic_0_sc.len) { dp_head_imm_len += op_logic_1_sc.len; } else { dp_head_imm_len += op_logic_0_sc.len; } //dp_head_reg_len { int dp_head_reg_imm_len = 0, dp_head_reg_reg_len = 0; dp_head_reg_len += op_movl_Tx_reg_array_maxlen[1]; //dp_head_reg_imm_len //shift != 0 dp_head_reg_imm_len += op_shift_T1_im_sc_maxlen; dp_head_reg_imm_len += op_set_cf.len; dp_head_reg_imm_len += op_shift_T1_im_maxlen; dp_head_reg_imm_len += sizeof (uint8_t); //shift == 0 dp_tmp1 = op_movl_T2_T1.len; dp_tmp1 += op_shift_T1_0_maxlen; dp_tmp1 += op_shift_T2_0_sc_maxlen; dp_tmp1 += op_set_cf.len; //compare if (dp_tmp1 > dp_head_reg_imm_len) dp_head_reg_imm_len = dp_tmp1; //dp_head_reg_reg_len if (op_shift_T1_T0_sc_maxlen + op_set_cf.len > op_shift_T1_T0_maxlen) { dp_head_reg_reg_len += op_shift_T1_T0_sc_maxlen + op_set_cf.len; } else { dp_head_reg_reg_len += op_shift_T1_T0_maxlen; } dp_head_reg_reg_len += op_movl_Tx_reg_array_maxlen[0]; if (dp_head_reg_imm_len > dp_head_reg_reg_len) { dp_head_reg_len += dp_head_reg_imm_len; } else { dp_head_reg_len += dp_head_reg_reg_len; } } if (dp_head_imm_len > dp_head_reg_len) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -