exec-all.h revision fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0af
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * internal execution defines for qemu 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2003 Fabrice Bellard 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is free software; you can redistribute it and/or 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modify it under the terms of the GNU Lesser General Public 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * License as published by the Free Software Foundation; either 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * version 2 of the License, or (at your option) any later version. 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is distributed in the hope that it will be useful, 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Lesser General Public License for more details. 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * You should have received a copy of the GNU Lesser General Public 172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * License along with this library; if not, see <http://www.gnu.org/licenses/>. 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _EXEC_ALL_H_ 215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define _EXEC_ALL_H_ 225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h" 240e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner#include "exec/cpu-common.h" 250e0515410009c5bdd4d2d77a4a9131081573f040David 'Digit' Turner#include "exec/cpu-all.h" 265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* allow to see translation results - the slowdown should be negligible, so we leave it */ 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DEBUG_DISAS 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 30280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner/* Page tracking code uses ram addresses in system mode, and virtual 31280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner addresses in userspace mode. Define tb_page_addr_t to be an appropriate 32280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner type. */ 33280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#if defined(CONFIG_USER_ONLY) 34280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnertypedef abi_ulong tb_page_addr_t; 35280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#else 36280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turnertypedef ram_addr_t tb_page_addr_t; 37280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner#endif 38280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* is_jmp field values */ 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_NEXT 0 /* next instruction can be analyzed */ 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_JUMP 1 /* only pc was modified dynamically */ 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_UPDATE 2 /* cpu state was modified dynamically */ 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DISAS_TB_JUMP 3 /* only pc was modified statically */ 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 454d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnerstruct TranslationBlock; 468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct TranslationBlock TranslationBlock; 478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: make safe guess about sizes */ 49fb02a555a0a2a34e84389d9e441749cc58428531David 'Digit' Turner#define MAX_OP_PER_INSTR 208 50fb02a555a0a2a34e84389d9e441749cc58428531David 'Digit' Turner 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* A Call op needs up to 6 + 2N parameters (N = number of arguments). */ 528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MAX_OPC_PARAM 10 53bcc6ae14820ddb24e2403d84b420ce61f371ae94David 'Digit' Turner#define OPC_BUF_SIZE 2048 548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) 558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Maximum size a TCG op can expand to. This is complicated because a 572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner single op may require several host instructions and register reloads. 582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner For now take a wild guess at 192 bytes, which should allow at least 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project a couple of fixup instructions per argument. */ 602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#define TCG_MAX_OP_SIZE 192 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM) 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 64e1e03df288d5a44bfbffbd86588395c7cbbc27dfDavid 'Digit' Turner#include "qemu/log.h" 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 664d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid gen_intermediate_code(CPUArchState *env, struct TranslationBlock *tb); 674d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid gen_intermediate_code_pc(CPUArchState *env, struct TranslationBlock *tb); 684d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid restore_state_to_opc(CPUArchState *env, struct TranslationBlock *tb, 694d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner int pc_pos); 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned long code_gen_max_block_size(void); 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_gen_init(void); 73ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turnervoid tcg_exec_init(unsigned long tb_size); 744d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnerint cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb, 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int *gen_code_size_ptr); 763e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnerbool cpu_restore_state(CPUArchState *env, uintptr_t searched_pc); 773e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner 784d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc); 7985c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid QEMU_NORETURN cpu_io_recompile(CPUArchState *env, uintptr_t retaddr); 803e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' TurnerTranslationBlock *tb_gen_code(CPUArchState *env, 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_ulong pc, target_ulong cs_base, int flags, 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int cflags); 834d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid cpu_exec_init(CPUArchState *env); 8485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid QEMU_NORETURN cpu_loop_exit(CPUArchState *env1); 8585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerint page_unprotect(target_ulong address, uintptr_t pc, void *puc); 863e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnervoid tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int is_cpu_write_access); 883e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnervoid tb_invalidate_phys_range(tb_page_addr_t start, tb_page_addr_t end, 893e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner int is_cpu_write_access); 901348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if !defined(CONFIG_USER_ONLY) 913e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner/* cputlb.c */ 924d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid tlb_flush_page(CPUArchState *env, target_ulong addr); 934d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid tlb_flush(CPUArchState *env, int flush_global); 940d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turnervoid tlb_set_page(CPUArchState *env, target_ulong vaddr, 950d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turner hwaddr paddr, int prot, 960d8b235c0c6c02de86a4e7415d574175b4518ff0David 'Digit' Turner int mmu_idx, target_ulong size); 97ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turnervoid tb_reset_jump_recursive(TranslationBlock *tb); 983e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnervoid tb_invalidate_phys_addr(hwaddr addr); 991348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#else 1001348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerstatic inline void tlb_flush_page(CPUArchState *env, target_ulong addr) 1011348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner{ 1021348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner} 1031348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 1041348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerstatic inline void tlb_flush(CPUArchState *env, int flush_global) 1051348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner{ 1061348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner} 1071348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#endif 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1093dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turnertypedef struct PhysPageDesc { 1103dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner /* offset in host memory of the page + io_index in the low bits */ 1113dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner ram_addr_t phys_offset; 1123dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner ram_addr_t region_offset; 1133dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner} PhysPageDesc; 1143dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner 1153dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' TurnerPhysPageDesc *phys_page_find(hwaddr index); 116ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' TurnerPhysPageDesc *phys_page_find_alloc(hwaddr index, int alloc); 1173dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner 1183dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turnerint io_mem_watch; 1193dc53fc5342d24fae977049a40c34cc63ba04ad6David 'Digit' Turner 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */ 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_PHYS_HASH_BITS 15 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_PHYS_HASH_SIZE (1 << CODE_GEN_PHYS_HASH_BITS) 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* estimated block size for TB allocation */ 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: use a per code average code fragment size and modulate it 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project according to the host CPU */ 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_SOFTMMU) 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_AVG_BLOCK_SIZE 128 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CODE_GEN_AVG_BLOCK_SIZE 64 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1344d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner#if defined(__arm__) || defined(_ARCH_PPC) \ 1354d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner || defined(__x86_64__) || defined(__i386__) \ 1364d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner || defined(__sparc__) || defined(__aarch64__) \ 1374d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turner || defined(CONFIG_TCG_INTERPRETER) 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define USE_DIRECT_JUMP 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct TranslationBlock { 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_ulong pc; /* simulated PC corresponding to this block (EIP + CS base) */ 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_ulong cs_base; /* CS base for this block */ 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint64_t flags; /* flags defining in which context the code was generated */ 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t size; /* size of target code for this block (1 <= 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project size <= TARGET_PAGE_SIZE) */ 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t cflags; /* compile flags */ 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CF_COUNT_MASK 0x7fff 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CF_LAST_IO 0x8000 /* Last insn may be an IO access. */ 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint8_t *tc_ptr; /* pointer to the translated code */ 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* next matching tb for physical address. */ 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct TranslationBlock *phys_hash_next; 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* first and second physical page containing code. The lower bit 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project of the pointer tells the index in page_next[] */ 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct TranslationBlock *page_next[2]; 15785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner tb_page_addr_t page_addr[2]; 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* the following data are used to directly call another TB from 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the code of this one. */ 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t tb_next_offset[2]; /* offset of original jump target */ 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_DIRECT_JUMP 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project uint16_t tb_jmp_offset[4]; /* offset of jump instruction */ 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 16585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner uintptr_t tb_next[2]; /* address of jump generated code */ 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* list of TBs jumping to this one. This is a circular list using 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the two least significant bits of the pointers to tell what is 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 = 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project jmp_first */ 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct TranslationBlock *jmp_next[2]; 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct TranslationBlock *jmp_first; 173171dd0bf53f93e64b71d3edc958e15f40c96748dDavid 'Digit' Turner uint32_t icount; 1745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 1755bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 1765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine /* Maps PCs in this translation block to corresponding PCs in guest address 1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * space. The array is arranged in such way, that every even entry contains 1785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * PC in the translation block, followed by an odd entry that contains 1795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * guest PC corresponding to that PC in the translation block. This 1805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * arrangement is set by tcg_gen_code_common that initializes this array 1815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * when performing guest code translation. */ 182c5111a01ca209a29fdcb1a9a8917cc08ae5af9cbAndrey Petrov uintptr_t* tpc2gpc; 1835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine /* Number of pairs (pc_tb, pc_guest) in tpc2gpc array. */ 1845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine unsigned int tpc2gpc_pairs; 1855bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}; 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1881348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#include "exec/spinlock.h" 1891348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 1901348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnertypedef struct TBContext TBContext; 1911348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 1921348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerstruct TBContext { 1931348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 1941348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner TranslationBlock *tbs; 1951348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE]; 1961348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner int nb_tbs; 1971348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner /* any access to the tbs or the page table must use this lock */ 1981348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner spinlock_t tb_lock; 1991348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 2001348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner /* statistics */ 2011348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner int tb_flush_count; 2021348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner int tb_phys_invalidate_count; 2031348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 2041348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner int tb_invalidated_flag; 2051348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner}; 2061348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_ulong tmp; 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK; 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline unsigned int tb_jmp_cache_hash_func(target_ulong pc) 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_ulong tmp; 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)); 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK) 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project | (tmp & TB_JMP_ADDR_MASK)); 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 22285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline unsigned int tb_phys_hash_func(tb_page_addr_t pc) 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 224280afa072a7b829e581d884c2b3276530a6014b7David 'Digit' Turner return (pc >> 2) & (CODE_GEN_PHYS_HASH_SIZE - 1); 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2275bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#ifdef CONFIG_ANDROID_MEMCHECK 2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets translated PC for a given (translated PC, guest PC) pair. 2295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return: 2305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Translated PC, or NULL if pair index was too large. 2315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */ 2325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline target_ulong 2335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetb_get_tb_pc(const TranslationBlock* tb, unsigned int pair) 2345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{ 2355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine return (tb->tpc2gpc != NULL && pair < tb->tpc2gpc_pairs) ? 2365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine tb->tpc2gpc[pair * 2] : 0; 2375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine} 2385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 2395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets guest PC for a given (translated PC, guest PC) pair. 2405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return: 2415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Guest PC, or NULL if pair index was too large. 2425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */ 2435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline target_ulong 2445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetb_get_guest_pc(const TranslationBlock* tb, unsigned int pair) 2455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{ 2465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine return (tb->tpc2gpc != NULL && pair < tb->tpc2gpc_pairs) ? 2475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine tb->tpc2gpc[pair * 2 + 1] : 0; 2485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine} 2495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 2505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets guest PC for a given translated PC. 2515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return: 2525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Guest PC for a given translated PC, or NULL if there was no pair, matching 2535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * translated PC in tb's tpc2gpc array. 2545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */ 2555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline target_ulong 2565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetb_search_guest_pc_from_tb_pc(const TranslationBlock* tb, target_ulong tb_pc) 2575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{ 2585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (tb->tpc2gpc != NULL && tb->tpc2gpc_pairs != 0) { 2595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine unsigned int m_min = 0; 2605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine unsigned int m_max = (tb->tpc2gpc_pairs - 1) << 1; 2615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine /* Make sure that tb_pc is within TB array. */ 2625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (tb_pc < tb->tpc2gpc[0]) { 2635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine return 0; 2645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine while (m_min <= m_max) { 2665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine const unsigned int m = ((m_min + m_max) >> 1) & ~1; 2675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine if (tb_pc < tb->tpc2gpc[m]) { 2685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine m_max = m - 2; 2695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } else if (m == m_max || tb_pc < tb->tpc2gpc[m + 2]) { 2705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine return tb->tpc2gpc[m + 1]; 2715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } else { 2725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine m_min = m + 2; 2735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine return tb->tpc2gpc[m_max + 1]; 2765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine } 2775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine return 0; 2785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine} 2795bb450ee9cc5da0c6582e63f41c504c7861e2788David 'Digit' Turner#endif // CONFIG_ANDROID_MEMCHECK 2805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tb_free(TranslationBlock *tb); 2824d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnervoid tb_flush(CPUArchState *env); 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tb_link_phys(TranslationBlock *tb, 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project target_ulong phys_pc, target_ulong phys_page2); 28585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); 286ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turnervoid tb_invalidate_phys_page_fast0(hwaddr start, int len); 287ff9a2b851f95dff46171881afcdc65b2e164d36dDavid 'Digit' Turner 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern uint8_t *code_gen_ptr; 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectextern int code_gen_max_blocks; 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(USE_DIRECT_JUMP) 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 29385c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER) 29485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) 29585c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner{ 29685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner /* patch the branch destination */ 29785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner *(uint32_t *)jmp_addr = addr - (jmp_addr + 4); 29885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner /* no need to flush icache explicitly */ 29985c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner} 30085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#elif defined(_ARCH_PPC) 30185c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define tb_set_jmp_target1 ppc_tb_set_jmp_target 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__i386__) || defined(__x86_64__) 30485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* patch the branch destination */ 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *(uint32_t *)jmp_addr = addr - (jmp_addr + 4); 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* no need to flush icache explicitly */ 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 31085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#elif defined(__aarch64__) 31185c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr); 31285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#define tb_set_jmp_target1 aarch64_tb_set_jmp_target 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__arm__) 31485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnerstatic inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 31685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#if !QEMU_GNUC_PREREQ(4, 1) 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register unsigned long _beg __asm ("a1"); 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register unsigned long _end __asm ("a2"); 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project register unsigned long _flg __asm ("a3"); 3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */ 3232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *(uint32_t *)jmp_addr = 3242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner (*(uint32_t *)jmp_addr & ~0xffffff) 3252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff); 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if QEMU_GNUC_PREREQ(4, 1) 32885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner __builtin___clear_cache((char *) jmp_addr, (char *) jmp_addr + 4); 3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* flush icache */ 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _beg = jmp_addr; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _end = jmp_addr + 4; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project _flg = 0; 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg)); 3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 33785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#elif defined(__sparc__) 33885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turnervoid tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr); 33985c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#else 34085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner#error tb_set_jmp_target1 is missing 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tb_set_jmp_target(TranslationBlock *tb, 34485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner int n, uintptr_t addr) 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 34685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner uint16_t offset = tb->tb_jmp_offset[n]; 34785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr); 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project offset = tb->tb_jmp_offset[n + 2]; 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (offset != 0xffff) 35085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr); 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* set the jump target */ 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tb_set_jmp_target(TranslationBlock *tb, 35785c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner int n, uintptr_t addr) 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tb->tb_next[n] = addr; 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void tb_add_jump(TranslationBlock *tb, int n, 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project TranslationBlock *tb_next) 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* NOTE: this test is only needed for thread safety */ 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (!tb->jmp_next[n]) { 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* patch the native jump address */ 37085c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr); 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* add in TB jmp circular list */ 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project tb->jmp_next[n] = tb_next->jmp_first; 37485c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner tb_next->jmp_first = (TranslationBlock *)((uintptr_t)(tb) | (n)); 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3781348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner/* GETRA is the true target of the return instruction that we'll execute, 3791348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner defined here for simplicity of defining the follow-up macros. */ 3801348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER) 3811348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerextern uintptr_t tci_tb_ptr; 3821348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETRA() tci_tb_ptr 3831348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#else 3841348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETRA() \ 3851348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner ((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0))) 3861348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#endif 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3881348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner/* The true return address will often point to a host insn that is part of 3891348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner the next translated guest insn. Adjust the address backward to point to 3901348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner the middle of the call insn. Subtracting one would do the job except for 3911348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner several compressed mode architectures (arm, mips) which set the low bit 3921348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner to indicate the compressed mode; subtracting two works around that. It 3931348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner is also the case that there are no host isas that contain a call insn 3941348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner smaller than 4 bytes, so we don't worry about special-casing this. */ 3951348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if defined(CONFIG_TCG_INTERPRETER) 3961348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETPC_ADJ 0 3971348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#else 3981348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner# define GETPC_ADJ 2 3991348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#endif 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 401eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner#define GETPC() (GETRA() - GETPC_ADJ) 402eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner 4031348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turner#if !defined(CONFIG_USER_ONLY) 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4051348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnervoid phys_mem_set_alloc(void *(*alloc)(size_t)); 4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4073e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' TurnerTranslationBlock *tb_find_pc(uintptr_t pc_ptr); 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 409fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turneruint64_t io_mem_read(int index, hwaddr addr, unsigned size); 410fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turnervoid io_mem_write(int index, hwaddr addr, uint64_t value, unsigned size); 411fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turner 412fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turnerextern CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4]; 413fdec1f1b82ec4e5ce7b62b8120ba5b1218a9c0afDavid 'Digit' Turnerextern CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4]; 4141348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnerextern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 416eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turnervoid tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx, 417eb3bc46a1a876f279b06d7372bf5866fbcf4e8f8David 'Digit' Turner uintptr_t retaddr); 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 419852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_defs.h" 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ACCESS_TYPE (NB_MMU_MODES + 1) 4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MEMSUFFIX _code 4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define env cpu_single_env 4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 1 426852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h" 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 2 429852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h" 4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 4 432852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h" 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DATA_SIZE 8 435852088c7e08182c2de563872d558309815cbfa0dDavid 'Digit' Turner#include "exec/softmmu_header.h" 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef ACCESS_TYPE 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef MEMSUFFIX 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef env 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(CONFIG_USER_ONLY) 4443e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnerstatic inline tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return addr; 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else 44901ee5b8ded901c76731bab7a12a87c2002479014David 'Digit' Turnertb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr); 4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4524d6613c972c53178ff9ea39de7fa79d07649fad5David 'Digit' Turnertypedef void (CPUDebugExcpHandler)(CPUArchState *env); 4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4541348777d4229cf65ef12d0a4ee531d4502847277David 'Digit' Turnervoid cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler); 4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* vl.c */ 4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern int singlestep; 4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4593e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner/* cpu-exec.c */ 4603e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turnerextern volatile sig_atomic_t exit_request; 4613e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner 4629b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner/* Deterministic execution requires that IO only be performed on the last 4639b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner instruction of a TB so that interrupts take effect immediately. */ 4649b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turnerstatic inline int can_do_io(CPUArchState *env) 4659b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner{ 46685c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner if (!use_icount) { 4679b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner return 1; 46885c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner } 4699b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner /* If not executing code then assume we are ok. */ 4703e0677df2819b1366819fe4112dc8464425b6edaDavid 'Digit' Turner if (env->current_tb == NULL) { 4719b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner return 1; 47285c62200dbdb7ced04b34cb228098b888a8cd828David 'Digit' Turner } 4739b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner return env->can_do_io != 0; 4749b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner} 4759b3a4b03315af9bcdf282243059e8fd1ce1c5c70David 'Digit' Turner 4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 477